module Erebos.PubKey (
    PublicKey, SecretKey,
    KeyPair(generateKeys), loadKey, loadKeyMb,
    Signature(sigKey), Signed, signedData, signedSignature,
    sign, signAdd, isSignedBy,
    fromSigned,
    unsafeMapSigned,

    PublicKexKey, SecretKexKey,
    dhSecret,
) where

import Control.Monad
import Control.Monad.Except

import Crypto.Error
import qualified Crypto.PubKey.Ed25519 as ED
import qualified Crypto.PubKey.Curve25519 as CX

import Data.ByteArray
import Data.ByteString (ByteString)
import qualified Data.Text as T

import Erebos.Storage
import Erebos.Storage.Key

data PublicKey = PublicKey ED.PublicKey
    deriving (Int -> PublicKey -> ShowS
[PublicKey] -> ShowS
PublicKey -> String
(Int -> PublicKey -> ShowS)
-> (PublicKey -> String)
-> ([PublicKey] -> ShowS)
-> Show PublicKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PublicKey -> ShowS
showsPrec :: Int -> PublicKey -> ShowS
$cshow :: PublicKey -> String
show :: PublicKey -> String
$cshowList :: [PublicKey] -> ShowS
showList :: [PublicKey] -> ShowS
Show)

data SecretKey = SecretKey ED.SecretKey (Stored PublicKey)

data Signature = Signature
    { Signature -> Stored PublicKey
sigKey :: Stored PublicKey
    , Signature -> Signature
sigSignature :: ED.Signature
    }
    deriving (Int -> Signature -> ShowS
[Signature] -> ShowS
Signature -> String
(Int -> Signature -> ShowS)
-> (Signature -> String)
-> ([Signature] -> ShowS)
-> Show Signature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Signature -> ShowS
showsPrec :: Int -> Signature -> ShowS
$cshow :: Signature -> String
show :: Signature -> String
$cshowList :: [Signature] -> ShowS
showList :: [Signature] -> ShowS
Show)

data Signed a = Signed
    { forall a. Signed a -> Stored a
signedData_ :: Stored a
    , forall a. Signed a -> [Stored Signature]
signedSignature_ :: [Stored Signature]
    }
    deriving (Int -> Signed a -> ShowS
[Signed a] -> ShowS
Signed a -> String
(Int -> Signed a -> ShowS)
-> (Signed a -> String) -> ([Signed a] -> ShowS) -> Show (Signed a)
forall a. Show a => Int -> Signed a -> ShowS
forall a. Show a => [Signed a] -> ShowS
forall a. Show a => Signed a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Signed a -> ShowS
showsPrec :: Int -> Signed a -> ShowS
$cshow :: forall a. Show a => Signed a -> String
show :: Signed a -> String
$cshowList :: forall a. Show a => [Signed a] -> ShowS
showList :: [Signed a] -> ShowS
Show)

signedData :: Signed a -> Stored a
signedData :: forall a. Signed a -> Stored a
signedData = Signed a -> Stored a
forall a. Signed a -> Stored a
signedData_

signedSignature :: Signed a -> [Stored Signature]
signedSignature :: forall a. Signed a -> [Stored Signature]
signedSignature = Signed a -> [Stored Signature]
forall a. Signed a -> [Stored Signature]
signedSignature_

instance KeyPair SecretKey PublicKey where
    keyGetPublic :: SecretKey -> Stored PublicKey
keyGetPublic (SecretKey SecretKey
_ Stored PublicKey
pub) = Stored PublicKey
pub
    keyGetData :: SecretKey -> ScrubbedBytes
keyGetData (SecretKey SecretKey
sec Stored PublicKey
_) = SecretKey -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert SecretKey
sec
    keyFromData :: ScrubbedBytes -> Stored PublicKey -> Maybe SecretKey
keyFromData ScrubbedBytes
kdata Stored PublicKey
spub = do
        SecretKey
skey <- CryptoFailable SecretKey -> Maybe SecretKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable SecretKey -> Maybe SecretKey)
-> CryptoFailable SecretKey -> Maybe SecretKey
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> CryptoFailable SecretKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable SecretKey
ED.secretKey ScrubbedBytes
kdata
        let PublicKey PublicKey
pkey = Stored PublicKey -> PublicKey
forall a. Stored a -> a
fromStored Stored PublicKey
spub
        Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey
