{-|
Module      : Botan.Low.PubKey
Description : Public key cryptography
Copyright   : (c) Leo D, 2023
License     : BSD-3-Clause
Maintainer  : leo@apotheca.io
Stability   : experimental
Portability : POSIX

Public key cryptography is a collection of techniques allowing
for encryption, signatures, and key agreement.
-}

module Botan.Low.PubKey
(

-- * Private keys
  PrivKey(..)
, CheckKeyFlags(..)
, pattern CheckKeyNormalTests
, pattern CheckKeyExpensiveTests
, PrivKeyExportFlags(..)
, pattern PrivKeyExportDER
, pattern PrivKeyExportPEM
, withPrivKey
, privKeyCreate
, privKeyLoad
, privKeyDestroy
, privKeyAlgoName
, privKeyCheckKey
, privKeyGetField
, privKeyExport
, privKeyExportPubKey

-- * Public Keys

, PubKey(..)
, withPubKey
, pubKeyLoad
, pubKeyDestroy
, pubKeyAlgoName
, pubKeyCheckKey
, pubKeyEstimatedStrength
, pubKeyFingerprint
, pubKeyGetField
, pubKeyExport

-- * PK Algorithms

, PKName(..)
, pattern RSA
, pattern SM2
, pattern ElGamal
, pattern DSA
, pattern ECDSA
, pattern ECKCDSA
, pattern ECGDSA
, pattern GOST_34_10
, pattern Ed25519
, pattern XMSS
, pattern DH
, pattern ECDH
, pattern Curve25519
, pattern Dilithium
, pattern Kyber
, pattern McEliece

-- ** DLGroup

, DLGroupName(..)
, pattern FFDHE_IETF_2048
, pattern FFDHE_IETF_3072
, pattern FFDHE_IETF_4096
, pattern FFDHE_IETF_6144
, pattern FFDHE_IETF_8192
, pattern MODP_IETF_1024
, pattern MODP_IETF_1536
, pattern MODP_IETF_2048
, pattern MODP_IETF_3072
, pattern MODP_IETF_4096
, pattern MODP_IETF_6144
, pattern MODP_IETF_8192
, pattern MODP_SRP_1024
, pattern MODP_SRP_1536
, pattern MODP_SRP_2048
, pattern MODP_SRP_3072
, pattern MODP_SRP_4096
, pattern MODP_SRP_6144
, pattern MODP_SRP_8192
, pattern DSA_JCE_1024
, pattern DSA_BOTAN_2048
, pattern DSA_BOTAN_3072

-- ** ECGroup

, ECGroupName(..)
, pattern Secp160k1
, pattern Secp160r1
, pattern Secp160r2
, pattern Secp192k1
, pattern Secp192r1
, pattern Secp224k1
, pattern Secp224r1
, pattern Secp256k1
, pattern Secp256r1
, pattern Secp384r1
, pattern Secp521r1
, pattern Brainpool160r1
, pattern Brainpool192r1
, pattern Brainpool224r1
, pattern Brainpool256r1
, pattern Brainpool320r1
, pattern Brainpool384r1
, pattern Brainpool512r1
, pattern X962_p192v2
, pattern X962_p192v3
, pattern X962_p239v1
, pattern X962_p239v2
, pattern X962_p239v3
, pattern Gost_256A
, pattern Gost_512A
, pattern Frp256v1
, pattern Sm2p256v1

-- ** XMSS

, XMSSName(..)
, pattern XMSS_SHA2_10_256
, pattern XMSS_SHA2_16_256
, pattern XMSS_SHA2_20_256
, pattern XMSS_SHA2_10_512
, pattern XMSS_SHA2_16_512
, pattern XMSS_SHA2_20_512
, pattern XMSS_SHAKE_10_256
, pattern XMSS_SHAKE_16_256
, pattern XMSS_SHAKE_20_256
, pattern XMSS_SHAKE_10_512
, pattern XMSS_SHAKE_16_512
, pattern XMSS_SHAKE_20_512

-- * EME

, EMEName(..)
, pattern EME_RAW
, pattern EME_PKCS1_v1_5
, pattern EME_OAEP
, eme_raw
, eme_pkcs1_v1_5
, eme_oaep
-- , eme_oaep_mgf
, eme_hash
, eme_sm2EncParam

-- * EMSA

, EMSAName(..)
, emsa_none
, emsa_emsa4
, emsa_hash
, emsa_ed25519Pure
, emsa_ed25519Prehashed
, emsa_ed25519GnuPG
, emsa_sm2SignParam

-- * Convenience

-- , PKPaddingName(..)
, createPrivKey
, createPubKey
, mkPrivKeyLoad1_name
, mkPrivKeyLoad3
, mkPrivKeyLoad4
, mkPubKeyLoad2
, mkPubKeyLoad2_name
, mkPubKeyLoad3
, mkPubKeyLoad4
    
) where

import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Unsafe as ByteString

import Botan.Bindings.MPI
import Botan.Bindings.PubKey
import Botan.Bindings.RNG

import Botan.Low.Error
import Botan.Low.Hash
import Botan.Low.Make
import Botan.Low.MPI
import Botan.Low.Prelude
import Botan.Low.Remake
import Botan.Low.RNG
import Botan.Low.View

{- $introduction

-}

{- $usage

Unless you need a specific `public key cryptosystem`, it is strongly
recommended that you use the `RSA`, `Ed25519`, or `Curve25519` algorithms,
depending on your desired operation.

Create an RSA keypair:

> import Botan.Low.RNG
> import Botan.Low.PubKey
> rng <- rngInit "user"
> -- Alice generates her keys
> alicePrivKey <- privKeyCreate RSA "4096" rng
> alicePubKey <- privKeyExportPubKey alicePrivKey

> NOTE: For algorithm-specific parameters, consult the Botan documentation and
source

Encrypt a message:

> import Botan.Low.PubKey.Encrypt
> message = "Fee fi fo fum!"
> -- Bob encrypts a message for Alice using her public key
> -- Unlike `Crypto.Saltine.Core.Box`, the message is only encrypted, not signed.
> encrypter <- encryptCreate alicePubKey EME_PKCS1_v1_5
> ciphertext <- encrypt encrypter rng message

> NOTE: For algorithm-specific padding parameters, consult the Botan
documentation and source

Decrypt a message:

> import Botan.Low.PubKey.Decrypt
> -- Alice decrypts the message from Bob using her private key
> decrypter <- decryptCreate alicePrivKey EME_PKCS1_v1_5
> plaintext <- decrypt decrypter ciphertext
> message == plaintext -- True

> NOTE: The same padding must be used for both encryption and decryption

Sign a message:

> import Botan.Low.PubKey.Sign
> import Botan.Low.Hash
> message = "Fee fi fo fum!"
> -- Alice signs the message using her private key
> signer <- signCreate alicePrivKey (emsa_emsa4 SHA3) StandardFormatSignature
> signUpdate signer message
> sig <- signFinish signer rng

> NOTE: Signing uses a different set of padding algorithms `EMSA` from
encryption `EME`, and different signing / encryption algorithms support
different specific padding algorithms

> NOTE: Signing does not yet have proper constants for selecting a padding
mechanism. For more information, refer to the `Botan.PubKey`,
`Botan.PubKey.Sign`, or the Botan C++ documentation. This area will be improved
in the near future.

Verify a message:

> import Botan.Low.PubKey.Verify
> -- Bob verifies the message using Alice's public key
> verifier <- verifyCreate alicePubKey (emsa_emsa4 SHA3) StandardFormatSignature
> verifyUpdate verifier message
> verified <- verifyFinish verifier sig
> verified -- True

> NOTE: The same padding must be used for both encryption and decryption

-}

-- Associated types

type PKPaddingName = ByteString
    
-- /*
-- * Public/private key creation, import, ...
-- */

newtype PrivKey = MkPrivKey { PrivKey -> ForeignPtr BotanPrivKeyStruct
getPrivKeyForeignPtr :: ForeignPtr BotanPrivKeyStruct }

