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

 -- |
-- Module      : Crypto.Saltine.Core.Hash
-- Copyright   : (c) Joseph Abrahamson 2013
-- License     : MIT
--
-- Maintainer  : me@jspha.com
-- Stability   : experimental
-- Portability : non-portable
--
-- Hashing: "Crypto.Saltine.Core.Hash"
--
-- The 'hash' function hashes a message 'ByteString' and returns a
-- hash. Hashes are always of length 'Bytes.hash'. The 'shorthash'
-- function hashes a message 'ByteString' with respect to a secret key
-- and returns a very short hash. Short hashes are always of length
-- 'Bytes.shorthash'.
--
-- The 'hash' function is designed to be usable as a strong component
-- of DSA, RSA-PSS, key derivation, hash-based message-authentication
-- codes, hash-based ciphers, and various other common
-- applications. "Strong" means that the security of these
-- applications, when instantiated with 'hash', is the same as the
-- security of the applications against generic attacks. In
-- particular, the 'hash' function is designed to make finding
-- collisions difficult.
--
-- 'hash' is currently an implementation of SHA-512. 'shorthash' is
-- currently an implementation of SipHash-2-4
-- (<https://131002.net/siphash/>).
--
-- There has been considerable degradation of public confidence in the
-- security conjectures for many hash functions, including
-- SHA-512. However, for the moment, there do not appear to be
-- alternatives that inspire satisfactory levels of confidence. One
-- can hope that NIST's SHA-3 competition will improve the situation.
--
-- Sodium includes an implementation of the Blake2b hash function
-- (<https://blake2.net/>) and is bound here as the 'generichash'
-- function.
--
-- This is version 2010.08.30 of the hash.html web page. Information
-- about SipHash has been added.
module Crypto.Saltine.Core.Hash (
  ShorthashKey,
  hash,
  shorthash, newShorthashKey,
  GenerichashKey,
  newGenerichashKey,
  GenerichashOutLen,
  generichashOutLen, generichash
  ) 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)

-- | Computes a cryptographically collision-resistant hash making
-- @hash m == hash m' ==> m == m'@ highly likely even when under
-- attack.
hash :: ByteString
     -- ^ Message
     -> ByteString
     -- ^ Hash
hash :: ByteString -> ByteString
hash m :: ByteString
m = (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
Bytes.hash ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ph :: Ptr CChar
ph ->
  [ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
m] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \[(pm :: Ptr CChar
pm, _)] -> Ptr CChar -> Ptr CChar -> CULLong -> IO CInt
c_hash Ptr CChar
ph Ptr CChar
pm (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CULLong) -> Int -> CULLong
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
S.length ByteString
m)

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

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

-- | Randomly generates a new key for 'shorthash'.
newShorthashKey :: IO ShorthashKey
newShorthashKey :: IO ShorthashKey
newShorthashKey = ByteString -> ShorthashKey
ShK (ByteString -> ShorthashKey) -> IO ByteString -> IO ShorthashKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IO ByteString
randomByteString Int
Bytes.shorthashKey

-- | Computes a very short, fast keyed hash.
shorthash :: ShorthashKey
          -> ByteString
          -- ^ Message
          -> ByteString
          -- ^ Hash
shorthash :: ShorthashKey -> ByteString -> ByteString
shorthash (ShK k :: ByteString
k) m :: ByteString
m = (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
Bytes.shorthash ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ph :: Ptr CChar
ph ->
  [ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
k, ByteString
m] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \[(pk :: Ptr CChar
pk, _), (pm :: Ptr CChar
pm, _)] ->
    Ptr CChar -> Ptr CChar -> CULLong -> Ptr CChar -> IO CInt
c_shorthash Ptr CChar
ph Ptr CChar
pm (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CULLong) -> Int -> CULLong
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
S.length ByteString
m) Ptr CChar
pk

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

instance IsEncoding GenerichashKey where
  decode :: ByteString -> Maybe GenerichashKey
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
Bytes.generichashKeyLenMax
             then GenerichashKey -> Maybe GenerichashKey
forall a. a -> Maybe a
Just (ByteString -> GenerichashKey
GhK ByteString
v)
             else Maybe GenerichashKey
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: GenerichashKey -> ByteString
encode (GhK v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

-- | Randomly generates a new key for 'generichash' of the given length.
newGenerichashKey :: Int -> IO (Maybe GenerichashKey)
newGenerichashKey :: Int -> IO (Maybe GenerichashKey)
newGenerichashKey n :: Int
n = if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= 0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
Bytes.generichashKeyLenMax
                      then GenerichashKey -> Maybe GenerichashKey
forall a. a -> Maybe a
Just (GenerichashKey -> Maybe GenerichashKey)
-> (ByteString -> GenerichashKey)
-> ByteString
-> Maybe GenerichashKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> GenerichashKey
GhK (ByteString -> Maybe GenerichashKey)
-> IO ByteString -> IO (Maybe GenerichashKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> IO ByteString
randomByteString Int
n
                      else Maybe GenerichashKey -> IO (Maybe GenerichashKey)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe GenerichashKey
forall a. Maybe a
Nothing

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

-- | Create a validated Generichash output length
generichashOutLen :: Int -> Maybe GenerichashOutLen
generichashOutLen :: Int -> Maybe GenerichashOutLen
generichashOutLen n :: Int
n = if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
Bytes.generichashOutLenMax
                      then GenerichashOutLen -> Maybe GenerichashOutLen
forall a. a -> Maybe a
Just (GenerichashOutLen -> Maybe GenerichashOutLen)
-> GenerichashOutLen -> Maybe GenerichashOutLen
forall a b. (a -> b) -> a -> b
$ Int -> GenerichashOutLen
GhOL (Int -> GenerichashOutLen) -> Int -> GenerichashOutLen
forall a b. (a -> b) -> a -> b
$ Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
                      else Maybe GenerichashOutLen
forall a. Maybe a
Nothing

-- | Computes a generic, keyed hash.
generichash :: GenerichashKey
            -> ByteString
            -- ^ Message
            -> GenerichashOutLen
            -- ^ Desired output hash length
            -> ByteString
            -- ^ Hash
generichash :: GenerichashKey -> ByteString -> GenerichashOutLen -> ByteString
generichash (GhK k :: ByteString
k) m :: ByteString
m (GhOL outLen :: Int
outLen) = (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
outLen ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt) -> ByteString
forall a b. (a -> b) -> a -> b
$ \ph :: Ptr CChar
ph ->
  [ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
k, ByteString
m] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \[(pk :: Ptr CChar
pk, _), (pm :: Ptr CChar
pm, _)] ->
    Ptr CChar
-> CULLong
-> Ptr CChar
-> CULLong
-> Ptr CChar
-> CULLong
-> IO CInt
c_generichash Ptr CChar
ph (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
outLen) Ptr CChar
pm (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CULLong) -> Int -> CULLong
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
S.length ByteString
m) Ptr CChar
pk (Int -> CULLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CULLong) -> Int -> CULLong
forall a b. (a -> b) -> a -> b
$ ByteString -> Int
S.length ByteString
k)

foreign import ccall "crypto_hash"
  c_hash :: Ptr CChar
         -- ^ Output hash buffer
         -> Ptr CChar
         -- ^ Constant message buffer
         -> CULLong
         -- ^ Constant message buffer length
         -> IO CInt
         -- ^ Always 0

foreign import ccall "crypto_shorthash"
  c_shorthash :: Ptr CChar
              -- ^ Output hash buffer
              -> Ptr CChar
              -- ^ Constant message buffer
              -> CULLong
              -- ^ Message buffer length
              -> Ptr CChar
              -- ^ Constant Key buffer
              -> IO CInt
              -- ^ Always 0

foreign import ccall "crypto_generichash"
  c_generichash :: Ptr CChar
                -- ^ Output hash buffer
                -> CULLong
                -- ^ Output hash length
                -> Ptr CChar
                -- ^ Constant message buffer
                -> CULLong
                -- ^ Message buffer length
                -> Ptr CChar
                -- ^ Constant Key buffer
                -> CULLong
                -- ^ Key buffer length
                -> IO CInt
                -- ^ Always 0