ED.toPublic SecretKey
skey PublicKey -> PublicKey -> Bool
forall a. Eq a => a -> a -> Bool
== PublicKey
pkey
        SecretKey -> Maybe SecretKey
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (SecretKey -> Maybe SecretKey) -> SecretKey -> Maybe SecretKey
forall a b. (a -> b) -> a -> b
$ SecretKey -> Stored PublicKey -> SecretKey
SecretKey SecretKey
skey Stored PublicKey
spub
    generateKeys :: Storage -> IO (SecretKey, Stored PublicKey)
generateKeys Storage
st = do
        SecretKey
secret <- IO SecretKey
forall (m :: * -> *). MonadRandom m => m SecretKey
ED.generateSecretKey
        Stored PublicKey
public <- Storage -> PublicKey -> IO (Stored PublicKey)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Storage -> a -> m (Stored a)
wrappedStore Storage
st (PublicKey -> IO (Stored PublicKey))
-> PublicKey -> IO (Stored PublicKey)
forall a b. (a -> b) -> a -> b
$ PublicKey -> PublicKey
PublicKey (PublicKey -> PublicKey) -> PublicKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey
ED.toPublic SecretKey
secret
        let pair :: SecretKey
pair = SecretKey -> Stored PublicKey -> SecretKey
SecretKey SecretKey
secret Stored PublicKey
public
        SecretKey -> IO ()
forall sec pub. KeyPair sec pub => sec -> IO ()
storeKey SecretKey
pair
        (SecretKey, Stored PublicKey) -> IO (SecretKey, Stored PublicKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (SecretKey
pair, Stored PublicKey
public)

instance Storable PublicKey where
    store' :: PublicKey -> Store
store' (PublicKey PublicKey
pk) = (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
storeRec ((forall (c :: * -> *). StorageCompleteness c => StoreRec c)
 -> Store)
-> (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
forall a b. (a -> b) -> a -> b
$ do
        String -> Text -> StoreRec c
forall a (c :: * -> *). StorableText a => String -> a -> StoreRec c
storeText String
"type" (Text -> StoreRec c) -> Text -> StoreRec c
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
"ed25519"
        String -> PublicKey -> StoreRec c
forall a (c :: * -> *).
ByteArrayAccess a =>
String -> a -> StoreRec c
storeBinary String
"pubkey" PublicKey
pk

    load' :: Load PublicKey
load' = LoadRec PublicKey -> Load PublicKey
forall a. LoadRec a -> Load a
loadRec (LoadRec PublicKey -> Load PublicKey)
-> LoadRec PublicKey -> Load PublicKey
forall a b. (a -> b) -> a -> b
$ do
        String
ktype <- String -> LoadRec String
forall a. StorableText a => String -> LoadRec a
loadText String
"type"
        Bool -> LoadRec ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> LoadRec ()) -> Bool -> LoadRec ()
forall a b. (a -> b) -> a -> b
$ String
ktype String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"ed25519"
        LoadRec PublicKey
-> (PublicKey -> LoadRec PublicKey)
-> Maybe PublicKey
-> LoadRec PublicKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> LoadRec PublicKey
forall a. String -> LoadRec a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"Public key decoding failed") (PublicKey -> LoadRec PublicKey
forall a. a -> LoadRec a
forall (m :: * -> *) a. Monad m => a -> m a
return (PublicKey -> LoadRec PublicKey)
-> (PublicKey -> PublicKey) -> PublicKey -> LoadRec PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> PublicKey
PublicKey) (Maybe PublicKey -> LoadRec PublicKey)
-> (ByteString -> Maybe PublicKey)
-> ByteString
-> LoadRec PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            CryptoFailable PublicKey -> Maybe PublicKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable PublicKey -> Maybe PublicKey)
-> (ByteString -> CryptoFailable PublicKey)
-> ByteString
-> Maybe PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> CryptoFailable PublicKey
forall ba. ByteArrayAccess ba => ba -> CryptoFailable PublicKey
ED.publicKey :: ByteString -> CryptoFailable ED.PublicKey) (ByteString -> LoadRec PublicKey)
-> LoadRec ByteString -> LoadRec PublicKey
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                String -> LoadRec ByteString
forall a. ByteArray a => String -> LoadRec a
loadBinary String
"pubkey"

instance Storable Signature where
    store' :: Signature -> Store
