{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}

-- |
-- Module      : Crypto.Saltine.Core.Box
-- Copyright   : (c) Joseph Abrahamson 2013
-- License     : MIT
--
-- Maintainer  : me@jspha.com
-- Stability   : experimental
-- Portability : non-portable
--
-- Public-key cryptography abstraction:
-- "Crypto.Saltine.Core.Box"
--
-- This module consists of functions dealing with two public-key
-- cryptography concepts in libsodium.
--
-- The first one is an authenticated encryption scheme. In this
-- scheme, the 'box' function encrypts and authenticates a message
-- 'ByteString' using the sender's secret key, the receiver's public
-- key, and a nonce. The 'boxOpen' function verifies and decrypts a
-- ciphertext 'ByteString' using the receiver's secret key, the
-- sender's public key, and a nonce. If the ciphertext fails
-- verification, 'boxOpen' returns 'Nothing'.
--
-- The set of box functions is designed to meet the
-- standard notions of privacy and third-party unforgeability for a
-- public-key authenticated-encryption scheme using nonces. For formal
-- definitions see, e.g., Jee Hea An, "Authenticated encryption in the
-- public-key setting: security notions and analyses,"
-- <http://eprint.iacr.org/2001/079>.
--
-- Distinct messages between the same @{sender, receiver}@ set are
-- required to have distinct nonces. For example, the
-- lexicographically smaller public key can use nonce 1 for its first
-- message to the other key, nonce 3 for its second message, nonce 5
-- for its third message, etc., while the lexicographically larger
-- public key uses nonce 2 for its first message to the other key,
-- nonce 4 for its second message, nonce 6 for its third message,
-- etc. Nonces are long enough that randomly generated nonces have
-- negligible risk of collision.
--
-- There is no harm in having the same nonce for different messages if
-- the @{sender, receiver}@ sets are different. This is true even if
-- the sets overlap. For example, a sender can use the same nonce for
-- two different messages if the messages are sent to two different
-- public keys.
--
-- The second concept is sealed boxes, which provide encryption and
-- preservation of integrity, but not authentication. Technically,
-- the sender of a message generates a keypair, uses the regular
-- box mechanism, attaches the public key to the message and then
-- immediately destroys the private key. This is useful, e.g. when
-- the receiver cannot know the sender's public key in advance and
-- hence cannot use the regular box functions, or when you want to
-- send messages anonymously.
--
-- The "Crypto.Saltine.Core.Box" module is not meant to provide
-- non-repudiation. On the contrary: the crypto_box function
-- guarantees repudiability. A receiver can freely modify a boxed
-- message, and therefore cannot convince third parties that this
-- particular message came from the sender. The sender and receiver
-- are nevertheless protected against forgeries by other parties. In
-- the terminology of
-- <http://groups.google.com/group/sci.crypt/msg/ec5c18b23b11d82c>,
-- crypto_box uses "public-key authenticators" rather than "public-key
-- signatures."
--
-- Users who want public verifiability (or receiver-assisted public
-- verifiability) should instead use signatures (or
-- signcryption). Signatures are documented in the
-- "Crypto.Saltine.Core.Sign" module.
--
-- "Crypto.Saltine.Core.Box" is @curve25519xsalsa20poly1305@, a
-- particular combination of Curve25519, Salsa20, and Poly1305
-- specified in "Cryptography in NaCl"
-- (<http://nacl.cr.yp.to/valid.html>). This function is conjectured
-- to meet the standard notions of privacy and third-party
-- unforgeability.
--
-- This is version 2010.08.30 of the box.html web page.
module Crypto.Saltine.Core.Box (
  SecretKey, PublicKey, Keypair, CombinedKey, Nonce,
  newKeypair, beforeNM, newNonce,
  box, boxOpen,
  boxAfterNM, boxOpenAfterNM,
  boxSeal, boxSealOpen
  ) where

import           Crypto.Saltine.Class
import           Crypto.Saltine.Internal.Util
import qualified Crypto.Saltine.Internal.ByteSizes as Bytes

import           Control.Applicative
import           Foreign.C
import           Foreign.Ptr
import qualified Data.ByteString                   as S
import           Data.ByteString (ByteString)
import           Data.Hashable (Hashable)
import           Data.Data (Data, Typeable)
import           GHC.Generics (Generic)


-- $types

-- | An opaque 'box' cryptographic secret key.
newtype SecretKey = SK ByteString deriving (SecretKey -> SecretKey -> Bool
(SecretKey -> SecretKey -> Bool)
-> (SecretKey -> SecretKey -> Bool) -> Eq SecretKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecretKey -> SecretKey -> Bool
$c/= :: SecretKey -> SecretKey -> Bool
== :: SecretKey -> SecretKey -> Bool
$c== :: SecretKey -> SecretKey -> Bool
Eq, Eq SecretKey
Eq SecretKey =>
(SecretKey -> SecretKey -> Ordering)
-> (SecretKey -> SecretKey -> Bool)
-> (SecretKey -> SecretKey -> Bool)
-> (SecretKey -> SecretKey -> Bool)
-> (SecretKey -> SecretKey -> Bool)
-> (SecretKey -> SecretKey -> SecretKey)
-> (SecretKey -> SecretKey -> SecretKey)
-> Ord SecretKey
SecretKey -> SecretKey -> Bool
SecretKey -> SecretKey -> Ordering
SecretKey -> SecretKey -> SecretKey
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SecretKey -> SecretKey -> SecretKey
$cmin :: SecretKey -> SecretKey -> SecretKey
max :: SecretKey -> SecretKey -> SecretKey
$cmax :: SecretKey -> SecretKey -> SecretKey
>= :: SecretKey -> SecretKey -> Bool
$c>= :: SecretKey -> SecretKey -> Bool
> :: SecretKey -> SecretKey -> Bool
$c> :: SecretKey -> SecretKey -> Bool
<= :: SecretKey -> SecretKey -> Bool
$c<= :: SecretKey -> SecretKey -> Bool
< :: SecretKey -> SecretKey -> Bool
$c< :: SecretKey -> SecretKey -> Bool
compare :: SecretKey -> SecretKey -> Ordering
$ccompare :: SecretKey -> SecretKey -> Ordering
$cp1Ord :: Eq SecretKey
Ord, Int -> SecretKey -> Int
SecretKey -> Int
(Int -> SecretKey -> Int)
-> (SecretKey -> Int) -> Hashable SecretKey
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: SecretKey -> Int
$chash :: SecretKey -> Int
hashWithSalt :: Int -> SecretKey -> Int
$chashWithSalt :: Int -> SecretKey -> Int
Hashable, Typeable SecretKey
DataType
Constr
Typeable SecretKey =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> SecretKey -> c SecretKey)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c SecretKey)
-> (SecretKey -> Constr)
-> (SecretKey -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c SecretKey))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SecretKey))
-> ((forall b. Data b => b -> b) -> SecretKey -> SecretKey)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> SecretKey -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> SecretKey -> r)
-> (forall u. (forall d. Data d => d -> u) -> SecretKey -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> SecretKey -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> SecretKey -> m SecretKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SecretKey -> m SecretKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> SecretKey -> m SecretKey)
-> Data SecretKey
SecretKey -> DataType
SecretKey -> Constr
(forall b. Data b => b -> b) -> SecretKey -> SecretKey
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SecretKey -> c SecretKey
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SecretKey
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> SecretKey -> u
forall u. (forall d. Data d => d -> u) -> SecretKey -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SecretKey -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SecretKey -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SecretKey
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SecretKey -> c SecretKey
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SecretKey)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SecretKey)
$cSK :: Constr
$tSecretKey :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
gmapMp :: (forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
gmapM :: (forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> SecretKey -> m SecretKey
gmapQi :: Int -> (forall d. Data d => d -> u) -> SecretKey -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> SecretKey -> u
gmapQ :: (forall d. Data d => d -> u) -> SecretKey -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> SecretKey -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SecretKey -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> SecretKey -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SecretKey -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> SecretKey -> r
gmapT :: (forall b. Data b => b -> b) -> SecretKey -> SecretKey
$cgmapT :: (forall b. Data b => b -> b) -> SecretKey -> SecretKey
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SecretKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c SecretKey)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c SecretKey)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c SecretKey)
dataTypeOf :: SecretKey -> DataType
$cdataTypeOf :: SecretKey -> DataType
toConstr :: SecretKey -> Constr
$ctoConstr :: SecretKey -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SecretKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c SecretKey
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SecretKey -> c SecretKey
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> SecretKey -> c SecretKey
$cp1Data :: Typeable SecretKey
Data, Typeable, (forall x. SecretKey -> Rep SecretKey x)
-> (forall x. Rep SecretKey x -> SecretKey) -> Generic SecretKey
forall x. Rep SecretKey x -> SecretKey
forall x. SecretKey -> Rep SecretKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecretKey x -> SecretKey
$cfrom :: forall x. SecretKey -> Rep SecretKey x
Generic)

