-- SPDX-FileCopyrightText: 2020 Serokell
--
-- SPDX-License-Identifier: MPL-2.0

module Crypto.Secretbox
  ( Key
  , toKey

  , Nonce
  , toNonce

  , create
  , open
  ) where

import Data.ByteArray (ByteArray, ByteArrayAccess)
import System.IO.Unsafe (unsafeDupablePerformIO)

import Crypto.Secretbox.Internal (Key, Nonce, toKey, toNonce)

import qualified Crypto.Secretbox.Internal as I


-- | Encrypt a message.
--
-- Note: This function is similar to the C++ API of NaCl.
-- That is, unlike @crypto_secretbox@ from the C API of NaCl,
-- it does not require any special padding.
create
  ::  ( ByteArrayAccess key, ByteArrayAccess nonce
      , ByteArrayAccess pt, ByteArray ct
      )
  => Key key  -- ^ Secret key
  -> Nonce nonce  -- ^ Nonce
  -> pt -- ^ Plaintext message
  -> ct
create :: Key key -> Nonce nonce -> pt -> ct
create key :: Key key
key nonce :: Nonce nonce
nonce msg :: pt
msg = IO ct -> ct
forall a. IO a -> a
unsafeDupablePerformIO (IO ct -> ct) -> IO ct -> ct
forall a b. (a -> b) -> a -> b
$ Key key -> Nonce nonce -> pt -> IO ct
forall key nonce pt ct.
(ByteArrayAccess key, ByteArrayAccess nonce, ByteArrayAccess pt,
 ByteArray ct) =>
Key key -> Nonce nonce -> pt -> IO ct
I.create Key key
key Nonce nonce
nonce pt
msg


-- | Decrypt a message.
--
-- Note: This function is similar to the C++ API of NaCl.
-- That is, unlike @crypto_secretbox_open@ from the C API of NaCl,
-- it does not require any special padding.
open
  ::  ( ByteArrayAccess key, ByteArrayAccess nonce
      , ByteArray pt, ByteArrayAccess ct
      )
  => Key key  -- ^ Secret key
  -> Nonce nonce  -- ^ Nonce
  -> ct -- ^ Cyphertext
  -> Maybe pt
open :: Key key -> Nonce nonce -> ct -> Maybe pt
open key :: Key key
key nonce :: Nonce nonce
nonce ct :: ct
ct = IO (Maybe pt) -> Maybe pt
forall a. IO a -> a
unsafeDupablePerformIO (IO (Maybe pt) -> Maybe pt) -> IO (Maybe pt) -> Maybe pt
forall a b. (a -> b) -> a -> b
$ Key key -> Nonce nonce -> ct -> IO (Maybe pt)
forall key nonce pt ct.
(ByteArrayAccess key, ByteArrayAccess nonce, ByteArray pt,
 ByteArrayAccess ct) =>
Key key -> Nonce nonce -> ct -> IO (Maybe pt)
I.open Key key
key Nonce nonce
nonce ct
ct