module NaCl.Box.Internal
( SecretKey
, toSecretKey
, PublicKey
, toPublicKey
, keypair
, Nonce
, toNonce
, create
, open
) where
import Prelude hiding (length)
import Data.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes, allocRet, length, withByteArray)
import Data.ByteArray.Sized (SizedByteArray, sizedByteArray)
import Data.ByteString (ByteString)
import Data.Functor (void)
import Data.Proxy (Proxy (Proxy))
import qualified Data.ByteArray.Sized as Sized (alloc, allocRet)
import qualified Libsodium as Na
type SecretKey a = SizedByteArray Na.CRYPTO_BOX_SECRETKEYBYTES a
toSecretKey :: ByteArrayAccess bytes => bytes -> Maybe (SecretKey bytes)
toSecretKey :: bytes -> Maybe (SecretKey bytes)
toSecretKey = bytes -> Maybe (SecretKey bytes)
forall (n :: Nat) ba.
(KnownNat n, ByteArrayAccess ba) =>
ba -> Maybe (SizedByteArray n ba)
sizedByteArray
type PublicKey a = SizedByteArray Na.CRYPTO_BOX_PUBLICKEYBYTES a
toPublicKey :: ByteArrayAccess bytes => bytes -> Maybe (PublicKey bytes)
toPublicKey :: bytes -> Maybe (PublicKey bytes)
toPublicKey = bytes -> Maybe (PublicKey bytes)
forall (n :: Nat) ba.
(KnownNat n, ByteArrayAccess ba) =>
ba -> Maybe (SizedByteArray n ba)
sizedByteArray
keypair :: IO (PublicKey ByteString, SecretKey ScrubbedBytes)
keypair :: IO (PublicKey ByteString, SecretKey ScrubbedBytes)
keypair = do
(PublicKey ByteString
pk, SecretKey ScrubbedBytes
sk) <-
Proxy 32
-> (Ptr CUChar -> IO (PublicKey ByteString))
-> IO (PublicKey ByteString, SecretKey ScrubbedBytes)
forall (n :: Nat) c p a.
ByteArrayN n c =>
Proxy n -> (Ptr p -> IO a) -> IO (a, c)
Sized.allocRet Proxy 32
forall k (t :: k). Proxy t
Proxy ((Ptr CUChar -> IO (PublicKey ByteString))
-> IO (PublicKey ByteString, SecretKey ScrubbedBytes))
-> (Ptr CUChar -> IO (PublicKey ByteString))
-> IO (PublicKey ByteString, SecretKey ScrubbedBytes)
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
skPtr ->
(Ptr CUChar -> IO ()) -> IO (PublicKey ByteString)
forall (n :: Nat) ba p.
(ByteArrayN n ba, KnownNat n) =>
(Ptr p -> IO ()) -> IO ba
Sized.alloc ((Ptr CUChar -> IO ()) -> IO (PublicKey ByteString))
-> (Ptr CUChar -> IO ()) -> IO (PublicKey ByteString)
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
pkPtr ->
IO CInt -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Ptr CUChar -> Ptr CUChar -> IO CInt
forall k1 k2 (pk :: k1) (sk :: k2).
Ptr CUChar -> Ptr CUChar -> IO CInt
Na.crypto_box_keypair Ptr CUChar
pkPtr Ptr CUChar
skPtr
(PublicKey ByteString, SecretKey ScrubbedBytes)
-> IO (PublicKey ByteString, SecretKey ScrubbedBytes)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PublicKey ByteString
pk, SecretKey ScrubbedBytes
sk)
type Nonce a = SizedByteArray Na.CRYPTO_BOX_NONCEBYTES a
toNonce :: ByteArrayAccess ba => ba -> Maybe (Nonce ba)
toNonce :: ba -> Maybe (Nonce ba)
toNonce = ba -> Maybe (Nonce ba)
forall (n :: Nat) ba.
(KnownNat n, ByteArrayAccess ba) =>
ba -> Maybe (SizedByteArray n ba)
sizedByteArray
create
:: ( ByteArrayAccess pkBytes, ByteArrayAccess skBytes
, ByteArrayAccess nonce
, ByteArrayAccess pt, ByteArray ct
)
=> PublicKey pkBytes
-> SecretKey skBytes
-> Nonce nonce
-> pt
-> IO ct
create :: PublicKey pkBytes
-> SecretKey skBytes -> Nonce nonce -> pt -> IO ct
create PublicKey pkBytes
pk SecretKey skBytes
sk Nonce nonce
nonce pt
msg = do
(CInt
_ret, ct
ct) <-
Int -> (Ptr CUChar -> IO CInt) -> IO (CInt, ct)
forall ba p a. ByteArray ba => Int -> (Ptr p -> IO a) -> IO (a, ba)
allocRet Int
clen ((Ptr CUChar -> IO CInt) -> IO (CInt, ct))
-> (Ptr CUChar -> IO CInt) -> IO (CInt, ct)
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
ctPtr ->
PublicKey pkBytes -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray PublicKey pkBytes
pk ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
pkPtr ->
SecretKey skBytes -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray SecretKey skBytes
sk ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
skPtr ->
Nonce nonce -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray Nonce nonce
nonce ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
noncePtr ->
pt -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray pt
msg ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
msgPtr -> do
Ptr CUChar
-> Ptr CUChar
-> (Any ::: CULLong)
-> Ptr CUChar
-> Ptr CUChar
-> Ptr CUChar
-> IO CInt
forall k1 k2 k3 k4 k5 k6 (c :: k1) (m :: k2) (mlen :: k3) (n :: k4)
(pk :: k5) (sk :: k6).
Ptr CUChar
-> Ptr CUChar
-> (Any ::: CULLong)
-> Ptr CUChar
-> Ptr CUChar
-> Ptr CUChar
-> IO CInt
Na.crypto_box_easy Ptr CUChar
ctPtr
Ptr CUChar
msgPtr (Int -> Any ::: CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Any ::: CULLong) -> Int -> Any ::: CULLong
forall a b. (a -> b) -> a -> b
$ pt -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length pt
msg)
Ptr CUChar
noncePtr
Ptr CUChar
pkPtr Ptr CUChar
skPtr
ct -> IO ct
forall (f :: * -> *) a. Applicative f => a -> f a
pure ct
ct
where
clen :: Int
clen :: Int
clen = CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
Na.crypto_box_macbytes Int -> Int -> Int
forall a. Num a => a -> a -> a
+ pt -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length pt
msg
open
:: ( ByteArrayAccess skBytes, ByteArrayAccess pkBytes
, ByteArrayAccess nonce
, ByteArray pt, ByteArrayAccess ct
)
=> SecretKey skBytes
-> PublicKey pkBytes
-> Nonce nonce
-> ct
-> IO (Maybe pt)
open :: SecretKey skBytes
-> PublicKey pkBytes -> Nonce nonce -> ct -> IO (Maybe pt)
open SecretKey skBytes
sk PublicKey pkBytes
pk Nonce nonce
nonce ct
ct = do
(CInt
ret, pt
msg) <-
Int -> (Ptr CUChar -> IO CInt) -> IO (CInt, pt)
forall ba p a. ByteArray ba => Int -> (Ptr p -> IO a) -> IO (a, ba)
allocRet Int
mlen ((Ptr CUChar -> IO CInt) -> IO (CInt, pt))
-> (Ptr CUChar -> IO CInt) -> IO (CInt, pt)
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
msgPtr ->
SecretKey skBytes -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray SecretKey skBytes
sk ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
skPtr ->
PublicKey pkBytes -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray PublicKey pkBytes
pk ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
pkPtr ->
Nonce nonce -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray Nonce nonce
nonce ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
noncePtr ->
ct -> (Ptr CUChar -> IO CInt) -> IO CInt
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
withByteArray ct
ct ((Ptr CUChar -> IO CInt) -> IO CInt)
-> (Ptr CUChar -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr CUChar
ctPtr -> do
Ptr CUChar
-> Ptr CUChar
-> (Any ::: CULLong)
-> Ptr CUChar
-> Ptr CUChar
-> Ptr CUChar
-> IO CInt
forall k1 k2 k3 k4 k5 k6 (c :: k1) (m :: k2) (mlen :: k3) (n :: k4)
(pk :: k5) (sk :: k6).
Ptr CUChar
-> Ptr CUChar
-> (Any ::: CULLong)
-> Ptr CUChar
-> Ptr CUChar
-> Ptr CUChar
-> IO CInt
Na.crypto_box_open_easy Ptr CUChar
msgPtr
Ptr CUChar
ctPtr (Int -> Any ::: CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Any ::: CULLong) -> Int -> Any ::: CULLong
forall a b. (a -> b) -> a -> b
$ ct -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length ct
ct)
Ptr CUChar
noncePtr
Ptr CUChar
pkPtr Ptr CUChar
skPtr
if CInt
ret CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
0 then
Maybe pt -> IO (Maybe pt)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe pt -> IO (Maybe pt)) -> Maybe pt -> IO (Maybe pt)
forall a b. (a -> b) -> a -> b
$ pt -> Maybe pt
forall a. a -> Maybe a
Just pt
msg
else
Maybe pt -> IO (Maybe pt)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe pt
forall a. Maybe a
Nothing
where
mlen :: Int
mlen :: Int
mlen = ct -> Int
forall ba. ByteArrayAccess ba => ba -> Int
length ct
ct Int -> Int -> Int
forall a. Num a => a -> a -> a
- CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
Na.crypto_box_macbytes