instance IsEncoding SecretKey where
  decode :: ByteString -> Maybe SecretKey
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
Bytes.boxSK
           then SecretKey -> Maybe SecretKey
forall a. a -> Maybe a
Just (ByteString -> SecretKey
SK ByteString
v)
           else Maybe SecretKey
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: SecretKey -> ByteString
encode (SK v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

-- | An opaque 'box' cryptographic public key.
newtype PublicKey = PK ByteString deriving (PublicKey -> PublicKey -> Bool
(PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool) -> Eq PublicKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicKey -> PublicKey -> Bool
$c/= :: PublicKey -> PublicKey -> Bool
== :: PublicKey -> PublicKey -> Bool
$c== :: PublicKey -> PublicKey -> Bool
Eq, Eq PublicKey
Eq PublicKey =>
(PublicKey -> PublicKey -> Ordering)
-> (PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> PublicKey)
-> (PublicKey -> PublicKey -> PublicKey)
-> Ord PublicKey
PublicKey -> PublicKey -> Bool
PublicKey -> PublicKey -> Ordering
PublicKey -> PublicKey -> PublicKey
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PublicKey -> PublicKey -> PublicKey
$cmin :: PublicKey -> PublicKey -> PublicKey
max :: PublicKey -> PublicKey -> PublicKey
$cmax :: PublicKey -> PublicKey -> PublicKey
>= :: PublicKey -> PublicKey -> Bool
$c>= :: PublicKey -> PublicKey -> Bool
> :: PublicKey -> PublicKey -> Bool
$c> :: PublicKey -> PublicKey -> Bool
<= :: PublicKey -> PublicKey -> Bool
$c<= :: PublicKey -> PublicKey -> Bool
< :: PublicKey -> PublicKey -> Bool
$c< :: PublicKey -> PublicKey -> Bool
compare :: PublicKey -> PublicKey -> Ordering
$ccompare :: PublicKey -> PublicKey -> Ordering
$cp1Ord :: Eq PublicKey
Ord, Int -> PublicKey -> Int
PublicKey -> Int
(Int -> PublicKey -> Int)
-> (PublicKey -> Int) -> Hashable PublicKey
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: PublicKey -> Int
$chash :: PublicKey -> Int
hashWithSalt :: Int -> PublicKey -> Int
$chashWithSalt :: Int -> PublicKey -> Int
Hashable, Typeable PublicKey
DataType
Constr
Typeable PublicKey =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> PublicKey -> c PublicKey)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PublicKey)
-> (PublicKey -> Constr)
-> (PublicKey -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PublicKey))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey))
-> ((forall b. Data b => b -> b) -> PublicKey -> PublicKey)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PublicKey -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PublicKey -> r)
-> (forall u. (forall d. Data d => d -> u) -> PublicKey -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> PublicKey -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey)
-> Data PublicKey
PublicKey -> DataType
PublicKey -> Constr
(forall b. Data b => b -> b) -> PublicKey -> PublicKey
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> PublicKey -> u
forall u. (forall d. Data d => d -> u) -> PublicKey -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PublicKey)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey)
$cPK :: Constr
$tPublicKey :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
gmapMp :: (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
gmapM :: (forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> PublicKey -> m PublicKey
gmapQi :: Int -> (forall d. Data d => d -> u) -> PublicKey -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PublicKey -> u
gmapQ :: (forall d. Data d => d -> u) -> PublicKey -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> PublicKey -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PublicKey -> r
gmapT :: (forall b. Data b => b -> b) -> PublicKey -> PublicKey
$cgmapT :: (forall b. Data b => b -> b) -> PublicKey -> PublicKey
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PublicKey)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c PublicKey)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PublicKey)
dataTypeOf :: PublicKey -> DataType
$cdataTypeOf :: PublicKey -> DataType
toConstr :: PublicKey -> Constr
$ctoConstr :: PublicKey -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PublicKey
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PublicKey -> c PublicKey
$cp1Data :: Typeable PublicKey
Data, Typeable, (forall x. PublicKey -> Rep PublicKey x)
-> (forall x. Rep PublicKey x -> PublicKey) -> Generic PublicKey
forall x. Rep PublicKey x -> PublicKey
forall x. PublicKey -> Rep PublicKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PublicKey x -> PublicKey
$cfrom :: forall x. PublicKey -> Rep PublicKey x
Generic)

