{-|
Module      : Botan.PubKey.Load
Description : Algorithm specific public key operations
Copyright   : (c) Leo D, 2023
License     : BSD-3-Clause
Maintainer  : leo@apotheca.io
Stability   : experimental
Portability : POSIX
-}

module Botan.PubKey.Load
(

-- * DH
  loadDHPrivKey
, loadDHPubKey

-- * DSA
, newDSAPrivKey
, loadDSAPrivKey
, loadDSAPubKey

-- * ECDH
, loadECDHPrivKey
, loadECDHPubKey

-- * ECDSA
, loadECDSAPrivKey
, loadECDSAPubKey

-- * Ed25519
, loadEd25519PrivKey
, loadEd25519PubKey
, exportEd25519PrivKey
, exportEd25519PubKey

-- * ElGamal
, newElGamalPrivKey
, loadElGamalPrivKey
, loadElGamalPubKey

-- * RSA
, loadRSAPrivKey
, loadRSAPubKey

-- * SM2
, loadSM2PrivKey
, loadSM2PubKey

-- * X25519
, loadX25519PrivKey
, loadX25519PubKey
, exportX25519PrivKey
, exportX25519PubKey

) where

import qualified Botan.Low.PubKey.DH as Low
import qualified Botan.Low.PubKey.DSA as Low
import qualified Botan.Low.PubKey.ECDH as Low
import qualified Botan.Low.PubKey.ECDSA as Low
import qualified Botan.Low.PubKey.Ed25519 as Low
import qualified Botan.Low.PubKey.ElGamal as Low
import qualified Botan.Low.PubKey.RSA as Low
import qualified Botan.Low.PubKey.SM2 as Low
import qualified Botan.Low.PubKey.X25519 as Low

import Botan.Error
import Botan.Prelude
import Botan.PubKey
import Botan.RNG

import Botan.Low.MPI

-- DH

