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

module Botan.Low.PubKey.X25519 where

import qualified Data.ByteString as ByteString

import Botan.Bindings.PubKey

import Botan.Bindings.PubKey.X25519

import Botan.Low.Error
import Botan.Low.Make
import Botan.Low.MPI
import Botan.Low.Prelude
import Botan.Low.PubKey
import Botan.Low.Remake

-- /*
-- * Algorithm specific key operations: X25519
-- */

-- NOTE: X25519 is Curve25519:
--  lib/pubkey/curve25519/curve25519.h:
--      typedef Curve25519_PublicKey X25519_PublicKey;
--      typedef Curve25519_PrivateKey X25519_PrivateKey;

-- NOTE: Input must be exactly 32 bytes long
privKeyLoadX25519
    :: ByteString   -- ^ __privkey[32]__
    -> IO PrivKey   -- ^ __key__
privKeyLoadX25519 :: ByteString -> IO PrivKey
privKeyLoadX25519 = ((Ptr BotanPrivKey -> IO CInt) -> IO PrivKey)
-> (Ptr BotanPrivKey -> ConstPtr Word8 -> IO CInt)
-> ByteString
-> IO PrivKey
forall botan object.
((Ptr botan -> IO CInt) -> IO object)
-> (Ptr botan -> ConstPtr Word8 -> IO CInt)
-> ByteString
-> IO object
mkCreateObjectCBytes (Ptr BotanPrivKey -> IO CInt) -> IO PrivKey
createPrivKey Ptr BotanPrivKey -> ConstPtr Word8 -> IO CInt
botan_privkey_load_x25519

-- NOTE: Input must be exactly 32 bytes long
pubKeyLoadX25519
    :: ByteString   -- ^ __pubkey[32]__
    -> IO PubKey    -- ^ __key__
pubKeyLoadX25519 :: ByteString -> IO PubKey
pubKeyLoadX25519 = ((Ptr BotanPubKey -> IO CInt) -> IO PubKey)
-> (Ptr BotanPubKey -> ConstPtr Word8 -> IO CInt)
-> ByteString
-> IO PubKey
forall botan object.
((Ptr botan -> IO CInt) -> IO object)
-> (Ptr botan -> ConstPtr Word8 -> IO CInt)
-> ByteString
-> IO object
mkCreateObjectCBytes (Ptr BotanPubKey -> IO CInt) -> IO PubKey
createPubKey Ptr BotanPubKey -> ConstPtr Word8 -> IO CInt
botan_pubkey_load_x25519

privKeyX25519GetPrivKey
    :: PrivKey          -- ^ __key__
    -> IO ByteString    -- ^ __output[32]__
privKeyX25519GetPrivKey :: PrivKey -> IO ByteString
privKeyX25519GetPrivKey PrivKey
sk = PrivKey -> (BotanPrivKey -> IO ByteString) -> IO ByteString
forall a. PrivKey -> (BotanPrivKey -> IO a) -> IO a
withPrivKey PrivKey
sk ((BotanPrivKey -> IO ByteString) -> IO ByteString)
-> (BotanPrivKey -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ BotanPrivKey
skPtr -> do
    Int -> (Ptr Word8 -> IO ()) -> IO ByteString
forall byte. Int -> (Ptr byte -> IO ()) -> IO ByteString
allocBytes Int
32 ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr -> 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 -> IO CInt
botan_privkey_x25519_get_privkey BotanPrivKey
skPtr Ptr Word8
outPtr

pubKeyX25519GetPubKey
    :: PubKey           -- ^ __key__
    -> IO ByteString    -- ^ __pubkey[32]__
pubKeyX25519GetPubKey :: PubKey -> IO ByteString
pubKeyX25519GetPubKey PubKey
pk = PubKey -> (BotanPubKey -> IO ByteString) -> IO ByteString
forall a. PubKey -> (BotanPubKey -> IO a) -> IO a
withPubKey PubKey
pk ((BotanPubKey -> IO ByteString) -> IO ByteString)
-> (BotanPubKey -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ BotanPubKey
pkPtr -> do
    Int -> (Ptr Word8 -> IO ()) -> IO ByteString
forall byte. Int -> (Ptr byte -> IO ()) -> IO ByteString
allocBytes Int
32 ((Ptr Word8 -> IO ()) -> IO ByteString)
-> (Ptr Word8 -> IO ()) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \ Ptr Word8
outPtr -> 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 -> IO CInt
botan_pubkey_x25519_get_pubkey BotanPubKey
pkPtr Ptr Word8
outPtr