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

-- |
-- Module      : Crypto.Saltine.Internal.Password
-- Copyright   : (c) Promethea Raschke 2018
--                   Max Amanshauser 2021
-- License     : MIT
-- Maintainer  : max@lambdalifting.org
-- Stability   : experimental
-- Portability : non-portable

module Crypto.Saltine.Internal.Password
  ( c_pwhash
  , c_pwhash_str
  , c_pwhash_str_verify
  , c_pwhash_str_needs_rehash

  , pwhash_alg_argon2i13
  , pwhash_alg_argon2id13
  , pwhash_alg_default
  , algorithm

  -- Default algorithm constants
  , pwhash_bytes_max
  , pwhash_bytes_min

  , pwhash_memlimit_interactive
  , pwhash_memlimit_moderate
  , pwhash_memlimit_sensitive
  , pwhash_memlimit_min
  , pwhash_memlimit_max

  , pwhash_opslimit_interactive
  , pwhash_opslimit_moderate
  , pwhash_opslimit_sensitive
  , pwhash_opslimit_min
  , pwhash_opslimit_max

  , pwhash_passwd_min
  , pwhash_passwd_max
  , pwhash_saltbytes
  , pwhash_strbytes
  , pwhash_strprefix

  -- Argon2i algorithm constants
  , pwhash_argon2i_bytes_max
  , pwhash_argon2i_bytes_min

  , pwhash_argon2i_memlimit_interactive
  , pwhash_argon2i_memlimit_moderate
  , pwhash_argon2i_memlimit_sensitive
  , pwhash_argon2i_memlimit_min
  , pwhash_argon2i_memlimit_max

  , pwhash_argon2i_opslimit_interactive
  , pwhash_argon2i_opslimit_moderate
  , pwhash_argon2i_opslimit_sensitive
  , pwhash_argon2i_opslimit_min
  , pwhash_argon2i_opslimit_max

  , pwhash_argon2i_passwd_min
  , pwhash_argon2i_passwd_max
  , pwhash_argon2i_saltbytes
  , pwhash_argon2i_strbytes
  , pwhash_argon2i_strprefix

  -- Argon2id algorithm constants
  , pwhash_argon2id_bytes_max
  , pwhash_argon2id_bytes_min

  , pwhash_argon2id_memlimit_interactive
  , pwhash_argon2id_memlimit_moderate
  , pwhash_argon2id_memlimit_sensitive
  , pwhash_argon2id_memlimit_min
  , pwhash_argon2id_memlimit_max

  , pwhash_argon2id_opslimit_interactive
  , pwhash_argon2id_opslimit_moderate
  , pwhash_argon2id_opslimit_sensitive
  , pwhash_argon2id_opslimit_min
  , pwhash_argon2id_opslimit_max

  , pwhash_argon2id_passwd_min
  , pwhash_argon2id_passwd_max
  , pwhash_argon2id_saltbytes
  , pwhash_argon2id_strbytes
  , pwhash_argon2id_strprefix

  , Salt(..)
  , PasswordHash(..)
  , Opslimit(..)
  , Memlimit(..)
  , Policy(..)
  , Algorithm(..)
  ) where

import Control.DeepSeq
import Crypto.Saltine.Class
import Crypto.Saltine.Internal.Util as U
import Data.ByteString              (ByteString)
import Data.Data                    (Data, Typeable)
import Data.Hashable                (Hashable)
import Data.Monoid
import Data.Text                    (Text)
import GHC.Generics                 (Generic)
import Foreign.C
import Foreign.Ptr

import qualified Data.ByteString    as S
import qualified Data.Text.Encoding as DTE


-- | Salt for deriving keys from passwords
newtype Salt = Salt { unSalt :: ByteString } deriving (Ord, Data, Hashable, Typeable, Generic, NFData)
instance Eq Salt where
    Salt a == Salt b = U.compare a b
instance Show Salt where
    show k = "Password.Salt " <> bin2hex (encode k)