store' Signature
sig = (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
storeRec ((forall (c :: * -> *). StorageCompleteness c => StoreRec c)
 -> Store)
-> (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
forall a b. (a -> b) -> a -> b
$ do
        String -> Stored PublicKey -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"key" (Stored PublicKey -> StoreRec c) -> Stored PublicKey -> StoreRec c
forall a b. (a -> b) -> a -> b
$ Signature -> Stored PublicKey
sigKey Signature
sig
        String -> Signature -> StoreRec c
forall a (c :: * -> *).
ByteArrayAccess a =>
String -> a -> StoreRec c
storeBinary String
"sig" (Signature -> StoreRec c) -> Signature -> StoreRec c
forall a b. (a -> b) -> a -> b
$ Signature -> Signature
sigSignature Signature
sig

    load' :: Load Signature
load' = LoadRec Signature -> Load Signature
forall a. LoadRec a -> Load a
loadRec (LoadRec Signature -> Load Signature)
-> LoadRec Signature -> Load Signature
forall a b. (a -> b) -> a -> b
$ Stored PublicKey -> Signature -> Signature
Signature
        (Stored PublicKey -> Signature -> Signature)
-> LoadRec (Stored PublicKey) -> LoadRec (Signature -> Signature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> LoadRec (Stored PublicKey)
forall a. Storable a => String -> LoadRec a
loadRef String
"key"
        LoadRec (Signature -> Signature)
-> LoadRec Signature -> LoadRec Signature
forall a b. LoadRec (a -> b) -> LoadRec a -> LoadRec b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> LoadRec Signature
loadSignature String
"sig"
        where loadSignature :: String -> LoadRec Signature
loadSignature = LoadRec Signature
-> (Signature -> LoadRec Signature)
-> Maybe Signature
-> LoadRec Signature
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> LoadRec Signature
forall a. String -> LoadRec a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"Signature decoding failed") Signature -> LoadRec Signature
forall a. a -> LoadRec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Signature -> LoadRec Signature)
-> (ByteString -> Maybe Signature)
-> ByteString
-> LoadRec Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
                  CryptoFailable Signature -> Maybe Signature
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable Signature -> Maybe Signature)
-> (ByteString -> CryptoFailable Signature)
-> ByteString
-> Maybe Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> CryptoFailable Signature
forall ba. ByteArrayAccess ba => ba -> CryptoFailable Signature
ED.signature :: ByteString -> CryptoFailable ED.Signature) (ByteString -> LoadRec Signature)
-> (String -> LoadRec ByteString) -> String -> LoadRec Signature
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< String -> LoadRec ByteString
forall a. ByteArray a => String -> LoadRec a
loadBinary

instance Storable a => Storable (Signed a) where
    store' :: Signed a -> Store
store' Signed a
sig = (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
storeRec ((forall (c :: * -> *). StorageCompleteness c => StoreRec c)
 -> Store)
-> (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
forall a b. (a -> b) -> a -> b
$ do
        String -> Stored a -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"SDATA" (Stored a -> StoreRec c) -> Stored a -> StoreRec c
forall a b. (a -> b) -> a -> b
$ Signed a -> Stored a
forall a. Signed a -> Stored a
signedData Signed a
sig
        (Stored Signature -> StoreRec c)
-> [Stored Signature] -> StoreRec c
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> Stored Signature -> StoreRec c
forall a (c :: * -> *).
(Storable a, StorageCompleteness c) =>
String -> a -> StoreRec c
storeRef String
"sig") ([Stored Signature] -> StoreRec c)
-> [Stored Signature] -> StoreRec c
forall a b. (a -> b) -> a -> b
$ Signed a -> [Stored Signature]
forall a. Signed a -> [Stored Signature]
signedSignature Signed a
sig

    load' :: Load (Signed a)
load' = LoadRec (Signed a) -> Load (Signed a)
forall a. LoadRec a -> Load a
loadRec (LoadRec (Signed a) -> Load (Signed a))
-> LoadRec (Signed a) -> Load (Signed a)
forall a b. (a -> b) -> a -> b
$ do
        Stored a
sdata <- String -> LoadRec (Stored a)
forall a. Storable a => String -> LoadRec a
loadRef String
"SDATA"
        [Stored Signature]
sigs <- String -> LoadRec [Stored Signature]
forall a. Storable a => String -> LoadRec [a]
loadRefs String
"sig"
        [Stored Signature]
-> (Stored Signature -> LoadRec ()) -> LoadRec ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Stored Signature]
sigs ((Stored Signature -> LoadRec ()) -> LoadRec ())
-> (Stored Signature -> LoadRec ()) -> LoadRec ()
forall a b. (a -> b) -> a -> b
$ \Stored Signature
sig -> do
            let PublicKey PublicKey
