{-|
Module      : Botan.Decrypt
Description : Public Key Decryption
Copyright   : (c) Leo D, 2023
License     : BSD-3-Clause
Maintainer  : leo@apotheca.io
Stability   : experimental
Portability : POSIX
-}

module Botan.PubKey.Decrypt
(

-- * Thing
-- $introduction

-- * Usage
-- $usage

-- * Public Key Decryption

  pkDecrypt
, pkDecryptOutputLength

-- * Mutable interface

-- ** Data type
, PKDecrypt(..)

-- ** Destructor
, destroyPKDecrypt

-- ** Initializers
, newPKDecrypt

-- ** Accessors
, getPKDecryptOutputLength

-- ** Algorithm
, pkDecryptWith

) where

import qualified Data.ByteString as ByteString

import qualified Botan.Low.PubKey.Decrypt as Low

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


{- $introduction

-}

{- $usage

-}

--
-- Public Key Decryption
--

pkDecrypt :: PrivKey -> PKPadding -> ByteString -> Maybe ByteString
pkDecrypt :: PrivKey -> PKPadding -> ByteString -> Maybe ByteString
pkDecrypt PrivKey
pk PKPadding
padding ByteString
ciphertext = IO (Maybe ByteString) -> Maybe ByteString
forall a. IO a -> a
unsafePerformIO (IO (Maybe ByteString) -> Maybe ByteString)
-> IO (Maybe ByteString) -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ do
    PKDecrypt
ctx <- PrivKey -> PKPadding -> IO PKDecrypt
forall (m :: * -> *).
MonadIO m =>
PrivKey -> PKPadding -> m PKDecrypt
newPKDecrypt PrivKey
pk PKPadding
padding
    -- TODO: Return nothing on catch error
    ByteString
pt <- PKDecrypt -> ByteString -> IO ByteString
forall (m :: * -> *).
MonadIO m =>
PKDecrypt -> ByteString -> m ByteString
pkDecryptWith PKDecrypt
ctx ByteString
ciphertext
    Maybe ByteString -> IO (Maybe ByteString)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ByteString -> IO (Maybe ByteString))
-> Maybe ByteString -> IO (Maybe ByteString)
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
pt
{-# NOINLINE pkDecrypt #-}

pkDecryptOutputLength :: PrivKey -> PKPadding -> Int -> Int
pkDecryptOutputLength :: PrivKey -> PKPadding -> Int -> Int
pkDecryptOutputLength PrivKey
pk PKPadding
padding Int
i = IO Int -> Int
forall a. IO a -> a
unsafePerformIO (IO Int -> Int) -> IO Int -> Int
forall a b. (a -> b) -> a -> b
$ do
    PKDecrypt
ctx <- PrivKey -> PKPadding -> IO PKDecrypt
forall (m :: * -> *).
MonadIO m =>
PrivKey -> PKPadding -> m PKDecrypt
newPKDecrypt PrivKey
pk PKPadding
padding
    PKDecrypt -> Int -> IO Int
forall (m :: * -> *). MonadIO m => PKDecrypt -> Int -> m Int
getPKDecryptOutputLength PKDecrypt
ctx Int
i
{-# NOINLINE pkDecryptOutputLength #-}

-- Data type

-- TODO: Maybe rename MutablePKDecrypt or PKDecryptor
type PKDecrypt = Low.Decrypt

-- Destructor

destroyPKDecrypt :: (MonadIO m) => PKDecrypt -> m ()
destroyPKDecrypt :: forall (m :: * -> *). MonadIO m => PKDecrypt -> m ()
destroyPKDecrypt = IO () -> m ()
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (PKDecrypt -> IO ()) -> PKDecrypt -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PKDecrypt -> IO ()
Low.decryptDestroy

-- Initializers

newPKDecrypt :: (MonadIO m) => PrivKey -> PKPadding -> m PKDecrypt
newPKDecrypt :: forall (m :: * -> *).
MonadIO m =>
PrivKey -> PKPadding -> m PKDecrypt
newPKDecrypt PrivKey
pk PKPadding
padding = IO PKDecrypt -> m PKDecrypt
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO PKDecrypt -> m PKDecrypt) -> IO PKDecrypt -> m PKDecrypt
forall a b. (a -> b) -> a -> b
$ PrivKey -> ByteString -> IO PKDecrypt
Low.decryptCreate PrivKey
pk (PKPadding -> ByteString
pkPaddingName PKPadding
padding)

-- Accessors

-- TODO: Verify
getPKDecryptOutputLength :: (MonadIO m) => PKDecrypt -> Int -> m Int
getPKDecryptOutputLength :: forall (m :: * -> *). MonadIO m => PKDecrypt -> Int -> m Int
getPKDecryptOutputLength PKDecrypt
pkd Int
i = IO Int -> m Int
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Int -> m Int) -> IO Int -> m Int
forall a b. (a -> b) -> a -> b
$ PKDecrypt -> Int -> IO Int
Low.decryptOutputLength PKDecrypt
pkd Int
i

-- Algorithm

pkDecryptWith :: (MonadIO m) => PKDecrypt -> ByteString -> m ByteString
pkDecryptWith :: forall (m :: * -> *).
MonadIO m =>
PKDecrypt -> ByteString -> m ByteString
pkDecryptWith PKDecrypt
pkd ByteString
bs = IO ByteString -> m ByteString
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> m ByteString) -> IO ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ PKDecrypt -> ByteString -> IO ByteString
Low.decrypt PKDecrypt
pkd ByteString
bs