module Crypto.Saltine.Core.Box (
SecretKey, PublicKey, Keypair(..), CombinedKey, Nonce,
newKeypair, beforeNM, newNonce,
box, boxOpen,
boxAfterNM, boxOpenAfterNM,
boxSeal, boxSealOpen
) where
import Crypto.Saltine.Internal.Box
( c_box_keypair
, c_box_easy
, c_box_open_easy
, c_box_beforenm
, c_box_easy_afternm
, c_box_open_easy_afternm
, c_box_seal, c_box_seal_open
, SecretKey(..)
, PublicKey(..)
, Keypair(..)
, CombinedKey(..)
, Nonce(..)
)
import Crypto.Saltine.Internal.Util as U
import Data.ByteString (ByteString)
import qualified Crypto.Saltine.Internal.Box as Bytes
import qualified Data.ByteString as S
newKeypair :: IO Keypair
newKeypair :: IO Keypair
newKeypair = do
((CInt
_err, ByteString
sk), ByteString
pk) <- Int
-> (Ptr CChar -> IO (CInt, ByteString))
-> IO ((CInt, ByteString), ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> IO (b, ByteString)
buildUnsafeByteString' Int
Bytes.box_publickeybytes ((Ptr CChar -> IO (CInt, ByteString))
-> IO ((CInt, ByteString), ByteString))
-> (Ptr CChar -> IO (CInt, ByteString))
-> IO ((CInt, ByteString), ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pkbuf ->
Int -> (Ptr CChar -> IO CInt) -> IO (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> IO (b, ByteString)
buildUnsafeByteString' Int
Bytes.box_secretkeybytes ((Ptr CChar -> IO CInt) -> IO (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> IO (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
skbuf ->
Ptr CChar -> Ptr CChar -> IO CInt
c_box_keypair Ptr CChar
pkbuf Ptr CChar
skbuf
Keypair -> IO Keypair
forall (m :: * -> *) a. Monad m => a -> m a
return (Keypair -> IO Keypair) -> Keypair -> IO Keypair
forall a b. (a -> b) -> a -> b
$ SecretKey -> PublicKey -> Keypair
Keypair (ByteString -> SecretKey
SK ByteString
sk) (ByteString -> PublicKey
PK ByteString
pk)
newNonce :: IO Nonce
newNonce :: IO Nonce
newNonce = ByteString -> Nonce
Nonce (ByteString -> Nonce) -> IO ByteString -> IO Nonce
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IO ByteString
randomByteString Int
Bytes.box_noncebytes
beforeNM :: SecretKey -> PublicKey -> CombinedKey
beforeNM :: SecretKey -> PublicKey -> CombinedKey
beforeNM (SK ByteString
sk) (PK ByteString
pk) = ByteString -> CombinedKey
CK (ByteString -> CombinedKey) -> ByteString -> CombinedKey
forall a b. (a -> b) -> a -> b
$ (CInt, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((CInt, ByteString) -> ByteString)
-> (CInt, ByteString) -> ByteString
forall a b. (a -> b) -> a -> b
$ Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
Bytes.box_beforenmbytes ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ckbuf ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
pk, ByteString
sk] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \[(Ptr CChar
ppk, Int
_), (Ptr CChar
psk, Int
_)] ->
Ptr CChar -> Ptr CChar -> Ptr CChar -> IO CInt
c_box_beforenm Ptr CChar
ckbuf Ptr CChar
ppk Ptr CChar
psk
box :: PublicKey
-> SecretKey
-> Nonce
-> ByteString
-> ByteString
box :: PublicKey -> SecretKey -> Nonce -> ByteString -> ByteString
box (PK ByteString
pk) (SK ByteString
sk) (Nonce ByteString
nonce) ByteString
msg =
(CInt, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((CInt, ByteString) -> ByteString)
-> ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt)
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
bufSize ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt) -> ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pc ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
pk, ByteString
sk, ByteString
msg, ByteString
nonce] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \
[(Ptr CChar
ppk, Int
_), (Ptr CChar
psk, Int
_), (Ptr CChar
pm, Int
_), (Ptr CChar
pn, Int
_)] ->
Ptr CChar
-> Ptr CChar
-> CULLong
-> Ptr CChar
-> Ptr CChar
-> Ptr CChar
-> IO CInt
c_box_easy Ptr CChar
pc Ptr CChar
pm (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen) Ptr CChar
pn Ptr CChar
ppk Ptr CChar
psk
where
bufSize :: Int
bufSize = ByteString -> Int
S.length ByteString
msg Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
Bytes.box_macbytes
msgLen :: Int
msgLen = ByteString -> Int
S.length ByteString
msg
boxOpen :: PublicKey -> SecretKey -> Nonce
-> ByteString
-> Maybe ByteString
boxOpen :: PublicKey -> SecretKey -> Nonce -> ByteString -> Maybe ByteString
boxOpen (PK ByteString
pk) (SK ByteString
sk) (Nonce ByteString
nonce) ByteString
cipher = do
let msgLen :: Int
msgLen = ByteString -> Int
S.length ByteString
cipher
Int
bufSize <- Int
msgLen Int -> Int -> Maybe Int
forall a. (Ord a, Num a) => a -> a -> Maybe a
`safeSubtract` Int
Bytes.box_macbytes
let (CInt
err, ByteString
vec) = Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
bufSize ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pm ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
pk, ByteString
sk, ByteString
cipher, ByteString
nonce] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \
[(Ptr CChar
ppk, Int
_), (Ptr CChar
psk, Int
_), (Ptr CChar
pc, Int
_), (Ptr CChar
pn, Int
_)] ->
Ptr CChar
-> Ptr CChar
-> CULLong
-> Ptr CChar
-> Ptr CChar
-> Ptr CChar
-> IO CInt
c_box_open_easy Ptr CChar
pm Ptr CChar
pc (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen) Ptr CChar
pn Ptr CChar
ppk Ptr CChar
psk
Either String ByteString -> Maybe ByteString
forall s a. Either s a -> Maybe a
hush (Either String ByteString -> Maybe ByteString)
-> (ByteString -> Either String ByteString)
-> ByteString
-> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CInt -> ByteString -> Either String ByteString
forall a. CInt -> a -> Either String a
handleErrno CInt
err (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
vec
boxAfterNM :: CombinedKey
-> Nonce
-> ByteString
-> ByteString
boxAfterNM :: CombinedKey -> Nonce -> ByteString -> ByteString
boxAfterNM (CK ByteString
ck) (Nonce ByteString
nonce) ByteString
msg =
(CInt, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((CInt, ByteString) -> ByteString)
-> ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt)
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
bufSize ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt) -> ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pc ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
ck, ByteString
msg, ByteString
nonce] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \
[(Ptr CChar
pck, Int
_), (Ptr CChar
pm, Int
_), (Ptr CChar
pn, Int
_)] ->
Ptr CChar
-> Ptr CChar -> CULLong -> Ptr CChar -> Ptr CChar -> IO CInt
c_box_easy_afternm Ptr CChar
pc Ptr CChar
pm (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen) Ptr CChar
pn Ptr CChar
pck
where
bufSize :: Int
bufSize = ByteString -> Int
S.length ByteString
msg Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
Bytes.box_macbytes
msgLen :: Int
msgLen = ByteString -> Int
S.length ByteString
msg
boxOpenAfterNM :: CombinedKey
-> Nonce
-> ByteString
-> Maybe ByteString
boxOpenAfterNM :: CombinedKey -> Nonce -> ByteString -> Maybe ByteString
boxOpenAfterNM (CK ByteString
ck) (Nonce ByteString
nonce) ByteString
cipher = do
let msgLen :: Int
msgLen = ByteString -> Int
S.length ByteString
cipher
Int
bufSize <- Int
msgLen Int -> Int -> Maybe Int
forall a. (Ord a, Num a) => a -> a -> Maybe a
`safeSubtract` Int
Bytes.box_macbytes
let (CInt
err, ByteString
vec) = Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
bufSize ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pm ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
ck, ByteString
cipher, ByteString
nonce] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \
[(Ptr CChar
pck, Int
_), (Ptr CChar
pc, Int
_), (Ptr CChar
pn, Int
_)] ->
Ptr CChar
-> Ptr CChar -> CULLong -> Ptr CChar -> Ptr CChar -> IO CInt
c_box_open_easy_afternm Ptr CChar
pm Ptr CChar
pc (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen) Ptr CChar
pn Ptr CChar
pck
Either String ByteString -> Maybe ByteString
forall s a. Either s a -> Maybe a
hush (Either String ByteString -> Maybe ByteString)
-> (ByteString -> Either String ByteString)
-> ByteString
-> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CInt -> ByteString -> Either String ByteString
forall a. CInt -> a -> Either String a
handleErrno CInt
err (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
vec
boxSeal :: PublicKey -> ByteString -> IO ByteString
boxSeal :: PublicKey -> ByteString -> IO ByteString
boxSeal (PK ByteString
pk) ByteString
msg = ((CInt, ByteString) -> ByteString)
-> IO (CInt, ByteString) -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (CInt, ByteString) -> ByteString
forall a b. (a, b) -> b
snd (IO (CInt, ByteString) -> IO ByteString)
-> ((Ptr CChar -> IO CInt) -> IO (CInt, ByteString))
-> (Ptr CChar -> IO CInt)
-> IO ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Ptr CChar -> IO CInt) -> IO (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> IO (b, ByteString)
buildUnsafeByteString' Int
bufSize ((Ptr CChar -> IO CInt) -> IO ByteString)
-> (Ptr CChar -> IO CInt) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pc ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
pk, ByteString
msg] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \
[(Ptr CChar
ppk, Int
_), (Ptr CChar
pm, Int
_)] ->
Ptr CChar -> Ptr CChar -> CULLong -> Ptr CChar -> IO CInt
c_box_seal Ptr CChar
pc Ptr CChar
pm (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen) Ptr CChar
ppk
where
bufSize :: Int
bufSize = ByteString -> Int
S.length ByteString
msg Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
Bytes.box_sealbytes
msgLen :: Int
msgLen = ByteString -> Int
S.length ByteString
msg
boxSealOpen :: PublicKey
-> SecretKey
-> ByteString
-> Maybe ByteString
boxSealOpen :: PublicKey -> SecretKey -> ByteString -> Maybe ByteString
boxSealOpen (PK ByteString
pk) (SK ByteString
sk) ByteString
cipher = do
let msgLen :: Int
msgLen = ByteString -> Int
S.length ByteString
cipher
Int
bufSize <- Int
msgLen Int -> Int -> Maybe Int
forall a. (Ord a, Num a) => a -> a -> Maybe a
`safeSubtract` Int
Bytes.box_sealbytes
let (CInt
err, ByteString
vec) = Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
bufSize ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
pm ->
[ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
pk, ByteString
sk, ByteString
cipher] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \
[(Ptr CChar
ppk, Int
_), (Ptr CChar
psk, Int
_), (Ptr CChar
pc, Int
_)] ->
Ptr CChar
-> Ptr CChar -> CULLong -> Ptr CChar -> Ptr CChar -> IO CInt
c_box_seal_open Ptr CChar
pm Ptr CChar
pc (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
msgLen) Ptr CChar
ppk Ptr CChar
psk
Either String ByteString -> Maybe ByteString
forall s a. Either s a -> Maybe a
hush (Either String ByteString -> Maybe ByteString)
-> (ByteString -> Either String ByteString)
-> ByteString
-> Maybe ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CInt -> ByteString -> Either String ByteString
forall a. CInt -> a -> Either String a
handleErrno CInt
err (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ ByteString
vec