pubkey = Stored PublicKey -> PublicKey
forall a. Stored a -> a
fromStored (Stored PublicKey -> PublicKey) -> Stored PublicKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ Signature -> Stored PublicKey
sigKey (Signature -> Stored PublicKey) -> Signature -> Stored PublicKey
forall a b. (a -> b) -> a -> b
$ Stored Signature -> Signature
forall a. Stored a -> a
fromStored Stored Signature
sig
            Bool -> LoadRec () -> LoadRec ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ PublicKey -> Ref -> Signature -> Bool
forall ba.
ByteArrayAccess ba =>
PublicKey -> ba -> Signature -> Bool
ED.verify PublicKey
pubkey (Stored a -> Ref
forall a. Stored a -> Ref
storedRef Stored a
sdata) (Signature -> Bool) -> Signature -> Bool
forall a b. (a -> b) -> a -> b
$ Signature -> Signature
sigSignature (Signature -> Signature) -> Signature -> Signature
forall a b. (a -> b) -> a -> b
$ Stored Signature -> Signature
forall a. Stored a -> a
fromStored Stored Signature
sig) (LoadRec () -> LoadRec ()) -> LoadRec () -> LoadRec ()
forall a b. (a -> b) -> a -> b
$
                String -> LoadRec ()
forall a. String -> LoadRec a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"signature verification failed"
        Signed a -> LoadRec (Signed a)
forall a. a -> LoadRec a
forall (m :: * -> *) a. Monad m => a -> m a
return (Signed a -> LoadRec (Signed a)) -> Signed a -> LoadRec (Signed a)
forall a b. (a -> b) -> a -> b
$ Stored a -> [Stored Signature] -> Signed a
forall a. Stored a -> [Stored Signature] -> Signed a
Signed Stored a
sdata [Stored Signature]
sigs

sign :: MonadStorage m => SecretKey -> Stored a -> m (Signed a)
sign :: forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Stored a -> m (Signed a)
sign SecretKey
secret Stored a
val = SecretKey -> Signed a -> m (Signed a)
forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Signed a -> m (Signed a)
signAdd SecretKey
secret (Signed a -> m (Signed a)) -> Signed a -> m (Signed a)
forall a b. (a -> b) -> a -> b
$ Stored a -> [Stored Signature] -> Signed a
forall a. Stored a -> [Stored Signature] -> Signed a
Signed Stored a
val []

signAdd :: MonadStorage m => SecretKey -> Signed a -> m (Signed a)
signAdd :: forall (m :: * -> *) a.
MonadStorage m =>
SecretKey -> Signed a -> m (Signed a)
signAdd (SecretKey SecretKey
secret Stored PublicKey
spublic) (Signed Stored a
val [Stored Signature]
sigs) = do
    let PublicKey PublicKey
public = Stored PublicKey -> PublicKey
forall a. Stored a -> a
fromStored Stored PublicKey
spublic
        sig :: Signature
sig = SecretKey -> PublicKey -> Ref -> Signature
forall ba.
ByteArrayAccess ba =>
SecretKey -> PublicKey -> ba -> Signature
ED.sign SecretKey
secret PublicKey
public (Ref -> Signature) -> Ref -> Signature
forall a b. (a -> b) -> a -> b
$ Stored a -> Ref
forall a. Stored a -> Ref
storedRef Stored a
val
    Stored Signature
ssig <- Signature -> m (Stored Signature)
forall a. Storable a => a -> m (Stored a)
forall (m :: * -> *) a.
(MonadStorage m, Storable a) =>
a -> m (Stored a)
mstore (Signature -> m (Stored Signature))
-> Signature -> m (Stored Signature)
forall a b. (a -> b) -> a -> b
$ Stored PublicKey -> Signature -> Signature
Signature Stored PublicKey
spublic Signature
sig
    Signed a -> m (Signed a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Signed a -> m (Signed a)) -> Signed a -> m (Signed a)
forall a b. (a -> b) -> a -> b
$ Stored a -> [Stored Signature] -> Signed a
forall a. Stored a -> [Stored Signature] -> Signed a
Signed Stored a
val (Stored Signature
ssig Stored Signature -> [Stored Signature] -> [Stored Signature]
forall a. a -> [a] -> [a]
: [Stored Signature]
sigs)