instance IsEncoding PublicKey where
  decode :: ByteString -> Maybe PublicKey
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
Bytes.boxPK
           then PublicKey -> Maybe PublicKey
forall a. a -> Maybe a
Just (ByteString -> PublicKey
PK ByteString
v)
           else Maybe PublicKey
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: PublicKey -> ByteString
encode (PK v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

-- | A convenience type for keypairs
type Keypair = (SecretKey, PublicKey)

-- | An opaque 'boxAfterNM' cryptographic combined key.
newtype CombinedKey = CK ByteString deriving (CombinedKey -> CombinedKey -> Bool
(CombinedKey -> CombinedKey -> Bool)
-> (CombinedKey -> CombinedKey -> Bool) -> Eq CombinedKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CombinedKey -> CombinedKey -> Bool
$c/= :: CombinedKey -> CombinedKey -> Bool
== :: CombinedKey -> CombinedKey -> Bool
$c== :: CombinedKey -> CombinedKey -> Bool
Eq, Eq CombinedKey
Eq CombinedKey =>
(CombinedKey -> CombinedKey -> Ordering)
-> (CombinedKey -> CombinedKey -> Bool)
-> (CombinedKey -> CombinedKey -> Bool)
-> (CombinedKey -> CombinedKey -> Bool)
-> (CombinedKey -> CombinedKey -> Bool)
-> (CombinedKey -> CombinedKey -> CombinedKey)
-> (CombinedKey -> CombinedKey -> CombinedKey)
-> Ord CombinedKey
CombinedKey -> CombinedKey -> Bool
CombinedKey -> CombinedKey -> Ordering
CombinedKey -> CombinedKey -> CombinedKey
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CombinedKey -> CombinedKey -> CombinedKey
$cmin :: CombinedKey -> CombinedKey -> CombinedKey
max :: CombinedKey -> CombinedKey -> CombinedKey
$cmax :: CombinedKey -> CombinedKey -> CombinedKey
>= :: CombinedKey -> CombinedKey -> Bool
$c>= :: CombinedKey -> CombinedKey -> Bool
> :: CombinedKey -> CombinedKey -> Bool
$c> :: CombinedKey -> CombinedKey -> Bool
<= :: CombinedKey -> CombinedKey -> Bool
$c<= :: CombinedKey -> CombinedKey -> Bool
< :: CombinedKey -> CombinedKey -> Bool
$c< :: CombinedKey -> CombinedKey -> Bool
compare :: CombinedKey -> CombinedKey -> Ordering
$ccompare :: CombinedKey -> CombinedKey -> Ordering
$cp1Ord :: Eq CombinedKey
Ord, Int -> CombinedKey -> Int
CombinedKey -> Int
(Int -> CombinedKey -> Int)
-> (CombinedKey -> Int) -> Hashable CombinedKey
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: CombinedKey -> Int
$chash :: CombinedKey -> Int
hashWithSalt :: Int -> CombinedKey -> Int
$chashWithSalt :: Int -> CombinedKey -> Int
Hashable, Typeable CombinedKey
DataType
Constr
Typeable CombinedKey =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> CombinedKey -> c CombinedKey)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c CombinedKey)
-> (CombinedKey -> Constr)
-> (CombinedKey -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c CombinedKey))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c CombinedKey))
-> ((forall b. Data b => b -> b) -> CombinedKey -> CombinedKey)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> CombinedKey -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> CombinedKey -> r)
-> (forall u. (forall d. Data d => d -> u) -> CombinedKey -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> CombinedKey -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey)
-> Data CombinedKey
CombinedKey -> DataType
CombinedKey -> Constr
(forall b. Data b => b -> b) -> CombinedKey -> CombinedKey
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CombinedKey -> c CombinedKey
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CombinedKey
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> CombinedKey -> u
forall u. (forall d. Data d => d -> u) -> CombinedKey -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CombinedKey -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CombinedKey -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CombinedKey
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CombinedKey -> c CombinedKey
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CombinedKey)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CombinedKey)
$cCK :: Constr
$tCombinedKey :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
gmapMp :: (forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
gmapM :: (forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> CombinedKey -> m CombinedKey
gmapQi :: Int -> (forall d. Data d => d -> u) -> CombinedKey -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> CombinedKey -> u
gmapQ :: (forall d. Data d => d -> u) -> CombinedKey -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> CombinedKey -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CombinedKey -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> CombinedKey -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CombinedKey -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> CombinedKey -> r
gmapT :: (forall b. Data b => b -> b) -> CombinedKey -> CombinedKey
$cgmapT :: (forall b. Data b => b -> b) -> CombinedKey -> CombinedKey
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CombinedKey)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c CombinedKey)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c CombinedKey)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c CombinedKey)
dataTypeOf :: CombinedKey -> DataType
$cdataTypeOf :: CombinedKey -> DataType
toConstr :: CombinedKey -> Constr
$ctoConstr :: CombinedKey -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CombinedKey
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c CombinedKey
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CombinedKey -> c CombinedKey
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> CombinedKey -> c CombinedKey
$cp1Data :: Typeable CombinedKey
Data, Typeable, (forall x. CombinedKey -> Rep CombinedKey x)
-> (forall x. Rep CombinedKey x -> CombinedKey)
-> Generic CombinedKey
forall x. Rep CombinedKey x -> CombinedKey
forall x. CombinedKey -> Rep CombinedKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep CombinedKey x -> CombinedKey
$cfrom :: forall x. CombinedKey -> Rep CombinedKey x
Generic)