loadDHPrivKey :: MP -> MP -> MP -> PrivKey
loadDHPrivKey :: MP -> MP -> MP -> PrivKey
loadDHPrivKey MP
p MP
g MP
x = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> IO PrivKey
Low.privKeyLoadDH MP
p MP
g MP
x
{-# NOINLINE loadDHPrivKey #-}

loadDHPubKey :: MP -> MP -> MP -> PubKey
loadDHPubKey :: MP -> MP -> MP -> PubKey
loadDHPubKey MP
p MP
g MP
y = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> IO PubKey
Low.pubKeyLoadDH MP
p MP
g MP
y
{-# NOINLINE loadDHPubKey #-}

-- DSA

newDSAPrivKey :: (MonadRandomIO m) => Int -> Int -> m PrivKey
newDSAPrivKey :: forall (m :: * -> *). MonadRandomIO m => Int -> Int -> m PrivKey
newDSAPrivKey Int
pbits Int
qbits = do
    RNG
rng <- m RNG
forall (m :: * -> *). MonadRandomIO m => m RNG
getRNG
    IO PrivKey -> m PrivKey
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PrivKey -> m PrivKey) -> IO PrivKey -> m PrivKey
forall a b. (a -> b) -> a -> b
$ RNG -> Int -> Int -> IO PrivKey
Low.privKeyCreateDSA RNG
rng Int
pbits Int
qbits

loadDSAPrivKey :: MP -> MP -> MP -> MP -> PrivKey
loadDSAPrivKey :: MP -> MP -> MP -> MP -> PrivKey
loadDSAPrivKey MP
p MP
q MP
g MP
x = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> MP -> IO PrivKey
Low.privKeyLoadDSA MP
p MP
q MP
g MP
x
{-# NOINLINE loadDSAPrivKey #-}

loadDSAPubKey :: MP -> MP -> MP -> MP -> PubKey
loadDSAPubKey :: MP -> MP -> MP -> MP -> PubKey
loadDSAPubKey MP
p MP
q MP
g MP
y = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> MP -> IO PubKey
Low.pubKeyLoadDSA MP
p MP
q MP
g MP
y
{-# NOINLINE loadDSAPubKey #-}

-- ECDH

loadECDHPrivKey :: MP -> ByteString -> PrivKey
loadECDHPrivKey :: MP -> ByteString -> PrivKey
loadECDHPrivKey MP
scalar ByteString
curve_name = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> ByteString -> IO PrivKey
Low.privKeyLoadECDH MP
scalar ByteString
curve_name
{-# NOINLINE loadECDHPrivKey #-}

loadECDHPubKey :: MP -> MP -> ByteString -> PubKey
loadECDHPubKey :: MP -> MP -> ByteString -> PubKey
loadECDHPubKey MP
public_x MP
public_y ByteString
curve_name = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> ByteString -> IO PubKey
Low.pubKeyLoadECDH MP
public_x MP
public_y ByteString
curve_name
{-# NOINLINE loadECDHPubKey #-}

-- ECDSA

loadECDSAPrivKey :: MP -> ByteString -> PrivKey
loadECDSAPrivKey :: MP -> ByteString -> PrivKey
loadECDSAPrivKey MP
scalar ByteString
curve_name = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> ByteString -> IO PrivKey
Low.privKeyLoadECDSA MP
scalar ByteString
curve_name
{-# NOINLINE loadECDSAPrivKey #-}

loadECDSAPubKey :: MP -> MP -> ByteString -> PubKey
loadECDSAPubKey :: MP -> MP -> ByteString -> PubKey
loadECDSAPubKey MP
public_x MP
public_y ByteString
curve_name = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> ByteString -> IO PubKey
Low.pubKeyLoadECDSA MP
public_x MP
public_y ByteString
curve_name
{-# NOINLINE loadECDSAPubKey #-}

-- Ed25519

-- NOTE: Input must be exactly 32 bytes long
loadEd25519PrivKey :: ByteString -> PrivKey
loadEd25519PrivKey :: ByteString -> PrivKey
loadEd25519PrivKey ByteString
bytes = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ ByteString -> IO PrivKey
Low.privKeyLoadEd25519 ByteString
bytes
{-# NOINLINE loadEd25519PrivKey #-}

-- NOTE: Input must be exactly 32 bytes long
loadEd25519PubKey :: ByteString -> PubKey
loadEd25519PubKey :: ByteString -> PubKey
loadEd25519PubKey ByteString
bytes = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ ByteString -> IO PubKey
Low.pubKeyLoadEd25519 ByteString
bytes
{-# NOINLINE loadEd25519PubKey #-}

exportEd25519PrivKey :: PrivKey -> ByteString
exportEd25519PrivKey :: PrivKey -> ByteString
exportEd25519PrivKey PrivKey
k = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PrivKey -> IO ByteString
Low.privKeyEd25519GetPrivKey PrivKey
k
{-# NOINLINE exportEd25519PrivKey #-}

exportEd25519PubKey :: PubKey -> ByteString
exportEd25519PubKey :: PubKey -> ByteString
exportEd25519PubKey PubKey
k = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PubKey -> IO ByteString
Low.pubKeyEd25519GetPubKey PubKey
k
{-# NOINLINE exportEd25519PubKey #-}

-- ElGamal

newElGamalPrivKey :: (MonadRandomIO m) => Int -> Int -> m PrivKey
newElGamalPrivKey :: forall (m :: * -> *). MonadRandomIO m => Int -> Int -> m PrivKey
newElGamalPrivKey Int
pbits Int
qbits = do
    RNG
rng <- m RNG
forall (m :: * -> *). MonadRandomIO m => m RNG
getRNG
    IO PrivKey -> m PrivKey
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PrivKey -> m PrivKey) -> IO PrivKey -> m PrivKey
forall a b. (a -> b) -> a -> b
$ RNG -> Int -> Int -> IO PrivKey
Low.privKeyCreateDSA RNG
rng Int
pbits Int
qbits

loadElGamalPrivKey :: MP -> MP -> MP -> PrivKey
loadElGamalPrivKey :: MP -> MP -> MP -> PrivKey
loadElGamalPrivKey MP
p MP
g MP
x = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> IO PrivKey
Low.privKeyLoadElGamal MP
p MP
g MP
x
{-# NOINLINE loadElGamalPrivKey #-}

loadElGamalPubKey :: MP -> MP -> MP -> PubKey
loadElGamalPubKey :: MP -> MP -> MP -> PubKey
loadElGamalPubKey MP
p MP
g MP
y = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> IO PubKey
Low.pubKeyLoadElGamal MP
p MP
g MP
y
{-# NOINLINE loadElGamalPubKey #-}

-- RSA

loadRSAPrivKey :: MP -> MP -> MP -> PrivKey
loadRSAPrivKey :: MP -> MP -> MP -> PrivKey
loadRSAPrivKey MP
p MP
q MP
e = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> MP -> IO PrivKey
Low.privKeyLoadRSA MP
p MP
q MP
e
{-# NOINLINE loadRSAPrivKey #-}

loadRSAPubKey :: MP -> MP -> PubKey
loadRSAPubKey :: MP -> MP -> PubKey
loadRSAPubKey MP
n MP
e = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> IO PubKey
Low.pubKeyLoadRSA MP
n MP
e
{-# NOINLINE loadRSAPubKey #-}

-- SM2

loadSM2PrivKey :: MP -> ByteString -> PrivKey
loadSM2PrivKey :: MP -> ByteString -> PrivKey
loadSM2PrivKey MP
scalar ByteString
curve_name = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ MP -> ByteString -> IO PrivKey
Low.privKeyLoadSM2 MP
scalar ByteString
curve_name
{-# NOINLINE loadSM2PrivKey #-}

loadSM2PubKey :: MP -> MP -> ByteString -> PubKey
loadSM2PubKey :: MP -> MP -> ByteString -> PubKey
loadSM2PubKey MP
public_x MP
public_y ByteString
curve_name = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ MP -> MP -> ByteString -> IO PubKey
Low.pubKeyLoadSM2 MP
public_x MP
public_y ByteString
curve_name
{-# NOINLINE loadSM2PubKey #-}

-- X25519 /  Curve25519

-- NOTE: Input must be exactly 32 bytes long
loadX25519PrivKey :: ByteString -> PrivKey
loadX25519PrivKey :: ByteString -> PrivKey
loadX25519PrivKey ByteString
bytes = IO PrivKey -> PrivKey
forall a. IO a -> a
unsafePerformIO (IO PrivKey -> PrivKey) -> IO PrivKey -> PrivKey
forall a b. (a -> b) -> a -> b
$ ByteString -> IO PrivKey
Low.privKeyLoadX25519 ByteString
bytes
{-# NOINLINE loadX25519PrivKey #-}

-- NOTE: Input must be exactly 32 bytes long
loadX25519PubKey :: ByteString -> PubKey
loadX25519PubKey :: ByteString -> PubKey
loadX25519PubKey ByteString
bytes = IO PubKey -> PubKey
forall a. IO a -> a
unsafePerformIO (IO PubKey -> PubKey) -> IO PubKey -> PubKey
forall a b. (a -> b) -> a -> b
$ ByteString -> IO PubKey
Low.pubKeyLoadX25519 ByteString
bytes
{-# NOINLINE loadX25519PubKey #-}

exportX25519PrivKey :: PrivKey -> ByteString
exportX25519PrivKey :: PrivKey -> ByteString
exportX25519PrivKey PrivKey
k = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PrivKey -> IO ByteString
Low.privKeyX25519GetPrivKey PrivKey
k
{-# NOINLINE exportX25519PrivKey #-}

exportX25519PubKey :: PubKey -> ByteString
exportX25519PubKey :: PubKey -> ByteString
exportX25519PubKey PubKey
k = IO ByteString -> ByteString
forall a. IO a -> a
unsafePerformIO (IO ByteString -> ByteString) -> IO ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PubKey -> IO ByteString
Low.pubKeyX25519GetPubKey PubKey
k
{-# NOINLINE exportX25519PubKey #-}