isSignedBy :: Signed a -> Stored PublicKey -> Bool
isSignedBy :: forall a. Signed a -> Stored PublicKey -> Bool
isSignedBy Signed a
sig Stored PublicKey
key = Stored PublicKey
key Stored PublicKey -> [Stored PublicKey] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (Stored Signature -> Stored PublicKey)
-> [Stored Signature] -> [Stored PublicKey]
forall a b. (a -> b) -> [a] -> [b]
map (Signature -> Stored PublicKey
sigKey (Signature -> Stored PublicKey)
-> (Stored Signature -> Signature)
-> Stored Signature
-> Stored PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored Signature -> Signature
forall a. Stored a -> a
fromStored) (Signed a -> [Stored Signature]
forall a. Signed a -> [Stored Signature]
signedSignature Signed a
sig)

fromSigned :: Stored (Signed a) -> a
fromSigned :: forall a. Stored (Signed a) -> a
fromSigned = Stored a -> a
forall a. Stored a -> a
fromStored (Stored a -> a)
-> (Stored (Signed a) -> Stored a) -> Stored (Signed a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signed a -> Stored a
forall a. Signed a -> Stored a
signedData (Signed a -> Stored a)
-> (Stored (Signed a) -> Signed a) -> Stored (Signed a) -> Stored a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stored (Signed a) -> Signed a
forall a. Stored a -> a
fromStored

-- |Passed function needs to preserve the object representation to be safe
unsafeMapSigned :: (a -> b) -> Signed a -> Signed b
unsafeMapSigned :: forall a b. (a -> b) -> Signed a -> Signed b
unsafeMapSigned a -> b
f Signed a
signed = Signed a
signed { signedData_ = unsafeMapStored f (signedData_ signed) }


data PublicKexKey = PublicKexKey CX.PublicKey
    deriving (Int -> PublicKexKey -> ShowS
[PublicKexKey] -> ShowS
PublicKexKey -> String
(Int -> PublicKexKey -> ShowS)
-> (PublicKexKey -> String)
-> ([PublicKexKey] -> ShowS)
-> Show PublicKexKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PublicKexKey -> ShowS
showsPrec :: Int -> PublicKexKey -> ShowS
$cshow :: PublicKexKey -> String
show :: PublicKexKey -> String
$cshowList :: [PublicKexKey] -> ShowS
showList :: [PublicKexKey] -> ShowS
Show)

data SecretKexKey = SecretKexKey CX.SecretKey (Stored PublicKexKey)

instance KeyPair SecretKexKey PublicKexKey where
    keyGetPublic :: SecretKexKey -> Stored PublicKexKey
keyGetPublic (SecretKexKey SecretKey
_ Stored PublicKexKey
pub) = Stored PublicKexKey
pub
    keyGetData :: SecretKexKey -> ScrubbedBytes
keyGetData (SecretKexKey SecretKey
sec Stored PublicKexKey
_) = SecretKey -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert SecretKey
sec
    keyFromData :: ScrubbedBytes -> Stored PublicKexKey -> Maybe SecretKexKey
keyFromData ScrubbedBytes
kdata Stored PublicKexKey
spub = do
        SecretKey
skey <- CryptoFailable SecretKey -> Maybe SecretKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable SecretKey -> Maybe SecretKey)
-> CryptoFailable SecretKey -> Maybe SecretKey
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> CryptoFailable SecretKey
forall bs. ByteArrayAccess bs => bs -> CryptoFailable SecretKey
CX.secretKey ScrubbedBytes
kdata
        let PublicKexKey PublicKey
pkey = Stored PublicKexKey -> PublicKexKey
forall a. Stored a -> a
fromStored Stored PublicKexKey
spub
        Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey
CX.toPublic SecretKey
skey PublicKey -> PublicKey -> Bool
forall a. Eq a => a -> a -> Bool
== PublicKey
pkey
        SecretKexKey -> Maybe SecretKexKey
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (SecretKexKey -> Maybe SecretKexKey)
-> SecretKexKey -> Maybe SecretKexKey
forall a b. (a -> b) -> a -> b
$ SecretKey -> Stored PublicKexKey -> SecretKexKey
SecretKexKey SecretKey
skey Stored PublicKexKey
spub
    generateKeys :: Storage -> IO (SecretKexKey, Stored PublicKexKey)
generateKeys Storage
st = do
        SecretKey
secret <- IO SecretKey
forall (m :: * -> *). MonadRandom m => m SecretKey
CX.generateSecretKey
        Stored PublicKexKey
public <- Storage -> PublicKexKey -> IO (Stored PublicKexKey)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Storage -> a -> m (Stored a)
wrappedStore Storage
st (PublicKexKey -> IO (Stored PublicKexKey))
-> PublicKexKey -> IO (Stored PublicKexKey)
forall a b. (a -> b) -> a -> b
$ PublicKey -> PublicKexKey
PublicKexKey (PublicKey -> PublicKexKey) -> PublicKey -> PublicKexKey
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey
CX.toPublic SecretKey
secret
        let pair :: SecretKexKey