instance IsEncoding CombinedKey where
  decode :: ByteString -> Maybe CombinedKey
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
Bytes.boxBeforeNM
           then CombinedKey -> Maybe CombinedKey
forall a. a -> Maybe a
Just (ByteString -> CombinedKey
CK ByteString
v)
           else Maybe CombinedKey
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: CombinedKey -> ByteString
encode (CK v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

-- | An opaque 'box' nonce.
newtype Nonce = Nonce ByteString deriving (Nonce -> Nonce -> Bool
(Nonce -> Nonce -> Bool) -> (Nonce -> Nonce -> Bool) -> Eq Nonce
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Nonce -> Nonce -> Bool
$c/= :: Nonce -> Nonce -> Bool
== :: Nonce -> Nonce -> Bool
$c== :: Nonce -> Nonce -> Bool
Eq, Eq Nonce
Eq Nonce =>
(Nonce -> Nonce -> Ordering)
-> (Nonce -> Nonce -> Bool)
-> (Nonce -> Nonce -> Bool)
-> (Nonce -> Nonce -> Bool)
-> (Nonce -> Nonce -> Bool)
-> (Nonce -> Nonce -> Nonce)
-> (Nonce -> Nonce -> Nonce)
-> Ord Nonce
Nonce -> Nonce -> Bool
Nonce -> Nonce -> Ordering
Nonce -> Nonce -> Nonce
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Nonce -> Nonce -> Nonce
$cmin :: Nonce -> Nonce -> Nonce
max :: Nonce -> Nonce -> Nonce
$cmax :: Nonce -> Nonce -> Nonce
>= :: Nonce -> Nonce -> Bool
$c>= :: Nonce -> Nonce -> Bool
> :: Nonce -> Nonce -> Bool
$c> :: Nonce -> Nonce -> Bool
<= :: Nonce -> Nonce -> Bool
$c<= :: Nonce -> Nonce -> Bool
< :: Nonce -> Nonce -> Bool
$c< :: Nonce -> Nonce -> Bool
compare :: Nonce -> Nonce -> Ordering
$ccompare :: Nonce -> Nonce -> Ordering
$cp1Ord :: Eq Nonce
Ord, Int -> Nonce -> Int
Nonce -> Int
(Int -> Nonce -> Int) -> (Nonce -> Int) -> Hashable Nonce
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Nonce -> Int
$chash :: Nonce -> Int
hashWithSalt :: Int -> Nonce -> Int
$chashWithSalt :: Int -> Nonce -> Int
Hashable, Typeable Nonce
DataType
Constr
Typeable Nonce =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Nonce -> c Nonce)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Nonce)
-> (Nonce -> Constr)
-> (Nonce -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Nonce))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Nonce))
-> ((forall b. Data b => b -> b) -> Nonce -> Nonce)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r)
-> (forall u. (forall d. Data d => d -> u) -> Nonce -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Nonce -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Nonce -> m Nonce)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Nonce -> m Nonce)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Nonce -> m Nonce)
-> Data Nonce
Nonce -> DataType
Nonce -> Constr
(forall b. Data b => b -> b) -> Nonce -> Nonce
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Nonce -> c Nonce
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Nonce
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Nonce -> u
forall u. (forall d. Data d => d -> u) -> Nonce -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Nonce -> m Nonce
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Nonce -> m Nonce
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Nonce
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Nonce -> c Nonce
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Nonce)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Nonce)
$cNonce :: Constr
$tNonce :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Nonce -> m Nonce
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Nonce -> m Nonce
gmapMp :: (forall d. Data d => d -> m d) -> Nonce -> m Nonce
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Nonce -> m Nonce
gmapM :: (forall d. Data d => d -> m d) -> Nonce -> m Nonce
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Nonce -> m Nonce
gmapQi :: Int -> (forall d. Data d => d -> u) -> Nonce -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Nonce -> u
gmapQ :: (forall d. Data d => d -> u) -> Nonce -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Nonce -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Nonce -> r
gmapT :: (forall b. Data b => b -> b) -> Nonce -> Nonce
$cgmapT :: (forall b. Data b => b -> b) -> Nonce -> Nonce
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Nonce)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Nonce)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Nonce)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Nonce)
dataTypeOf :: Nonce -> DataType
$cdataTypeOf :: Nonce -> DataType
toConstr :: Nonce -> Constr
$ctoConstr :: Nonce -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Nonce
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Nonce
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Nonce -> c Nonce
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Nonce -> c Nonce
$cp1Data :: Typeable Nonce
Data, Typeable, (forall x. Nonce -> Rep Nonce x)
-> (forall x. Rep Nonce x -> Nonce) -> Generic Nonce
forall x. Rep Nonce x -> Nonce
forall x. Nonce -> Rep Nonce x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Nonce x -> Nonce
$cfrom :: forall x. Nonce -> Rep Nonce x
Generic)