instance IsEncoding Salt where
  decode v = if S.length v == pwhash_saltbytes
           then Just (Salt v)
           else Nothing
  {-# INLINE decode #-}
  encode (Salt v) = v
  {-# INLINE encode #-}

-- | Verification string for stored passwords
-- This hash contains only printable characters, hence we can just derive Show.
newtype PasswordHash = PasswordHash { unPasswordHash :: Text } deriving (Ord, Data, Hashable, Typeable, Generic, Show, NFData)
-- Constant time Eq instance, just in case.
instance Eq PasswordHash where
    PasswordHash a == PasswordHash b = U.compare (DTE.encodeUtf8 a) (DTE.encodeUtf8 b)

-- | Wrapper type for the operations used by password hashing
newtype Opslimit = Opslimit { getOpslimit :: Int } deriving (Eq, Ord, Data, Hashable, Typeable, Generic, Show, NFData)

-- | Wrapper type for the memory used by password hashing
newtype Memlimit = Memlimit { getMemlimit :: Int } deriving (Eq, Ord, Data, Hashable, Typeable, Generic, Show, NFData)

-- | Wrapper for opslimit, memlimit and algorithm
data Policy = Policy
  { opsPolicy :: Opslimit
  , memPolicy :: Memlimit
  , algPolicy :: Algorithm
  } deriving (Eq, Ord, Data, Typeable, Generic, Show)
instance Hashable Policy

-- | Algorithms known to Libsodium, as an enum datatype
data Algorithm
  = DefaultAlgorithm
  | Argon2i13
  | Argon2id13
  deriving (Eq, Enum, Ord, Show, Generic, Data, Typeable, Bounded)
instance Hashable Algorithm

algorithm :: Algorithm -> CInt
algorithm DefaultAlgorithm = fromIntegral pwhash_alg_default
algorithm Argon2i13        = fromIntegral pwhash_alg_argon2i13
algorithm Argon2id13       = fromIntegral pwhash_alg_argon2id13

-- | Lets libsodium pick a hashing algorithm
pwhash_alg_default :: Int
pwhash_alg_default = fromIntegral c_crypto_pwhash_alg_default
-- | version 1.3 of the Argon2i algorithm
pwhash_alg_argon2i13 :: Int
pwhash_alg_argon2i13 = fromIntegral c_crypto_pwhash_alg_argon2i13
-- | version 1.3 of the Argon2id algorithm
pwhash_alg_argon2id13 :: Int
pwhash_alg_argon2id13 = fromIntegral c_crypto_pwhash_alg_argon2id13

-- | Constants for the default algorithm
-- | Minimum output length for key derivation (16 (128 bits)).
pwhash_bytes_min :: Int
pwhash_bytes_min = fromIntegral c_crypto_pwhash_bytes_min
-- | Maximum output length for key derivation.
pwhash_bytes_max :: Int
pwhash_bytes_max = fromIntegral c_crypto_pwhash_bytes_max

-- | Minimum allowed memory limit for password hashing
pwhash_memlimit_min :: Int
pwhash_memlimit_min = fromIntegral c_crypto_pwhash_memlimit_min
-- | Maximum allowed memory limit for password hashing
pwhash_memlimit_max :: Int
pwhash_memlimit_max = fromIntegral c_crypto_pwhash_memlimit_max
-- | Constant for currently 64MB memory
pwhash_memlimit_interactive :: Int
pwhash_memlimit_interactive = fromIntegral c_crypto_pwhash_memlimit_interactive
-- | Constant for currently 256MB memory
pwhash_memlimit_moderate :: Int
pwhash_memlimit_moderate = fromIntegral c_crypto_pwhash_memlimit_moderate
-- | Constant for currently 1024MB memory
pwhash_memlimit_sensitive :: Int
pwhash_memlimit_sensitive = fromIntegral c_crypto_pwhash_memlimit_sensitive

-- | Minimum allowed number of computations for password hashing
pwhash_opslimit_min :: Int
pwhash_opslimit_min = fromIntegral c_crypto_pwhash_opslimit_min
-- | Maximum allowed number of computations for password hashing
pwhash_opslimit_max :: Int
pwhash_opslimit_max = fromIntegral c_crypto_pwhash_opslimit_max

-- | Constant for relatively fast hashing
pwhash_opslimit_interactive :: Int
pwhash_opslimit_interactive = fromIntegral c_crypto_pwhash_opslimit_interactive
-- | Constant for moderately fast hashing
pwhash_opslimit_moderate :: Int
pwhash_opslimit_moderate = fromIntegral c_crypto_pwhash_opslimit_moderate
-- | Constant for relatively slow hashing
pwhash_opslimit_sensitive :: Int
pwhash_opslimit_sensitive = fromIntegral c_crypto_pwhash_opslimit_sensitive

-- | Minimum number of characters in password for key derivation
pwhash_passwd_min :: Int
pwhash_passwd_min = fromIntegral c_crypto_pwhash_passwd_min
-- | Maximum number of characters in password for key derivation
pwhash_passwd_max :: Int
pwhash_passwd_max = fromIntegral c_crypto_pwhash_passwd_max

-- | Size of salt
pwhash_saltbytes :: Int
pwhash_saltbytes = fromIntegral c_crypto_pwhash_saltbytes
-- | (Maximum) size of password hashing output
pwhash_strbytes :: Int
pwhash_strbytes = fromIntegral c_crypto_pwhash_strbytes
-- string that hashes with this algorithm are prefixed with
pwhash_strprefix :: Int
pwhash_strprefix = fromIntegral c_crypto_pwhash_strprefix


-- | Constants for Argon2ID
-- | Minimum output length for key derivation (= 16 (128 bits)).
pwhash_argon2id_bytes_min :: Int
pwhash_argon2id_bytes_min = fromIntegral c_crypto_pwhash_argon2id_bytes_min
-- | Maximum output length for key derivation.
pwhash_argon2id_bytes_max :: Int
pwhash_argon2id_bytes_max = fromIntegral c_crypto_pwhash_argon2id_bytes_max

-- | Minimum allowed memory limit for password hashing
pwhash_argon2id_memlimit_min :: Int
pwhash_argon2id_memlimit_min = fromIntegral c_crypto_pwhash_argon2id_memlimit_min
-- | Maximum allowed memory limit for password hashing
pwhash_argon2id_memlimit_max :: Int
pwhash_argon2id_memlimit_max = fromIntegral c_crypto_pwhash_argon2id_memlimit_max
-- | Constant for currently 64MB memory
pwhash_argon2id_memlimit_interactive :: Int
pwhash_argon2id_memlimit_interactive = fromIntegral c_crypto_pwhash_argon2id_memlimit_interactive
-- | Constant for currently 256MB memory
pwhash_argon2id_memlimit_moderate :: Int
pwhash_argon2id_memlimit_moderate = fromIntegral c_crypto_pwhash_argon2id_memlimit_moderate
-- | Constant for currently 1024MB memory
pwhash_argon2id_memlimit_sensitive :: Int
pwhash_argon2id_memlimit_sensitive = fromIntegral c_crypto_pwhash_argon2id_memlimit_sensitive

-- | Minimum allowed number of computations for password hashing
pwhash_argon2id_opslimit_min :: Int
pwhash_argon2id_opslimit_min = fromIntegral c_crypto_pwhash_argon2id_opslimit_min
-- | Maximum allowed number of computations for password hashing
pwhash_argon2id_opslimit_max :: Int
pwhash_argon2id_opslimit_max = fromIntegral c_crypto_pwhash_argon2id_opslimit_max

-- | Constant for relatively fast hashing
pwhash_argon2id_opslimit_interactive :: Int
pwhash_argon2id_opslimit_interactive = fromIntegral c_crypto_pwhash_argon2id_opslimit_interactive
-- | Constant for moderately fast hashing
pwhash_argon2id_opslimit_moderate :: Int
pwhash_argon2id_opslimit_moderate = fromIntegral c_crypto_pwhash_argon2id_opslimit_moderate
-- | Constant for relatively slow hashing
pwhash_argon2id_opslimit_sensitive :: Int
pwhash_argon2id_opslimit_sensitive = fromIntegral c_crypto_pwhash_argon2id_opslimit_sensitive

-- | Minimum number of characters in password for key derivation
pwhash_argon2id_passwd_min :: Int
pwhash_argon2id_passwd_min = fromIntegral c_crypto_pwhash_argon2id_passwd_min
-- | Maximum number of characters in password for key derivation
pwhash_argon2id_passwd_max :: Int
pwhash_argon2id_passwd_max = fromIntegral c_crypto_pwhash_argon2id_passwd_max

-- | Size of salt
pwhash_argon2id_saltbytes :: Int
pwhash_argon2id_saltbytes = fromIntegral c_crypto_pwhash_argon2id_saltbytes
-- | (Maximum) size of password hashing output
pwhash_argon2id_strbytes :: Int
pwhash_argon2id_strbytes = fromIntegral c_crypto_pwhash_argon2id_strbytes
-- string that hashes with this algorithm are prefixed with
pwhash_argon2id_strprefix :: Int
pwhash_argon2id_strprefix = fromIntegral c_crypto_pwhash_argon2id_strprefix

-- | Constants for ARGON2I
-- | Minimum output length for key derivation (= 16 (128 bits)).
pwhash_argon2i_bytes_min :: Int
pwhash_argon2i_bytes_min = fromIntegral c_crypto_pwhash_argon2i_bytes_min
-- | Maximum output length for key derivation.
pwhash_argon2i_bytes_max :: Int
pwhash_argon2i_bytes_max = fromIntegral c_crypto_pwhash_argon2i_bytes_max

-- | Minimum allowed memory limit for password hashing
pwhash_argon2i_memlimit_min :: Int
pwhash_argon2i_memlimit_min = fromIntegral c_crypto_pwhash_argon2i_memlimit_min
-- | Maximum allowed memory limit for password hashing
pwhash_argon2i_memlimit_max :: Int
pwhash_argon2i_memlimit_max = fromIntegral c_crypto_pwhash_argon2i_memlimit_max
-- | Constant for currently 64MB memory
pwhash_argon2i_memlimit_interactive :: Int
pwhash_argon2i_memlimit_interactive = fromIntegral c_crypto_pwhash_argon2i_memlimit_interactive
-- | Constant for currently 256MB memory
pwhash_argon2i_memlimit_moderate :: Int
pwhash_argon2i_memlimit_moderate = fromIntegral c_crypto_pwhash_argon2i_memlimit_moderate
-- | Constant for currently 1024MB memory
pwhash_argon2i_memlimit_sensitive :: Int
pwhash_argon2i_memlimit_sensitive = fromIntegral c_crypto_pwhash_argon2i_memlimit_sensitive

-- | Minimum allowed number of computations for password hashing
pwhash_argon2i_opslimit_min :: Int
pwhash_argon2i_opslimit_min = fromIntegral c_crypto_pwhash_argon2i_opslimit_min
-- | Maximum allowed number of computations for password hashing
pwhash_argon2i_opslimit_max :: Int
pwhash_argon2i_opslimit_max = fromIntegral c_crypto_pwhash_argon2i_opslimit_max

-- | Constant for relatively fast hashing
pwhash_argon2i_opslimit_interactive :: Int
pwhash_argon2i_opslimit_interactive = fromIntegral c_crypto_pwhash_argon2i_opslimit_interactive
-- | Constant for moderately fast hashing
pwhash_argon2i_opslimit_moderate :: Int
pwhash_argon2i_opslimit_moderate = fromIntegral c_crypto_pwhash_argon2i_opslimit_moderate
-- | Constant for relatively slow hashing
pwhash_argon2i_opslimit_sensitive :: Int
pwhash_argon2i_opslimit_sensitive = fromIntegral c_crypto_pwhash_argon2i_opslimit_sensitive

-- | Minimum number of characters in password for key derivation
pwhash_argon2i_passwd_min :: Int
pwhash_argon2i_passwd_min = fromIntegral c_crypto_pwhash_argon2i_passwd_min
-- | Maximum number of characters in password for key derivation
pwhash_argon2i_passwd_max :: Int
pwhash_argon2i_passwd_max = fromIntegral c_crypto_pwhash_argon2i_passwd_max

-- | Size of salt
pwhash_argon2i_saltbytes :: Int
pwhash_argon2i_saltbytes = fromIntegral c_crypto_pwhash_argon2i_saltbytes
-- | (Maximum) size of password hashing output
pwhash_argon2i_strbytes :: Int
pwhash_argon2i_strbytes = fromIntegral c_crypto_pwhash_argon2i_strbytes
-- string that hashes with this algorithm are prefixed with
pwhash_argon2i_strprefix :: Int
pwhash_argon2i_strprefix = fromIntegral c_crypto_pwhash_argon2i_strprefix



foreign import ccall "crypto_pwhash"
  c_pwhash
        :: Ptr CChar
        -- ^ Derived key output buffer
        -> CULLong
        -- ^ Derived key length
        -> Ptr CChar
        -- ^ Password input buffer
        -> CULLong
        -- ^ Password length
        -> Ptr CChar
        -- ^ Salt input buffer
        -> CULLong
        -- ^ Operation limit
        -> CSize
        -- ^ Memory usage limit
        -> CInt
        -- ^ Algorithm
        -> IO CInt

foreign import ccall "crypto_pwhash_str"
  c_pwhash_str
        :: Ptr CChar
        -- ^ Hashed password output buffer
        -> Ptr CChar
        -- ^ Password input buffer
        -> CULLong
        -- ^ Password length
        -> CULLong
        -- ^ Operation limit
        -> CSize
        -- ^ Memory usage limit
        -> IO CInt

foreign import ccall "crypto_pwhash_str_verify"
  c_pwhash_str_verify
        :: Ptr CChar
        -- ^ Hashed password input buffer
        -> Ptr CChar
        -- ^ Password input buffer
        -> CULLong
        -- ^ Password length
        -> IO CInt

foreign import ccall "crypto_pwhash_str_needs_rehash"
  c_pwhash_str_needs_rehash
        :: Ptr CChar
        -- ^ Hashed password input buffer
        -> CULLong
        -- ^ Operation limit
        -> CSize
        -- ^ Memory usage limit
        -> IO CInt

foreign import ccall "crypto_pwhash_alg_argon2id13"
  c_crypto_pwhash_alg_argon2id13 :: CSize

foreign import ccall "crypto_pwhash_alg_argon2i13"
  c_crypto_pwhash_alg_argon2i13 :: CSize

foreign import ccall "crypto_pwhash_alg_default"
  c_crypto_pwhash_alg_default :: CSize

-- Constants for the default algorithm
foreign import ccall "crypto_pwhash_bytes_min"
  c_crypto_pwhash_bytes_min :: CSize

foreign import ccall "crypto_pwhash_bytes_max"
  c_crypto_pwhash_bytes_max :: CSize

foreign import ccall "crypto_pwhash_memlimit_min"
  c_crypto_pwhash_memlimit_min :: CSize

foreign import ccall "crypto_pwhash_memlimit_max"
  c_crypto_pwhash_memlimit_max :: CSize

foreign import ccall "crypto_pwhash_memlimit_interactive"
  c_crypto_pwhash_memlimit_interactive :: CSize

foreign import ccall "crypto_pwhash_memlimit_moderate"
  c_crypto_pwhash_memlimit_moderate :: CSize

foreign import ccall "crypto_pwhash_memlimit_sensitive"
  c_crypto_pwhash_memlimit_sensitive :: CSize

foreign import ccall "crypto_pwhash_opslimit_min"
  c_crypto_pwhash_opslimit_min :: CSize

foreign import ccall "crypto_pwhash_opslimit_max"
  c_crypto_pwhash_opslimit_max :: CSize

foreign import ccall "crypto_pwhash_opslimit_interactive"
  c_crypto_pwhash_opslimit_interactive :: CSize

foreign import ccall "crypto_pwhash_opslimit_moderate"
  c_crypto_pwhash_opslimit_moderate :: CSize

foreign import ccall "crypto_pwhash_opslimit_sensitive"
  c_crypto_pwhash_opslimit_sensitive :: CSize

foreign import ccall "crypto_pwhash_passwd_min"
  c_crypto_pwhash_passwd_min :: CSize

foreign import ccall "crypto_pwhash_passwd_max"
  c_crypto_pwhash_passwd_max :: CSize

foreign import ccall "crypto_pwhash_saltbytes"
  c_crypto_pwhash_saltbytes :: CSize

foreign import ccall "crypto_pwhash_strbytes"
  c_crypto_pwhash_strbytes :: CSize

foreign import ccall "crypto_pwhash_strprefix"
  c_crypto_pwhash_strprefix :: CSize

-- Constants for ARGON2ID (currently default)
foreign import ccall "crypto_pwhash_argon2id_bytes_min"
  c_crypto_pwhash_argon2id_bytes_min :: CSize

foreign import ccall "crypto_pwhash_argon2id_bytes_max"
  c_crypto_pwhash_argon2id_bytes_max :: CSize

foreign import ccall "crypto_pwhash_argon2id_memlimit_min"
  c_crypto_pwhash_argon2id_memlimit_min :: CSize

foreign import ccall "crypto_pwhash_argon2id_memlimit_max"
  c_crypto_pwhash_argon2id_memlimit_max :: CSize

foreign import ccall "crypto_pwhash_argon2id_memlimit_interactive"
  c_crypto_pwhash_argon2id_memlimit_interactive :: CSize

foreign import ccall "crypto_pwhash_argon2id_memlimit_moderate"
  c_crypto_pwhash_argon2id_memlimit_moderate :: CSize

foreign import ccall "crypto_pwhash_argon2id_memlimit_sensitive"
  c_crypto_pwhash_argon2id_memlimit_sensitive :: CSize

foreign import ccall "crypto_pwhash_argon2id_opslimit_min"
  c_crypto_pwhash_argon2id_opslimit_min :: CSize

foreign import ccall "crypto_pwhash_argon2id_opslimit_max"
  c_crypto_pwhash_argon2id_opslimit_max :: CSize

foreign import ccall "crypto_pwhash_argon2id_opslimit_interactive"
  c_crypto_pwhash_argon2id_opslimit_interactive :: CSize

foreign import ccall "crypto_pwhash_argon2id_opslimit_moderate"
  c_crypto_pwhash_argon2id_opslimit_moderate :: CSize

foreign import ccall "crypto_pwhash_argon2id_opslimit_sensitive"
  c_crypto_pwhash_argon2id_opslimit_sensitive :: CSize

foreign import ccall "crypto_pwhash_argon2id_passwd_min"
  c_crypto_pwhash_argon2id_passwd_min :: CSize

foreign import ccall "crypto_pwhash_argon2id_passwd_max"
  c_crypto_pwhash_argon2id_passwd_max :: CSize

foreign import ccall "crypto_pwhash_argon2id_saltbytes"
  c_crypto_pwhash_argon2id_saltbytes :: CSize

foreign import ccall "crypto_pwhash_argon2id_strbytes"
  c_crypto_pwhash_argon2id_strbytes :: CSize

foreign import ccall "crypto_pwhash_argon2id_strprefix"
  c_crypto_pwhash_argon2id_strprefix :: CSize


-- Constants for ARGON2I
foreign import ccall "crypto_pwhash_argon2i_bytes_min"
  c_crypto_pwhash_argon2i_bytes_min :: CSize

foreign import ccall "crypto_pwhash_argon2i_bytes_max"
  c_crypto_pwhash_argon2i_bytes_max :: CSize

foreign import ccall "crypto_pwhash_argon2i_memlimit_min"
  c_crypto_pwhash_argon2i_memlimit_min :: CSize

foreign import ccall "crypto_pwhash_argon2i_memlimit_max"
  c_crypto_pwhash_argon2i_memlimit_max :: CSize

foreign import ccall "crypto_pwhash_argon2i_memlimit_interactive"
  c_crypto_pwhash_argon2i_memlimit_interactive :: CSize

foreign import ccall "crypto_pwhash_argon2i_memlimit_moderate"
  c_crypto_pwhash_argon2i_memlimit_moderate :: CSize

foreign import ccall "crypto_pwhash_argon2i_memlimit_sensitive"
  c_crypto_pwhash_argon2i_memlimit_sensitive :: CSize

foreign import ccall "crypto_pwhash_argon2i_opslimit_min"
  c_crypto_pwhash_argon2i_opslimit_min :: CSize

foreign import ccall "crypto_pwhash_argon2i_opslimit_max"
  c_crypto_pwhash_argon2i_opslimit_max :: CSize

foreign import ccall "crypto_pwhash_argon2i_opslimit_interactive"
  c_crypto_pwhash_argon2i_opslimit_interactive :: CSize

foreign import ccall "crypto_pwhash_argon2i_opslimit_moderate"
  c_crypto_pwhash_argon2i_opslimit_moderate :: CSize

foreign import ccall "crypto_pwhash_argon2i_opslimit_sensitive"
  c_crypto_pwhash_argon2i_opslimit_sensitive :: CSize

foreign import ccall "crypto_pwhash_argon2i_passwd_min"
  c_crypto_pwhash_argon2i_passwd_min :: CSize

foreign import ccall "crypto_pwhash_argon2i_passwd_max"
  c_crypto_pwhash_argon2i_passwd_max :: CSize

foreign import ccall "crypto_pwhash_argon2i_saltbytes"
  c_crypto_pwhash_argon2i_saltbytes :: CSize

foreign import ccall "crypto_pwhash_argon2i_strbytes"
  c_crypto_pwhash_argon2i_strbytes :: CSize

foreign import ccall "crypto_pwhash_argon2i_strprefix"
  c_crypto_pwhash_argon2i_strprefix :: CSize