newPrivKey      :: BotanPrivKey -> IO PrivKey
withPrivKey     :: PrivKey -> (BotanPrivKey -> IO a) -> IO a
privKeyDestroy  :: PrivKey -> IO ()
createPrivKey   :: (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
(BotanPrivKey -> IO PrivKey
newPrivKey, PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey, PrivKey -> IO ()
privKeyDestroy, (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey, (Ptr BotanPrivKey -> Ptr CSize -> IO CInt) -> IO [PrivKey]
_)
    = (Ptr BotanPrivKeyStruct -> BotanPrivKey)
-> (BotanPrivKey -> Ptr BotanPrivKeyStruct)
-> (ForeignPtr BotanPrivKeyStruct -> PrivKey)
-> (PrivKey -> ForeignPtr BotanPrivKeyStruct)
-> FinalizerPtr BotanPrivKeyStruct
-> (BotanPrivKey -> IO PrivKey,
    PrivKey -> (BotanPrivKey -> IO a) -> IO a, PrivKey -> IO (),
    (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey,
    (Ptr BotanPrivKey -> Ptr CSize -> IO CInt) -> IO [PrivKey])
forall botan struct object a.
Storable botan =>
(Ptr struct -> botan)
-> (botan -> Ptr struct)
-> (ForeignPtr struct -> object)
-> (object -> ForeignPtr struct)
-> FinalizerPtr struct
-> (botan -> IO object, object -> (botan -> IO a) -> IO a,
    object -> IO (), (Ptr botan -> IO CInt) -> IO object,
    (Ptr botan -> Ptr CSize -> IO CInt) -> IO [object])
mkBindings
        Ptr BotanPrivKeyStruct -> BotanPrivKey
MkBotanPrivKey BotanPrivKey -> Ptr BotanPrivKeyStruct
runBotanPrivKey
        ForeignPtr BotanPrivKeyStruct -> PrivKey
MkPrivKey PrivKey -> ForeignPtr BotanPrivKeyStruct
getPrivKeyForeignPtr
        FinalizerPtr BotanPrivKeyStruct
botan_privkey_destroy

type PrivKeyName = ByteString

type PKName = ByteString

pattern RSA
    ,   SM2
    ,   ElGamal
    ,   DSA
    ,   ECDSA
    ,   ECKCDSA
    ,   ECGDSA
    ,   GOST_34_10
    ,   Ed25519
    ,   XMSS
    ,   DH
    ,   ECDH
    ,   Curve25519
    ,   Dilithium
    ,   Kyber
    -- ,   SPHINCSPlus
    ,   McEliece
    ::  PKName

pattern $mRSA :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bRSA :: EMSAName
RSA         = BOTAN_PK_RSA
pattern $mSM2 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSM2 :: EMSAName
SM2         = BOTAN_PK_SM2
pattern $mElGamal :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bElGamal :: EMSAName
ElGamal     = BOTAN_PK_ELGAMAL
pattern $mDSA :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bDSA :: EMSAName
DSA         = BOTAN_PK_DSA
pattern $mECDSA :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bECDSA :: EMSAName
ECDSA       = BOTAN_PK_ECDSA
pattern $mECKCDSA :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bECKCDSA :: EMSAName
ECKCDSA     = BOTAN_PK_ECKCDSA
pattern $mECGDSA :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bECGDSA :: EMSAName
ECGDSA      = BOTAN_PK_ECGDSA
pattern $mGOST_34_10 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bGOST_34_10 :: EMSAName
GOST_34_10  = BOTAN_PK_GOST_34_10
pattern $mEd25519 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bEd25519 :: EMSAName
Ed25519     = BOTAN_PK_ED25519
pattern $mXMSS :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS :: EMSAName
XMSS        = BOTAN_PK_XMSS
pattern $mDH :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bDH :: EMSAName
DH          = BOTAN_PK_DH
pattern $mECDH :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bECDH :: EMSAName
ECDH        = BOTAN_PK_ECDH
pattern $mCurve25519 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bCurve25519 :: EMSAName
Curve25519  = BOTAN_PK_CURVE25519
pattern $mDilithium :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bDilithium :: EMSAName
Dilithium   = BOTAN_PK_DILITHIUM
pattern $mKyber :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bKyber :: EMSAName
Kyber       = BOTAN_PK_KYBER
-- pattern SPHINCSPlus = BOTAN_PK_SPHINCSPLUS
pattern $mMcEliece :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMcEliece :: EMSAName
McEliece    = BOTAN_PK_MCELIECE

type XMSSName = ByteString

pattern XMSS_SHA2_10_256
    ,   XMSS_SHA2_16_256
    ,   XMSS_SHA2_20_256
    ,   XMSS_SHA2_10_512
    ,   XMSS_SHA2_16_512
    ,   XMSS_SHA2_20_512
    ,   XMSS_SHAKE_10_256
    ,   XMSS_SHAKE_16_256
    ,   XMSS_SHAKE_20_256
    ,   XMSS_SHAKE_10_512
    ,   XMSS_SHAKE_16_512
    ,   XMSS_SHAKE_20_512
    ::  XMSSName

pattern $mXMSS_SHA2_10_256 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHA2_10_256 :: EMSAName
XMSS_SHA2_10_256 = BOTAN_XMSS_SHA2_10_256
pattern $mXMSS_SHA2_16_256 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHA2_16_256 :: EMSAName
XMSS_SHA2_16_256 = BOTAN_XMSS_SHA2_16_256
pattern $mXMSS_SHA2_20_256 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHA2_20_256 :: EMSAName
XMSS_SHA2_20_256 = BOTAN_XMSS_SHA2_20_256
pattern $mXMSS_SHA2_10_512 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHA2_10_512 :: EMSAName
XMSS_SHA2_10_512 = BOTAN_XMSS_SHA2_10_512
pattern $mXMSS_SHA2_16_512 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHA2_16_512 :: EMSAName
XMSS_SHA2_16_512 = BOTAN_XMSS_SHA2_16_512
pattern $mXMSS_SHA2_20_512 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHA2_20_512 :: EMSAName
XMSS_SHA2_20_512 = BOTAN_XMSS_SHA2_20_512
pattern $mXMSS_SHAKE_10_256 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHAKE_10_256 :: EMSAName
XMSS_SHAKE_10_256 = BOTAN_XMSS_SHAKE_10_256
pattern $mXMSS_SHAKE_16_256 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHAKE_16_256 :: EMSAName
XMSS_SHAKE_16_256 = BOTAN_XMSS_SHAKE_16_256
pattern $mXMSS_SHAKE_20_256 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHAKE_20_256 :: EMSAName
XMSS_SHAKE_20_256 = BOTAN_XMSS_SHAKE_20_256
pattern $mXMSS_SHAKE_10_512 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHAKE_10_512 :: EMSAName
XMSS_SHAKE_10_512 = BOTAN_XMSS_SHAKE_10_512
pattern $mXMSS_SHAKE_16_512 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHAKE_16_512 :: EMSAName
XMSS_SHAKE_16_512 = BOTAN_XMSS_SHAKE_16_512
pattern $mXMSS_SHAKE_20_512 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bXMSS_SHAKE_20_512 :: EMSAName
XMSS_SHAKE_20_512 = BOTAN_XMSS_SHAKE_20_512

type ECGroupName = ByteString

pattern Secp160k1
    ,   Secp160r1
    ,   Secp160r2
    ,   Secp192k1
    ,   Secp192r1
    ,   Secp224k1
    ,   Secp224r1
    ,   Secp256k1
    ,   Secp256r1
    ,   Secp384r1
    ,   Secp521r1
    ,   Brainpool160r1
    ,   Brainpool192r1
    ,   Brainpool224r1
    ,   Brainpool256r1
    ,   Brainpool320r1
    ,   Brainpool384r1
    ,   Brainpool512r1
    ,   X962_p192v2
    ,   X962_p192v3
    ,   X962_p239v1
    ,   X962_p239v2
    ,   X962_p239v3
    ,   Gost_256A
    ,   Gost_512A
    ,   Frp256v1
    ,   Sm2p256v1
    ::  ECGroupName

pattern $mSecp160k1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp160k1 :: EMSAName
Secp160k1       = BOTAN_ECGROUP_SECP_160_K1
pattern $mSecp160r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp160r1 :: EMSAName
Secp160r1       = BOTAN_ECGROUP_SECP_160_R1
pattern $mSecp160r2 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp160r2 :: EMSAName
Secp160r2       = BOTAN_ECGROUP_SECP_160_R2
pattern $mSecp192k1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp192k1 :: EMSAName
Secp192k1       = BOTAN_ECGROUP_SECP_192_K1
pattern $mSecp192r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp192r1 :: EMSAName
Secp192r1       = BOTAN_ECGROUP_SECP_192_R1
pattern $mSecp224k1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp224k1 :: EMSAName
Secp224k1       = BOTAN_ECGROUP_SECP_224_K1
pattern $mSecp224r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp224r1 :: EMSAName
Secp224r1       = BOTAN_ECGROUP_SECP_224_R1
pattern $mSecp256k1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp256k1 :: EMSAName
Secp256k1       = BOTAN_ECGROUP_SECP_256_K1
pattern $mSecp256r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp256r1 :: EMSAName
Secp256r1       = BOTAN_ECGROUP_SECP_256_R1
pattern $mSecp384r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp384r1 :: EMSAName
Secp384r1       = BOTAN_ECGROUP_SECP_384_R1
pattern $mSecp521r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSecp521r1 :: EMSAName
Secp521r1       = BOTAN_ECGROUP_SECP_521_R1
pattern $mBrainpool160r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool160r1 :: EMSAName
Brainpool160r1  = BOTAN_ECGROUP_BRAINPOOL_160_R1
pattern $mBrainpool192r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool192r1 :: EMSAName
Brainpool192r1  = BOTAN_ECGROUP_BRAINPOOL_192_R1
pattern $mBrainpool224r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool224r1 :: EMSAName
Brainpool224r1  = BOTAN_ECGROUP_BRAINPOOL_224_R1
pattern $mBrainpool256r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool256r1 :: EMSAName
Brainpool256r1  = BOTAN_ECGROUP_BRAINPOOL_256_R1
pattern $mBrainpool320r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool320r1 :: EMSAName
Brainpool320r1  = BOTAN_ECGROUP_BRAINPOOL_320_R1
pattern $mBrainpool384r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool384r1 :: EMSAName
Brainpool384r1  = BOTAN_ECGROUP_BRAINPOOL_384_R1
pattern $mBrainpool512r1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bBrainpool512r1 :: EMSAName
Brainpool512r1  = BOTAN_ECGROUP_BRAINPOOL_512_R1
pattern $mX962_p192v2 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bX962_p192v2 :: EMSAName
X962_p192v2     = BOTAN_ECGROUP_X962_P192_V2
pattern $mX962_p192v3 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bX962_p192v3 :: EMSAName
X962_p192v3     = BOTAN_ECGROUP_X962_P192_V3
pattern $mX962_p239v1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bX962_p239v1 :: EMSAName
X962_p239v1     = BOTAN_ECGROUP_X962_P239_V1
pattern $mX962_p239v2 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bX962_p239v2 :: EMSAName
X962_p239v2     = BOTAN_ECGROUP_X962_P239_V2
pattern $mX962_p239v3 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bX962_p239v3 :: EMSAName
X962_p239v3     = BOTAN_ECGROUP_X962_P239_V3
pattern $mGost_256A :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bGost_256A :: EMSAName
Gost_256A       = BOTAN_ECGROUP_GOST_256A
pattern $mGost_512A :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bGost_512A :: EMSAName
Gost_512A       = BOTAN_ECGROUP_GOST_512A
pattern $mFrp256v1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bFrp256v1 :: EMSAName
Frp256v1        = BOTAN_ECGROUP_FRP_256_V1
pattern $mSm2p256v1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bSm2p256v1 :: EMSAName
Sm2p256v1       = BOTAN_ECGROUP_SM2_P256_V1

type DLGroupName = ByteString

pattern FFDHE_IETF_2048
    ,   FFDHE_IETF_3072
    ,   FFDHE_IETF_4096
    ,   FFDHE_IETF_6144
    ,   FFDHE_IETF_8192
    ,   MODP_IETF_1024
    ,   MODP_IETF_1536
    ,   MODP_IETF_2048
    ,   MODP_IETF_3072
    ,   MODP_IETF_4096
    ,   MODP_IETF_6144
    ,   MODP_IETF_8192
    ,   MODP_SRP_1024
    ,   MODP_SRP_1536
    ,   MODP_SRP_2048
    ,   MODP_SRP_3072
    ,   MODP_SRP_4096
    ,   MODP_SRP_6144
    ,   MODP_SRP_8192
    ,   DSA_JCE_1024
    ,   DSA_BOTAN_2048
    ,   DSA_BOTAN_3072
    ::  DLGroupName

pattern $mFFDHE_IETF_2048 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bFFDHE_IETF_2048 :: EMSAName
FFDHE_IETF_2048 = BOTAN_DLGROUP_FFDHE_IETF_2048
pattern $mFFDHE_IETF_3072 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bFFDHE_IETF_3072 :: EMSAName
FFDHE_IETF_3072 = BOTAN_DLGROUP_FFDHE_IETF_3072
pattern $mFFDHE_IETF_4096 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bFFDHE_IETF_4096 :: EMSAName
FFDHE_IETF_4096 = BOTAN_DLGROUP_FFDHE_IETF_4096
pattern $mFFDHE_IETF_6144 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bFFDHE_IETF_6144 :: EMSAName
FFDHE_IETF_6144 = BOTAN_DLGROUP_FFDHE_IETF_6144
pattern $mFFDHE_IETF_8192 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bFFDHE_IETF_8192 :: EMSAName
FFDHE_IETF_8192 = BOTAN_DLGROUP_FFDHE_IETF_8192
pattern $mMODP_IETF_1024 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_1024 :: EMSAName
MODP_IETF_1024  = BOTAN_DLGROUP_MODP_IETF_1024
pattern $mMODP_IETF_1536 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_1536 :: EMSAName
MODP_IETF_1536  = BOTAN_DLGROUP_MODP_IETF_1536
pattern $mMODP_IETF_2048 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_2048 :: EMSAName
MODP_IETF_2048  = BOTAN_DLGROUP_MODP_IETF_2048
pattern $mMODP_IETF_3072 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_3072 :: EMSAName
MODP_IETF_3072  = BOTAN_DLGROUP_MODP_IETF_3072
pattern $mMODP_IETF_4096 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_4096 :: EMSAName
MODP_IETF_4096  = BOTAN_DLGROUP_MODP_IETF_4096
pattern $mMODP_IETF_6144 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_6144 :: EMSAName
MODP_IETF_6144  = BOTAN_DLGROUP_MODP_IETF_6144
pattern $mMODP_IETF_8192 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_IETF_8192 :: EMSAName
MODP_IETF_8192  = BOTAN_DLGROUP_MODP_IETF_8192
pattern $mMODP_SRP_1024 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_1024 :: EMSAName
MODP_SRP_1024   = BOTAN_DLGROUP_MODP_SRP_1024
pattern $mMODP_SRP_1536 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_1536 :: EMSAName
MODP_SRP_1536   = BOTAN_DLGROUP_MODP_SRP_1536
pattern $mMODP_SRP_2048 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_2048 :: EMSAName
MODP_SRP_2048   = BOTAN_DLGROUP_MODP_SRP_2048
pattern $mMODP_SRP_3072 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_3072 :: EMSAName
MODP_SRP_3072   = BOTAN_DLGROUP_MODP_SRP_3072
pattern $mMODP_SRP_4096 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_4096 :: EMSAName
MODP_SRP_4096   = BOTAN_DLGROUP_MODP_SRP_4096
pattern $mMODP_SRP_6144 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_6144 :: EMSAName
MODP_SRP_6144   = BOTAN_DLGROUP_MODP_SRP_6144
pattern $mMODP_SRP_8192 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMODP_SRP_8192 :: EMSAName
MODP_SRP_8192   = BOTAN_DLGROUP_MODP_SRP_8192
pattern $mDSA_JCE_1024 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bDSA_JCE_1024 :: EMSAName
DSA_JCE_1024    = BOTAN_DLGROUP_DSA_JCE_1024
pattern $mDSA_BOTAN_2048 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bDSA_BOTAN_2048 :: EMSAName
DSA_BOTAN_2048  = BOTAN_DLGROUP_DSA_BOTAN_2048
pattern $mDSA_BOTAN_3072 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bDSA_BOTAN_3072 :: EMSAName
DSA_BOTAN_3072  = BOTAN_DLGROUP_DSA_BOTAN_3072

{- |
Encoding Method for Encryption

WARNING: Name is not completely accurate, may be changed to PKEncryptParams
-}
type EMEName = ByteString

pattern EME_RAW
    ,   EME_PKCS1_v1_5
    ,   EME_OAEP
    :: EMEName

pattern $mEME_RAW :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bEME_RAW :: EMSAName
EME_RAW = BOTAN_EME_RAW
pattern $mEME_PKCS1_v1_5 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bEME_PKCS1_v1_5 :: EMSAName
EME_PKCS1_v1_5 = BOTAN_EME_PKCS1_v1_5
pattern $mEME_OAEP :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bEME_OAEP :: EMSAName
EME_OAEP = BOTAN_EME_OAEP

eme_raw :: EMEName
eme_raw :: EMSAName
eme_raw = EMSAName
EME_RAW

eme_pkcs1_v1_5 :: EMEName
eme_pkcs1_v1_5 :: EMSAName
eme_pkcs1_v1_5 = EMSAName
EME_PKCS1_v1_5

eme_oaep :: HashName -> EMEName
eme_oaep :: EMSAName -> EMSAName
eme_oaep EMSAName
h = EMSAName
EME_OAEP EMSAName -> EMSAName -> EMSAName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ EMSAName
h

-- TODO: OAEP with MGF, L
-- eme_oaep_mgf :: HashName -> MGFName -> EMEName
-- eme_oaep_mgf h m = EME_OAEP /$ h <> "," <> m

eme_hash :: HashName -> EMEName
eme_hash :: EMSAName -> EMSAName
eme_hash = EMSAName -> EMSAName
forall a. a -> a
id

eme_sm2EncParam :: HashName -> EMEName
eme_sm2EncParam :: EMSAName -> EMSAName
eme_sm2EncParam EMSAName
h = EMSAName
h

type MGFName = ByteString

pattern MGF1
    :: MGFName

pattern $mMGF1 :: forall {r}. EMSAName -> ((# #) -> r) -> ((# #) -> r) -> r
$bMGF1 :: EMSAName
MGF1 = BOTAN_MGF_MGF1

mgf1 :: HashName -> MGFName
mgf1 :: EMSAName -> EMSAName
mgf1 EMSAName
h = EMSAName
MGF1 EMSAName -> EMSAName -> EMSAName
forall a. (IsString a, Semigroup a) => a -> a -> a
/$ EMSAName
h

{- |
Encoding Method for Signature with Appendix

WARNING: Name is not completely accurate, may be changed to PKSignParams
-}
type EMSAName = ByteString

-- emsa_rsa :: 

emsa_emsa4 :: HashName -> EMSAName
emsa_emsa4 :: EMSAName -> EMSAName
emsa_emsa4 EMSAName
h = EMSAName
"EMSA4(" EMSAName -> EMSAName -> EMSAName
forall a. Semigroup a => a -> a -> a
<> EMSAName
h EMSAName -> EMSAName -> EMSAName
forall a. Semigroup a => a -> a -> a
<> EMSAName
")"

emsa_ed25519Pure :: EMSAName
emsa_ed25519Pure :: EMSAName
emsa_ed25519Pure = EMSAName
"Pure"

emsa_ed25519Prehashed :: EMSAName
emsa_ed25519Prehashed :: EMSAName
emsa_ed25519Prehashed = EMSAName
"Ed25519ph"

emsa_ed25519GnuPG :: HashName -> EMSAName
emsa_ed25519GnuPG :: EMSAName -> EMSAName
emsa_ed25519GnuPG = EMSAName -> EMSAName
emsa_hash

emsa_hash :: HashName -> EMSAName
emsa_hash :: EMSAName -> EMSAName
emsa_hash = EMSAName -> EMSAName
forall a. a -> a
id

emsa_sm2SignParam :: ByteString -> HashName -> EMSAName
emsa_sm2SignParam :: EMSAName -> EMSAName -> EMSAName
emsa_sm2SignParam EMSAName
uid EMSAName
h = EMSAName
uid EMSAName -> EMSAName -> EMSAName
forall a. Semigroup a => a -> a -> a
<> EMSAName
"," EMSAName -> EMSAName -> EMSAName
forall a. Semigroup a => a -> a -> a
<> EMSAName
h

-- emsa_xmss
-- emsa_dilithium

emsa_none :: EMSAName
emsa_none :: EMSAName
emsa_none = EMSAName
""        

-- | Create a new private key
privKeyCreate
    :: ByteString   -- ^ __algo_name__: something like "RSA" or "ECDSA"
    -> ByteString   -- ^ __algo_params__: is specific to the algorithm. For RSA, specifies
                    --   the modulus bit length. For ECC is the name of the curve.
    -> RNG          -- ^ __rng__: a random number generator
    -> IO PrivKey   -- ^ __key__: the new object will be placed here
privKeyCreate :: EMSAName -> EMSAName -> RNG -> IO PrivKey
privKeyCreate EMSAName
name EMSAName
params RNG
rng = EMSAName -> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
name ((Ptr CChar -> IO PrivKey) -> IO PrivKey)
-> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
namePtr -> do
    EMSAName -> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
params ((Ptr CChar -> IO PrivKey) -> IO PrivKey)
-> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
paramsPtr -> do
        RNG -> (BotanRNG -> IO PrivKey) -> IO PrivKey
forall a. RNG -> (BotanRNG -> IO a) -> IO a
withRNG RNG
rng ((BotanRNG -> IO PrivKey) -> IO PrivKey)
-> (BotanRNG -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ BotanRNG
botanRNG -> do
            (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey ((Ptr BotanPrivKey -> IO CInt) -> IO PrivKey)
-> (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPrivKey
out -> Ptr BotanPrivKey
-> ConstPtr CChar -> ConstPtr CChar -> BotanRNG -> IO CInt
botan_privkey_create
                Ptr BotanPrivKey
out
                (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
namePtr)
                (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
paramsPtr)
                BotanRNG
botanRNG

-- WARNING: withFooInit-style limited lifetime functions moved to high-level botan
withPrivKeyCreate :: ByteString -> ByteString -> RNG -> (PrivKey -> IO a) -> IO a
withPrivKeyCreate :: forall a. EMSAName -> EMSAName -> RNG -> (PrivKey -> IO a) -> IO a
withPrivKeyCreate = (EMSAName -> EMSAName -> RNG -> IO PrivKey)
-> (PrivKey -> IO ())
-> EMSAName
-> EMSAName
-> RNG
-> (PrivKey -> IO a)
-> IO a
forall x y z t a.
(x -> y -> z -> IO t)
-> (t -> IO ()) -> x -> y -> z -> (t -> IO a) -> IO a
mkWithTemp3 EMSAName -> EMSAName -> RNG -> IO PrivKey
privKeyCreate PrivKey -> IO ()
privKeyDestroy

type CheckKeyFlags = Word32

pattern CheckKeyNormalTests
    ,   CheckKeyExpensiveTests
    ::  CheckKeyFlags
pattern $mCheckKeyNormalTests :: forall {r}. PrivKeyExportFlags -> ((# #) -> r) -> ((# #) -> r) -> r
$bCheckKeyNormalTests :: PrivKeyExportFlags
CheckKeyNormalTests    = BOTAN_CHECK_KEY_NORMAL_TESTS
pattern $mCheckKeyExpensiveTests :: forall {r}. PrivKeyExportFlags -> ((# #) -> r) -> ((# #) -> r) -> r
$bCheckKeyExpensiveTests :: PrivKeyExportFlags
CheckKeyExpensiveTests = BOTAN_CHECK_KEY_EXPENSIVE_TESTS

-- TODO: Probably catch -1 (INVALID_INPUT), return Bool
-- | Check the validity of a private key
privKeyCheckKey
    :: PrivKey          -- ^ __key__
    -> RNG              -- ^ __rng__
    -> CheckKeyFlags    -- ^ __flags__
    -> IO ()
privKeyCheckKey :: PrivKey -> RNG -> PrivKeyExportFlags -> IO ()
privKeyCheckKey PrivKey
sk RNG
rng PrivKeyExportFlags
flags = PrivKey -> (BotanPrivKey -> IO ()) -> IO ()
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey PrivKey
sk ((BotanPrivKey -> IO ()) -> IO ())
-> (BotanPrivKey -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanPrivKey
skPtr -> do
    RNG -> (BotanRNG -> IO ()) -> IO ()
forall a. RNG -> (BotanRNG -> IO a) -> IO a
withRNG RNG
rng ((BotanRNG -> IO ()) -> IO ()) -> (BotanRNG -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanRNG
botanRNG -> do
        HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanPrivKey -> BotanRNG -> PrivKeyExportFlags -> IO CInt
botan_privkey_check_key BotanPrivKey
skPtr BotanRNG
botanRNG PrivKeyExportFlags
flags

-- NOTE: Expectes PKCS #8 / PEM structure
-- botan_privkey_export -> null password? and botan_privkey_export_encrypted_... -> use a password?
-- NOTE: This is probably a bad implementation; null pointer and empty string are different
--  and unencrypted is not the same as encrypted with "" as a pasword
--  We'll fix this by having privKeyLoad and privKeyLoadEncrypted be separate functions
{- |
Input currently assumed to be PKCS #8 structure;
Set password to NULL to indicate no encryption expected
Starting in 2.8.0, the rng parameter is unused and may be set to null
-}
privKeyLoad
    :: ByteString   -- ^ __bits[]__
    -> ByteString   -- ^ __password__
    -> IO PrivKey   -- ^ __key__
privKeyLoad :: EMSAName -> EMSAName -> IO PrivKey
privKeyLoad EMSAName
bits EMSAName
password = EMSAName -> (Ptr Word8 -> CSize -> IO PrivKey) -> IO PrivKey
forall byte a. EMSAName -> (Ptr byte -> CSize -> IO a) -> IO a
asBytesLen EMSAName
bits ((Ptr Word8 -> CSize -> IO PrivKey) -> IO PrivKey)
-> (Ptr Word8 -> CSize -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
bitsPtr CSize
bitsLen -> do
    let asCStringNullable :: EMSAName -> (Ptr CChar -> IO a) -> IO a
asCStringNullable EMSAName
str Ptr CChar -> IO a
act = if EMSAName -> Bool
ByteString.null EMSAName
str
        then Ptr CChar -> IO a
act Ptr CChar
forall a. Ptr a
nullPtr
        else EMSAName -> (Ptr CChar -> IO a) -> IO a
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
str Ptr CChar -> IO a
act
    EMSAName -> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCStringNullable EMSAName
password ((Ptr CChar -> IO PrivKey) -> IO PrivKey)
-> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
passwordPtr -> do
        (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey ((Ptr BotanPrivKey -> IO CInt) -> IO PrivKey)
-> (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPrivKey
out -> Ptr BotanPrivKey
-> BotanRNG -> ConstPtr Word8 -> CSize -> ConstPtr CChar -> IO CInt
botan_privkey_load
            Ptr BotanPrivKey
out
            (Ptr BotanRNGStruct -> BotanRNG
MkBotanRNG Ptr BotanRNGStruct
forall a. Ptr a
nullPtr)
            (Ptr Word8 -> ConstPtr Word8
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr Word8
bitsPtr)
            CSize
bitsLen
            (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
passwordPtr)

type PrivKeyExportFlags = Word32

pattern PrivKeyExportDER
    ,   PrivKeyExportPEM
    ::  PrivKeyExportFlags

pattern $mPrivKeyExportDER :: forall {r}. PrivKeyExportFlags -> ((# #) -> r) -> ((# #) -> r) -> r
$bPrivKeyExportDER :: PrivKeyExportFlags
PrivKeyExportDER = BOTAN_PRIVKEY_EXPORT_FLAG_DER
pattern $mPrivKeyExportPEM :: forall {r}. PrivKeyExportFlags -> ((# #) -> r) -> ((# #) -> r) -> r
$bPrivKeyExportPEM :: PrivKeyExportFlags
PrivKeyExportPEM = BOTAN_PRIVKEY_EXPORT_FLAG_PEM

-- NOTE: Different from allocBytesQuerying / INSUFFICIENT_BUFFER_SPACE
{- |
On input *out_len is number of bytes in out[]
On output *out_len is number of bytes written (or required)
If out is not big enough no output is written, *out_len is set and 1 is returned
Returns 0 on success and sets
If some other error occurs a negative integer is returned.
-}      
privKeyExport
    :: PrivKey              -- ^ __key__
    -> PrivKeyExportFlags   -- ^ __flags__
    -> IO ByteString        -- ^ __out[]__
privKeyExport :: PrivKey -> PrivKeyExportFlags -> IO EMSAName
privKeyExport PrivKey
sk PrivKeyExportFlags
flags = PrivKey -> (BotanPrivKey -> IO EMSAName) -> IO EMSAName
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey PrivKey
sk ((BotanPrivKey -> IO EMSAName) -> IO EMSAName)
-> (BotanPrivKey -> IO EMSAName) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ BotanPrivKey
skPtr -> do
    (Ptr CSize -> IO EMSAName) -> IO EMSAName
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO EMSAName) -> IO EMSAName)
-> (Ptr CSize -> IO EMSAName) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \Ptr CSize
szPtr -> do
        Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
szPtr CSize
0
        -- NOTE: Presumed be -1
        CInt
_ <- BotanPrivKey
-> Ptr Word8 -> Ptr CSize -> PrivKeyExportFlags -> IO CInt
botan_privkey_export BotanPrivKey
skPtr Ptr Word8
forall a. Ptr a
nullPtr Ptr CSize
szPtr PrivKeyExportFlags
flags
        CSize
sz <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
szPtr
        Int -> (Ptr Word8 -> IO ()) -> IO EMSAName
forall byte. Int -> (Ptr byte -> IO ()) -> IO EMSAName
allocBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
sz) ((Ptr Word8 -> IO ()) -> IO EMSAName)
-> (Ptr Word8 -> IO ()) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
bytesPtr -> do
            HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanPrivKey
-> Ptr Word8 -> Ptr CSize -> PrivKeyExportFlags -> IO CInt
botan_privkey_export BotanPrivKey
skPtr Ptr Word8
bytesPtr Ptr CSize
szPtr PrivKeyExportFlags
flags

-- TODO:
-- | View the private key's DER encoding
-- privKeyViewDER
--         :: BotanPrivKey                         -- ^ __key__
--         -> BotanViewContext ctx                 -- ^ __ctx__
--         -> FunPtr (BotanViewBinCallback ctx)    -- ^ __view__
--         -> IO CInt

-- TODO:
-- | View the private key's PEM encoding
-- privKeyViewPEM
--         :: BotanPrivKey                         -- ^ __key__
--         -> BotanViewContext ctx                 -- ^ __ctx__
--         -> FunPtr (BotanViewStrCallback ctx)    -- ^ __view__
--         -> IO CInt

privKeyAlgoName
    :: PrivKey          -- ^ __key__
    -> IO ByteString    -- ^ __out[]__
privKeyAlgoName :: PrivKey -> IO EMSAName
privKeyAlgoName = (forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a)
-> GetCString BotanPrivKey CChar -> PrivKey -> IO EMSAName
forall typ ptr byte.
WithPtr typ ptr -> GetCString ptr byte -> typ -> IO EMSAName
mkGetCString PrivKey -> (BotanPrivKey -> IO a) -> IO a
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey GetCString BotanPrivKey CChar
botan_privkey_algo_name

-- TODO:
-- privKeyExportEncryptedPBKDFMsec
--     :: PrivKey
--     -> RNG
--     -> ByteString   -- Passphrase
--     -> Word32       -- Msec runtime
--     -> ByteString   -- Cipher algo
--     -> ByteString   -- PBKDF algo
--     -> Word32       -- Flags
--     -> IO ByteString 
-- privKeyExportEncryptedPBKDFMsec = undefined

-- TODO:
-- privKeyExportEncryptedPBKDFIter
--     :: PrivKey
--     -> RNG
--     -> ByteString   -- Passphrase
--     -> CSize        -- Iterations
--     -> ByteString   -- Cipher algo
--     -> ByteString   -- PBKDF algo
--     -> Word32       -- Flags
--     -> IO ByteString 
-- privKeyExportEncryptedPBKDFIter = undefined

newtype PubKey = MkPubKey { PubKey -> ForeignPtr BotanPubKeyStruct
getPubKeyForeignPtr :: ForeignPtr BotanPubKeyStruct }

newPubKey      :: BotanPubKey -> IO PubKey
withPubKey     :: PubKey -> (BotanPubKey -> IO a) -> IO a
pubKeyDestroy  :: PubKey -> IO ()
createPubKey   :: (Ptr BotanPubKey -> IO CInt) -> IO PubKey
(BotanPubKey -> IO PubKey
newPubKey, PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey, PubKey -> IO ()
pubKeyDestroy, (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey, (Ptr BotanPubKey -> Ptr CSize -> IO CInt) -> IO [PubKey]
_)
    = (Ptr BotanPubKeyStruct -> BotanPubKey)
-> (BotanPubKey -> Ptr BotanPubKeyStruct)
-> (ForeignPtr BotanPubKeyStruct -> PubKey)
-> (PubKey -> ForeignPtr BotanPubKeyStruct)
-> FinalizerPtr BotanPubKeyStruct
-> (BotanPubKey -> IO PubKey,
    PubKey -> (BotanPubKey -> IO a) -> IO a, PubKey -> IO (),
    (Ptr BotanPubKey -> IO CInt) -> IO PubKey,
    (Ptr BotanPubKey -> Ptr CSize -> IO CInt) -> IO [PubKey])
forall botan struct object a.
Storable botan =>
(Ptr struct -> botan)
-> (botan -> Ptr struct)
-> (ForeignPtr struct -> object)
-> (object -> ForeignPtr struct)
-> FinalizerPtr struct
-> (botan -> IO object, object -> (botan -> IO a) -> IO a,
    object -> IO (), (Ptr botan -> IO CInt) -> IO object,
    (Ptr botan -> Ptr CSize -> IO CInt) -> IO [object])
mkBindings
        Ptr BotanPubKeyStruct -> BotanPubKey
MkBotanPubKey BotanPubKey -> Ptr BotanPubKeyStruct
runBotanPubKey
        ForeignPtr BotanPubKeyStruct -> PubKey
MkPubKey PubKey -> ForeignPtr BotanPubKeyStruct
getPubKeyForeignPtr
        FinalizerPtr BotanPubKeyStruct
botan_pubkey_destroy

type PubKeyName = ByteString

pubKeyLoad
    :: ByteString   -- ^ __bits[]__
    -> IO PubKey    -- ^ __key__
pubKeyLoad :: EMSAName -> IO PubKey
pubKeyLoad = ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (Ptr BotanPubKey -> ConstPtr Word8 -> CSize -> IO CInt)
-> EMSAName
-> IO PubKey
forall botan object.
((Ptr botan -> IO CInt) -> IO object)
-> (Ptr botan -> ConstPtr Word8 -> CSize -> IO CInt)
-> EMSAName
-> IO object
mkCreateObjectCBytesLen (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey Ptr BotanPubKey -> ConstPtr Word8 -> CSize -> IO CInt
botan_pubkey_load

-- WARNING: withFooInit-style limited lifetime functions moved to high-level botan
withPubKeyLoad :: ByteString -> (PubKey -> IO a) -> IO a
withPubKeyLoad :: forall a. EMSAName -> (PubKey -> IO a) -> IO a
withPubKeyLoad = (EMSAName -> IO PubKey)
-> (PubKey -> IO ()) -> EMSAName -> (PubKey -> IO a) -> IO a
forall x t a.
(x -> IO t) -> (t -> IO ()) -> x -> (t -> IO a) -> IO a
mkWithTemp1 EMSAName -> IO PubKey
pubKeyLoad PubKey -> IO ()
pubKeyDestroy

privKeyExportPubKey
    :: PrivKey      -- ^ __in__
    -> IO PubKey    -- ^ __out__
privKeyExportPubKey :: PrivKey -> IO PubKey
privKeyExportPubKey = ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (PrivKey -> (BotanPrivKey -> IO PubKey) -> IO PubKey)
-> (Ptr BotanPubKey -> BotanPrivKey -> IO CInt)
-> PrivKey
-> IO PubKey
forall botan object arg carg.
((Ptr botan -> IO CInt) -> IO object)
-> (arg -> (carg -> IO object) -> IO object)
-> (Ptr botan -> carg -> IO CInt)
-> arg
-> IO object
mkCreateObjectWith (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey PrivKey -> (BotanPrivKey -> IO PubKey) -> IO PubKey
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey Ptr BotanPubKey -> BotanPrivKey -> IO CInt
botan_privkey_export_pubkey

type PubKeyExportFlags = PrivKeyExportFlags

pattern PubKeyExportDER
    ,   PubKeyExportPEM
    ::  PubKeyExportFlags

pattern $mPubKeyExportDER :: forall {r}. PrivKeyExportFlags -> ((# #) -> r) -> ((# #) -> r) -> r
$bPubKeyExportDER :: PrivKeyExportFlags
PubKeyExportDER = PrivKeyExportDER
pattern $mPubKeyExportPEM :: forall {r}. PrivKeyExportFlags -> ((# #) -> r) -> ((# #) -> r) -> r
$bPubKeyExportPEM :: PrivKeyExportFlags
PubKeyExportPEM = PrivKeyExportPEM

-- NOTE: Different from allocBytesQuerying / INSUFFICIENT_BUFFER_SPACE     
pubKeyExport
    :: PubKey               -- ^ __key__
    -> PubKeyExportFlags    -- ^ __flags__
    -> IO ByteString        -- ^ __out[]__
pubKeyExport :: PubKey -> PrivKeyExportFlags -> IO EMSAName
pubKeyExport PubKey
pk PrivKeyExportFlags
flags = PubKey -> (BotanPubKey -> IO EMSAName) -> IO EMSAName
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey PubKey
pk ((BotanPubKey -> IO EMSAName) -> IO EMSAName)
-> (BotanPubKey -> IO EMSAName) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ BotanPubKey
pkPtr -> do
    (Ptr CSize -> IO EMSAName) -> IO EMSAName
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CSize -> IO EMSAName) -> IO EMSAName)
-> (Ptr CSize -> IO EMSAName) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \Ptr CSize
szPtr -> do
        Ptr CSize -> CSize -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CSize
szPtr CSize
0
        -- NOTE: Presumed be -1
        CInt
_ <- BotanPubKey
-> Ptr Word8 -> Ptr CSize -> PrivKeyExportFlags -> IO CInt
botan_pubkey_export BotanPubKey
pkPtr Ptr Word8
forall a. Ptr a
nullPtr Ptr CSize
szPtr PrivKeyExportFlags
flags
        CSize
sz <- Ptr CSize -> IO CSize
forall a. Storable a => Ptr a -> IO a
peek Ptr CSize
szPtr
        Int -> (Ptr Word8 -> IO ()) -> IO EMSAName
forall byte. Int -> (Ptr byte -> IO ()) -> IO EMSAName
allocBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
sz) ((Ptr Word8 -> IO ()) -> IO EMSAName)
-> (Ptr Word8 -> IO ()) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
bytesPtr -> do
            HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanPubKey
-> Ptr Word8 -> Ptr CSize -> PrivKeyExportFlags -> IO CInt
botan_pubkey_export BotanPubKey
pkPtr Ptr Word8
bytesPtr Ptr CSize
szPtr PrivKeyExportFlags
flags


pubKeyAlgoName
    :: PubKey           -- ^ __key__
    -> IO ByteString    -- ^ __out[]__
pubKeyAlgoName :: PubKey -> IO EMSAName
pubKeyAlgoName = (forall a. PubKey -> (BotanPubKey -> IO a) -> IO a)
-> GetCString BotanPubKey CChar -> PubKey -> IO EMSAName
forall typ ptr byte.
WithPtr typ ptr -> GetCString ptr byte -> typ -> IO EMSAName
mkGetCString PubKey -> (BotanPubKey -> IO a) -> IO a
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey GetCString BotanPubKey CChar
botan_pubkey_algo_name

pubKeyCheckKey
    :: PubKey           -- ^ __key__
    -> RNG              -- ^ __rng__
    -> CheckKeyFlags    -- ^ __flags__
    -> IO Bool
pubKeyCheckKey :: PubKey -> RNG -> PrivKeyExportFlags -> IO Bool
pubKeyCheckKey PubKey
pk RNG
rng PrivKeyExportFlags
flags = PubKey -> (BotanPubKey -> IO Bool) -> IO Bool
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey PubKey
pk ((BotanPubKey -> IO Bool) -> IO Bool)
-> (BotanPubKey -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \ BotanPubKey
pkPtr -> do
    RNG -> (BotanRNG -> IO Bool) -> IO Bool
forall a. RNG -> (BotanRNG -> IO a) -> IO a
withRNG RNG
rng ((BotanRNG -> IO Bool) -> IO Bool)
-> (BotanRNG -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \ BotanRNG
botanRNG -> do
        HasCallStack => IO CInt -> IO Bool
IO CInt -> IO Bool
throwBotanCatchingSuccess (IO CInt -> IO Bool) -> IO CInt -> IO Bool
forall a b. (a -> b) -> a -> b
$ BotanPubKey -> BotanRNG -> PrivKeyExportFlags -> IO CInt
botan_pubkey_check_key BotanPubKey
pkPtr BotanRNG
botanRNG PrivKeyExportFlags
flags

-- Annoying - this mixes cint and csize
--  I need to consolidate getsize / getint
pubKeyEstimatedStrength
    :: PubKey   -- ^ __key__
    -> IO Int   -- ^ __estimate__
pubKeyEstimatedStrength :: PubKey -> IO Int
pubKeyEstimatedStrength PubKey
pk = Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Int) -> IO Int -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall a. PubKey -> (BotanPubKey -> IO a) -> IO a)
-> GetSize BotanPubKey -> PubKey -> IO Int
forall typ ptr. WithPtr typ ptr -> GetSize ptr -> typ -> IO Int
mkGetSize PubKey -> (BotanPubKey -> IO a) -> IO a
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey GetSize BotanPubKey
botan_pubkey_estimated_strength PubKey
pk

pubKeyFingerprint
    :: PubKey           -- ^ __key__
    -> HashName         -- ^ __hash__
    -> IO ByteString    -- ^ __out[]__
pubKeyFingerprint :: PubKey -> EMSAName -> IO EMSAName
pubKeyFingerprint PubKey
pk EMSAName
algo = PubKey -> (BotanPubKey -> IO EMSAName) -> IO EMSAName
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey PubKey
pk ((BotanPubKey -> IO EMSAName) -> IO EMSAName)
-> (BotanPubKey -> IO EMSAName) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ BotanPubKey
pkPtr -> do
    EMSAName -> (Ptr CChar -> IO EMSAName) -> IO EMSAName
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
algo ((Ptr CChar -> IO EMSAName) -> IO EMSAName)
-> (Ptr CChar -> IO EMSAName) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
algoPtr -> do
        (Ptr Word8 -> Ptr CSize -> IO CInt) -> IO EMSAName
forall byte. (Ptr byte -> Ptr CSize -> IO CInt) -> IO EMSAName
allocBytesQuerying ((Ptr Word8 -> Ptr CSize -> IO CInt) -> IO EMSAName)
-> (Ptr Word8 -> Ptr CSize -> IO CInt) -> IO EMSAName
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr Ptr CSize
outLen -> BotanPubKey -> ConstPtr CChar -> Ptr Word8 -> Ptr CSize -> IO CInt
botan_pubkey_fingerprint
            BotanPubKey
pkPtr
            (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
algoPtr)
            Ptr Word8
outPtr
            Ptr CSize
outLen

-- | Get arbitrary named fields from public or private keys
pubKeyGetField
    :: MP           -- ^ __output__
    -> PubKey       -- ^ __key__
    -> ByteString   -- ^ __field_name__
    -> IO ()
pubKeyGetField :: MP -> PubKey -> EMSAName -> IO ()
pubKeyGetField MP
mp PubKey
pk EMSAName
field = MP -> (BotanMP -> IO ()) -> IO ()
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP MP
mp ((BotanMP -> IO ()) -> IO ()) -> (BotanMP -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanMP
mpPtr -> do
    PubKey -> (BotanPubKey -> IO ()) -> IO ()
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey PubKey
pk ((BotanPubKey -> IO ()) -> IO ())
-> (BotanPubKey -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanPubKey
pkPtr -> do
        EMSAName -> (Ptr CChar -> IO ()) -> IO ()
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
field ((Ptr CChar -> IO ()) -> IO ()) -> (Ptr CChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
fieldPtr -> do
            HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanMP -> BotanPubKey -> ConstPtr CChar -> IO CInt
botan_pubkey_get_field
                BotanMP
mpPtr
                BotanPubKey
pkPtr
                (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
fieldPtr)

-- | Get arbitrary named fields from public or private keys
privKeyGetField
    :: MP           -- ^ __output__
    -> PrivKey      -- ^ __key__
    -> ByteString   -- ^ __field_name__
    -> IO ()
privKeyGetField :: MP -> PrivKey -> EMSAName -> IO ()
privKeyGetField MP
mp PrivKey
sk EMSAName
field = MP -> (BotanMP -> IO ()) -> IO ()
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP MP
mp ((BotanMP -> IO ()) -> IO ()) -> (BotanMP -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanMP
mpPtr -> do
    PrivKey -> (BotanPrivKey -> IO ()) -> IO ()
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey PrivKey
sk ((BotanPrivKey -> IO ()) -> IO ())
-> (BotanPrivKey -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ BotanPrivKey
skPtr -> do
        EMSAName -> (Ptr CChar -> IO ()) -> IO ()
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
field ((Ptr CChar -> IO ()) -> IO ()) -> (Ptr CChar -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
fieldPtr -> do
            HasCallStack => IO CInt -> IO ()
IO CInt -> IO ()
throwBotanIfNegative_ (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ BotanMP -> BotanPrivKey -> ConstPtr CChar -> IO CInt
botan_privkey_get_field
                BotanMP
mpPtr
                BotanPrivKey
skPtr
                (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
fieldPtr)

-- Helpers

mkPrivKeyLoad1_name
    :: (Ptr BotanPrivKey -> BotanMP -> ConstPtr CChar -> IO BotanErrorCode)
    -> MP -> ByteString -> IO PrivKey
mkPrivKeyLoad1_name :: (Ptr BotanPrivKey -> BotanMP -> ConstPtr CChar -> IO CInt)
-> MP -> EMSAName -> IO PrivKey
mkPrivKeyLoad1_name Ptr BotanPrivKey -> BotanMP -> ConstPtr CChar -> IO CInt
load MP
a EMSAName
name = MP -> (BotanMP -> IO PrivKey) -> IO PrivKey
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP MP
a ((BotanMP -> IO PrivKey) -> IO PrivKey)
-> (BotanMP -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ BotanMP
aPtr -> do
    EMSAName -> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
name ((Ptr CChar -> IO PrivKey) -> IO PrivKey)
-> (Ptr CChar -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
namePtr -> do
        (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey ((Ptr BotanPrivKey -> IO CInt) -> IO PrivKey)
-> (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPrivKey
out -> Ptr BotanPrivKey -> BotanMP -> ConstPtr CChar -> IO CInt
load Ptr BotanPrivKey
out BotanMP
aPtr (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
namePtr)

mkPrivKeyLoad3
    :: (Ptr BotanPrivKey -> BotanMP -> BotanMP -> BotanMP -> IO BotanErrorCode)
    -> MP -> MP -> MP -> IO PrivKey
mkPrivKeyLoad3 :: (Ptr BotanPrivKey -> BotanMP -> BotanMP -> BotanMP -> IO CInt)
-> MP -> MP -> MP -> IO PrivKey
mkPrivKeyLoad3 Ptr BotanPrivKey -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load MP
a MP
b MP
c = (forall a. MP -> (BotanMP -> IO a) -> IO a)
-> [MP] -> ([BotanMP] -> IO PrivKey) -> IO PrivKey
forall object cobject b.
(forall a. object -> (cobject -> IO a) -> IO a)
-> [object] -> ([cobject] -> IO b) -> IO b
withMany MP -> (BotanMP -> IO a) -> IO a
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP [MP
a,MP
b,MP
c] (([BotanMP] -> IO PrivKey) -> IO PrivKey)
-> ([BotanMP] -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ [BotanMP
aPtr,BotanMP
bPtr,BotanMP
cPtr] -> do
    (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey ((Ptr BotanPrivKey -> IO CInt) -> IO PrivKey)
-> (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPrivKey
out -> Ptr BotanPrivKey -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load Ptr BotanPrivKey
out BotanMP
aPtr BotanMP
bPtr BotanMP
cPtr

mkPrivKeyLoad4
    :: (Ptr BotanPrivKey -> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO BotanErrorCode)
    -> MP -> MP -> MP -> MP -> IO PrivKey
mkPrivKeyLoad4 :: (Ptr BotanPrivKey
 -> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO CInt)
-> MP -> MP -> MP -> MP -> IO PrivKey
mkPrivKeyLoad4 Ptr BotanPrivKey
-> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load MP
a MP
b MP
c MP
d = (forall a. MP -> (BotanMP -> IO a) -> IO a)
-> [MP] -> ([BotanMP] -> IO PrivKey) -> IO PrivKey
forall object cobject b.
(forall a. object -> (cobject -> IO a) -> IO a)
-> [object] -> ([cobject] -> IO b) -> IO b
withMany MP -> (BotanMP -> IO a) -> IO a
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP [MP
a,MP
b,MP
c,MP
d] (([BotanMP] -> IO PrivKey) -> IO PrivKey)
-> ([BotanMP] -> IO PrivKey) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ [BotanMP
aPtr,BotanMP
bPtr,BotanMP
cPtr,BotanMP
dPtr] -> do
    (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey ((Ptr BotanPrivKey -> IO CInt) -> IO PrivKey)
-> (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPrivKey
out -> Ptr BotanPrivKey
-> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load Ptr BotanPrivKey
out BotanMP
aPtr BotanMP
bPtr BotanMP
cPtr BotanMP
dPtr

--

mkPubKeyLoad2
    :: (Ptr BotanPubKey -> BotanMP -> BotanMP -> IO BotanErrorCode)
    -> MP -> MP -> IO PubKey
mkPubKeyLoad2 :: (Ptr BotanPubKey -> BotanMP -> BotanMP -> IO CInt)
-> MP -> MP -> IO PubKey
mkPubKeyLoad2 Ptr BotanPubKey -> BotanMP -> BotanMP -> IO CInt
load MP
a MP
b = (forall a. MP -> (BotanMP -> IO a) -> IO a)
-> [MP] -> ([BotanMP] -> IO PubKey) -> IO PubKey
forall object cobject b.
(forall a. object -> (cobject -> IO a) -> IO a)
-> [object] -> ([cobject] -> IO b) -> IO b
withMany MP -> (BotanMP -> IO a) -> IO a
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP [MP
a,MP
b] (([BotanMP] -> IO PubKey) -> IO PubKey)
-> ([BotanMP] -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ [BotanMP
aPtr,BotanMP
bPtr] -> do
    (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (Ptr BotanPubKey -> IO CInt) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPubKey
out -> Ptr BotanPubKey -> BotanMP -> BotanMP -> IO CInt
load Ptr BotanPubKey
out BotanMP
aPtr BotanMP
bPtr

mkPubKeyLoad2_name
    :: (Ptr BotanPubKey -> BotanMP -> BotanMP -> ConstPtr CChar -> IO BotanErrorCode)
    -> MP -> MP -> ByteString -> IO PubKey
mkPubKeyLoad2_name :: (Ptr BotanPubKey
 -> BotanMP -> BotanMP -> ConstPtr CChar -> IO CInt)
-> MP -> MP -> EMSAName -> IO PubKey
mkPubKeyLoad2_name Ptr BotanPubKey -> BotanMP -> BotanMP -> ConstPtr CChar -> IO CInt
load MP
x MP
y EMSAName
name = (forall a. MP -> (BotanMP -> IO a) -> IO a)
-> [MP] -> ([BotanMP] -> IO PubKey) -> IO PubKey
forall object cobject b.
(forall a. object -> (cobject -> IO a) -> IO a)
-> [object] -> ([cobject] -> IO b) -> IO b
withMany MP -> (BotanMP -> IO a) -> IO a
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP [MP
x,MP
y] (([BotanMP] -> IO PubKey) -> IO PubKey)
-> ([BotanMP] -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ [BotanMP
xPtr,BotanMP
yPtr] -> do
    EMSAName -> (Ptr CChar -> IO PubKey) -> IO PubKey
forall a. EMSAName -> (Ptr CChar -> IO a) -> IO a
asCString EMSAName
name ((Ptr CChar -> IO PubKey) -> IO PubKey)
-> (Ptr CChar -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ Ptr CChar
namePtr -> do
        (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (Ptr BotanPubKey -> IO CInt) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPubKey
out -> Ptr BotanPubKey -> BotanMP -> BotanMP -> ConstPtr CChar -> IO CInt
load Ptr BotanPubKey
out BotanMP
xPtr BotanMP
yPtr (Ptr CChar -> ConstPtr CChar
forall a. Ptr a -> ConstPtr a
ConstPtr Ptr CChar
namePtr)

mkPubKeyLoad3
    :: (Ptr BotanPubKey -> BotanMP -> BotanMP -> BotanMP -> IO BotanErrorCode)
    -> MP -> MP -> MP -> IO PubKey
mkPubKeyLoad3 :: (Ptr BotanPubKey -> BotanMP -> BotanMP -> BotanMP -> IO CInt)
-> MP -> MP -> MP -> IO PubKey
mkPubKeyLoad3 Ptr BotanPubKey -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load MP
a MP
b MP
c = (forall a. MP -> (BotanMP -> IO a) -> IO a)
-> [MP] -> ([BotanMP] -> IO PubKey) -> IO PubKey
forall object cobject b.
(forall a. object -> (cobject -> IO a) -> IO a)
-> [object] -> ([cobject] -> IO b) -> IO b
withMany MP -> (BotanMP -> IO a) -> IO a
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP [MP
a,MP
b,MP
c] (([BotanMP] -> IO PubKey) -> IO PubKey)
-> ([BotanMP] -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ [BotanMP
aPtr,BotanMP
bPtr,BotanMP
cPtr] -> do
    (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (Ptr BotanPubKey -> IO CInt) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPubKey
out -> Ptr BotanPubKey -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load Ptr BotanPubKey
out BotanMP
aPtr BotanMP
bPtr BotanMP
cPtr

mkPubKeyLoad4
    :: (Ptr BotanPubKey -> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO BotanErrorCode)
    -> MP -> MP -> MP -> MP -> IO PubKey
mkPubKeyLoad4 :: (Ptr BotanPubKey
 -> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO CInt)
-> MP -> MP -> MP -> MP -> IO PubKey
mkPubKeyLoad4 Ptr BotanPubKey
-> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load MP
a MP
b MP
c MP
d = (forall a. MP -> (BotanMP -> IO a) -> IO a)
-> [MP] -> ([BotanMP] -> IO PubKey) -> IO PubKey
forall object cobject b.
(forall a. object -> (cobject -> IO a) -> IO a)
-> [object] -> ([cobject] -> IO b) -> IO b
withMany MP -> (BotanMP -> IO a) -> IO a
forall a. MP -> (BotanMP -> IO a) -> IO a
withMP [MP
a,MP
b,MP
c,MP
d] (([BotanMP] -> IO PubKey) -> IO PubKey)
-> ([BotanMP] -> IO PubKey) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ [BotanMP
aPtr,BotanMP
bPtr,BotanMP
cPtr,BotanMP
dPtr] -> do
    (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (Ptr BotanPubKey -> IO CInt) -> IO PubKey
forall a b. (a -> b) -> a -> b
$ \ Ptr BotanPubKey
out -> Ptr BotanPubKey
-> BotanMP -> BotanMP -> BotanMP -> BotanMP -> IO CInt
load Ptr BotanPubKey
out BotanMP
aPtr BotanMP
bPtr BotanMP
cPtr BotanMP
dPtr