instance IsEncoding Nonce where
  decode :: ByteString -> Maybe Nonce
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
Bytes.boxNonce
           then Nonce -> Maybe Nonce
forall a. a -> Maybe a
Just (ByteString -> Nonce
Nonce ByteString
v)
           else Maybe Nonce
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: Nonce -> ByteString
encode (Nonce v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

instance IsNonce Nonce where
  zero :: Nonce
zero            = ByteString -> Nonce
Nonce (Int -> Word8 -> ByteString
S.replicate Int
Bytes.boxNonce 0)
  nudge :: Nonce -> Nonce
nudge (Nonce n :: ByteString
n) = ByteString -> Nonce
Nonce (ByteString -> ByteString
nudgeBS ByteString
n)

-- | Randomly generates a secret key and a corresponding public key.
newKeypair :: IO Keypair
newKeypair :: IO Keypair
newKeypair = do
  -- This is a little bizarre and a likely source of errors.
  -- _err ought to always be 0.
  ((_err :: CInt
_err, sk :: ByteString
sk), pk :: 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.boxPK ((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
$ \pkbuf :: Ptr CChar
pkbuf ->
    Int -> (Ptr CChar -> IO CInt) -> IO (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> IO (b, ByteString)
buildUnsafeByteString' Int
Bytes.boxSK ((Ptr CChar -> IO CInt) -> IO (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> IO (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \skbuf :: 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 (ByteString -> SecretKey
SK ByteString
sk, ByteString -> PublicKey
PK ByteString
pk)

-- | Randomly generates a nonce for usage with 'box' and 'boxOpen'.
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.boxNonce

-- | Build a 'CombinedKey' for sending from 'SecretKey' to
-- 'PublicKey'. This is a precomputation step which can accelerate
-- later encryption calls.
beforeNM :: SecretKey -> PublicKey -> CombinedKey
beforeNM :: SecretKey -> PublicKey -> CombinedKey
beforeNM (SK sk :: ByteString
sk) (PK 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.boxBeforeNM ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall a b. (a -> b) -> a -> b
$ \ckbuf :: 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
$ \[(ppk :: Ptr CChar
ppk, _), (psk :: Ptr CChar
psk, _)] ->
    Ptr CChar -> Ptr CChar -> Ptr CChar -> IO CInt
c_box_beforenm Ptr CChar
ckbuf Ptr CChar
ppk Ptr CChar
psk

-- | Encrypts a message for sending to the owner of the public
-- key. They must have your public key in order to decrypt the
-- message. It is infeasible for an attacker to decrypt the message so
-- long as the 'Nonce' is not repeated.
box :: PublicKey
    -> SecretKey
    -> Nonce
    -> ByteString
    -- ^ Message
    -> ByteString
    -- ^ Ciphertext (incl. authentication tag)
box :: PublicKey -> SecretKey -> Nonce -> ByteString -> ByteString
box (PK pk :: ByteString
pk) (SK sk :: ByteString
sk) (Nonce nonce :: ByteString
nonce) msg :: 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
$ \pc :: 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
$ \
      [(ppk :: Ptr CChar
ppk, _), (psk :: Ptr CChar
psk, _), (pm :: Ptr CChar
pm, _), (pn :: Ptr CChar
pn, _)] ->
        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.boxMac
    msgLen :: Int
msgLen  = ByteString -> Int
S.length ByteString
msg

-- | Decrypts a message sent from the owner of the public key. They
-- must have encrypted it using your public key. Returns 'Nothing' if
-- the keys and message do not match.
boxOpen :: PublicKey -> SecretKey -> Nonce
        -> ByteString
        -- ^ Ciphertext (incl. authentication tag)
        -> Maybe ByteString
        -- ^ Message
boxOpen :: PublicKey -> SecretKey -> Nonce -> ByteString -> Maybe ByteString
boxOpen (PK pk :: ByteString
pk) (SK sk :: ByteString
sk) (Nonce nonce :: ByteString
nonce) cipher :: 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.boxMac
  let (err :: CInt
err, vec :: 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
$ \pm :: 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
$ \
          [(ppk :: Ptr CChar
ppk, _), (psk :: Ptr CChar
psk, _), (pc :: Ptr CChar
pc, _), (pn :: Ptr CChar
pn, _)] ->
            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

    

-- | 'box' using a 'CombinedKey' and thus faster.
boxAfterNM :: CombinedKey
           -> Nonce
           -> ByteString
           -- ^ Message
           -> ByteString
           -- ^ Ciphertext (incl. authentication tag)
boxAfterNM :: CombinedKey -> Nonce -> ByteString -> ByteString
boxAfterNM (CK ck :: ByteString
ck) (Nonce nonce :: ByteString
nonce) msg :: 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
$ \pc :: 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
$ \
      [(pck :: Ptr CChar
pck, _), (pm :: Ptr CChar
pm, _), (pn :: Ptr CChar
pn, _)] ->
        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.boxMac
    msgLen :: Int
msgLen  = ByteString -> Int
S.length ByteString
msg

-- | 'boxOpen' using a 'CombinedKey' and is thus faster.
boxOpenAfterNM :: CombinedKey
               -> Nonce
               -> ByteString
               -- ^ Ciphertext (incl. authentication tag)
               -> Maybe ByteString
               -- ^ Message
boxOpenAfterNM :: CombinedKey -> Nonce -> ByteString -> Maybe ByteString
boxOpenAfterNM (CK ck :: ByteString
ck) (Nonce nonce :: ByteString
nonce) cipher :: 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.boxMac
  let (err :: CInt
err, vec :: 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
$ \pm :: 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
$ \
          [(pck :: Ptr CChar
pck, _), (pc :: Ptr CChar
pc, _), (pn :: Ptr CChar
pn, _)] ->
            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

    


-- | Encrypts a message for sending to the owner of the public
-- key. The message is unauthenticated, but permits integrity checking.
boxSeal :: PublicKey -> ByteString -> IO ByteString
boxSeal :: PublicKey -> ByteString -> IO ByteString
boxSeal (PK pk :: ByteString
pk) msg :: 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
$ \pc :: 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
$ \
      [(ppk :: Ptr CChar
ppk, _), (pm :: Ptr CChar
pm, _)] ->
        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.sealedBox
    msgLen :: Int
msgLen  = ByteString -> Int
S.length ByteString
msg

-- | Decrypts a sealed box message. The message must have been
-- encrypted using the receiver's public key.
-- Returns 'Nothing' if keys and message do not match or integrity
-- is violated.
boxSealOpen :: PublicKey
            -> SecretKey
            -> ByteString
            -- ^ Ciphertext
            -> Maybe ByteString
            -- ^ Message
boxSealOpen :: PublicKey -> SecretKey -> ByteString -> Maybe ByteString
boxSealOpen (PK pk :: ByteString
pk) (SK sk :: ByteString
sk) cipher :: 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.sealedBox
  let (err :: CInt
err, vec :: 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
$ \pm :: 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
$ \
          [(ppk :: Ptr CChar
ppk, _), (psk :: Ptr CChar
psk, _), (pc :: Ptr CChar
pc, _)] ->
          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

-- | Should always return a 0.
foreign import ccall "crypto_box_keypair"
  c_box_keypair :: Ptr CChar
                -- ^ Public key
                -> Ptr CChar
                -- ^ Secret key
                -> IO CInt
                -- ^ Always 0

-- | The secretbox C API uses C strings.
foreign import ccall "crypto_box_easy"
  c_box_easy :: Ptr CChar
             -- ^ Cipher output buffer
             -> Ptr CChar
             -- ^ Constant message input buffer
             -> CULLong
             -- ^ Length of message input buffer
             -> Ptr CChar
             -- ^ Constant nonce buffer
             -> Ptr CChar
             -- ^ Constant public key buffer
             -> Ptr CChar
             -- ^ Constant secret key buffer
             -> IO CInt
             -- ^ Always 0

-- | The secretbox C API uses C strings.
foreign import ccall "crypto_box_open_easy"
  c_box_open_easy :: Ptr CChar
                  -- ^ Message output buffer
                  -> Ptr CChar
                  -- ^ Constant ciphertext input buffer
                  -> CULLong
                  -- ^ Length of message input buffer
                  -> Ptr CChar
                  -- ^ Constant nonce buffer
                  -> Ptr CChar
                  -- ^ Constant public key buffer
                  -> Ptr CChar
                  -- ^ Constant secret key buffer
                  -> IO CInt
                  -- ^ 0 for success, -1 for failure to verify

-- | Single target key precompilation.
foreign import ccall "crypto_box_beforenm"
  c_box_beforenm :: Ptr CChar
                 -- ^ Combined key output buffer
                 -> Ptr CChar
                 -- ^ Constant public key buffer
                 -> Ptr CChar
                 -- ^ Constant secret key buffer
                 -> IO CInt
                 -- ^ Always 0

-- | Precompiled key crypto box. Uses C strings.
foreign import ccall "crypto_box_easy_afternm"
  c_box_easy_afternm :: Ptr CChar
                     -- ^ Cipher output buffer
                     -> Ptr CChar
                     -- ^ Constant message input buffer
                     -> CULLong
                     -- ^ Length of message input buffer (incl. 0s)
                     -> Ptr CChar
                     -- ^ Constant nonce buffer
                     -> Ptr CChar
                     -- ^ Constant combined key buffer
                     -> IO CInt
                     -- ^ Always 0

-- | The secretbox C API uses C strings.
foreign import ccall "crypto_box_open_easy_afternm"
  c_box_open_easy_afternm :: Ptr CChar
                          -- ^ Message output buffer
                          -> Ptr CChar
                          -- ^ Constant ciphertext input buffer
                          -> CULLong
                          -- ^ Length of message input buffer (incl. 0s)
                          -> Ptr CChar
                          -- ^ Constant nonce buffer
                          -> Ptr CChar
                          -- ^ Constant combined key buffer
                          -> IO CInt
                          -- ^ 0 for success, -1 for failure to verify


-- | The sealedbox C API uses C strings.
foreign import ccall "crypto_box_seal"
  c_box_seal :: Ptr CChar
             -- ^ Cipher output buffer
             -> Ptr CChar
             -- ^ Constant message input buffer
             -> CULLong
             -- ^ Length of message input buffer
             -> Ptr CChar
             -- ^ Constant public key buffer
             -> IO CInt
             -- ^ Always 0

-- | The sealedbox C API uses C strings.
foreign import ccall "crypto_box_seal_open"
  c_box_seal_open :: Ptr CChar
                  -- ^ Message output buffer
                  -> Ptr CChar
                  -- ^ Constant ciphertext input buffer
                  -> CULLong
                  -- ^ Length of message input buffer
                  -> Ptr CChar
                  -- ^ Constant public key buffer
                  -> Ptr CChar
                  -- ^ Constant secret key buffer
                  -> IO CInt
                  -- ^ 0 for success, -1 for failure to decrypt