pair = SecretKey -> Stored PublicKexKey -> SecretKexKey
SecretKexKey SecretKey
secret Stored PublicKexKey
public
        SecretKexKey -> IO ()
forall sec pub. KeyPair sec pub => sec -> IO ()
storeKey SecretKexKey
pair
        (SecretKexKey, Stored PublicKexKey)
-> IO (SecretKexKey, Stored PublicKexKey)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (SecretKexKey
pair, Stored PublicKexKey
public)

instance Storable PublicKexKey where
    store' :: PublicKexKey -> Store
store' (PublicKexKey PublicKey
pk) = (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
storeRec ((forall (c :: * -> *). StorageCompleteness c => StoreRec c)
 -> Store)
-> (forall (c :: * -> *). StorageCompleteness c => StoreRec c)
-> Store
forall a b. (a -> b) -> a -> b
$ do
        String -> Text -> StoreRec c
forall a (c :: * -> *). StorableText a => String -> a -> StoreRec c
storeText String
"type" (Text -> StoreRec c) -> Text -> StoreRec c
forall a b. (a -> b) -> a -> b
$ String -> Text
T.pack String
"x25519"
        String -> PublicKey -> StoreRec c
forall a (c :: * -> *).
ByteArrayAccess a =>
String -> a -> StoreRec c
storeBinary String
"pubkey" PublicKey
pk

    load' :: Load PublicKexKey
load' = LoadRec PublicKexKey -> Load PublicKexKey
forall a. LoadRec a -> Load a
loadRec (LoadRec PublicKexKey -> Load PublicKexKey)
-> LoadRec PublicKexKey -> Load PublicKexKey
forall a b. (a -> b) -> a -> b
$ do
        String
ktype <- String -> LoadRec String
forall a. StorableText a => String -> LoadRec a
loadText String
"type"
        Bool -> LoadRec ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> LoadRec ()) -> Bool -> LoadRec ()
forall a b. (a -> b) -> a -> b
$ String
ktype String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"x25519"
        LoadRec PublicKexKey
-> (PublicKey -> LoadRec PublicKexKey)
-> Maybe PublicKey
-> LoadRec PublicKexKey
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> LoadRec PublicKexKey
forall a. String -> LoadRec a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError String
"public key decoding failed") (PublicKexKey -> LoadRec PublicKexKey
forall a. a -> LoadRec a
forall (m :: * -> *) a. Monad m => a -> m a
return (PublicKexKey -> LoadRec PublicKexKey)
-> (PublicKey -> PublicKexKey) -> PublicKey -> LoadRec PublicKexKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> PublicKexKey
PublicKexKey) (Maybe PublicKey -> LoadRec PublicKexKey)
-> (ScrubbedBytes -> Maybe PublicKey)
-> ScrubbedBytes
-> LoadRec PublicKexKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            CryptoFailable PublicKey -> Maybe PublicKey
forall a. CryptoFailable a -> Maybe a
maybeCryptoError (CryptoFailable PublicKey -> Maybe PublicKey)
-> (ScrubbedBytes -> CryptoFailable PublicKey)
-> ScrubbedBytes
-> Maybe PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ScrubbedBytes -> CryptoFailable PublicKey
forall bs. ByteArrayAccess bs => bs -> CryptoFailable PublicKey
CX.publicKey :: ScrubbedBytes -> CryptoFailable CX.PublicKey) (ScrubbedBytes -> LoadRec PublicKexKey)
-> LoadRec ScrubbedBytes -> LoadRec PublicKexKey
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<
                String -> LoadRec ScrubbedBytes
forall a. ByteArray a => String -> LoadRec a
loadBinary String
"pubkey"

dhSecret :: SecretKexKey -> PublicKexKey -> ScrubbedBytes
dhSecret :: SecretKexKey -> PublicKexKey -> ScrubbedBytes
dhSecret (SecretKexKey SecretKey
secret Stored PublicKexKey
_) (PublicKexKey PublicKey
public) = DhSecret -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
convert (DhSecret -> ScrubbedBytes) -> DhSecret -> ScrubbedBytes
forall a b. (a -> b) -> a -> b
$ PublicKey -> SecretKey -> DhSecret
CX.dh PublicKey
public SecretKey
secret