saltine-0.2.0.0: src/Crypto/Saltine/Internal/OneTimeAuth.hs
{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric, ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Saltine.Internal.OneTimeAuth
-- Copyright : (c) Max Amanshauser 2021
-- License : MIT
--
-- Maintainer : max@lambdalifting.org
-- Stability : experimental
-- Portability : non-portable
--
module Crypto.Saltine.Internal.OneTimeAuth (
onetimeauth_bytes
, onetimeauth_keybytes
, c_onetimeauth
, c_onetimeauth_verify
, Key(..)
, Authenticator(..)
) where
import Control.DeepSeq
import Crypto.Saltine.Class
import Crypto.Saltine.Core.Hash (shorthash)
import Crypto.Saltine.Internal.Hash (nullShKey)
import Crypto.Saltine.Internal.Util as U
import Data.ByteString (ByteString)
import Data.Data (Data, Typeable)
import Data.Hashable (Hashable)
import Data.Monoid
import Foreign.C
import Foreign.Ptr
import GHC.Generics (Generic)
import qualified Data.ByteString as S
-- | An opaque 'auth' cryptographic key.
newtype Key = Key { unKey :: ByteString } deriving (Ord, Hashable, Data, Typeable, Generic, NFData)
instance Eq Key where
Key a == Key b = U.compare a b
instance Show Key where
show k = "OneTimeAuth.Key {hashesTo = \"" <> (bin2hex . shorthash nullShKey $ encode k) <> "}\""
instance IsEncoding Key where
decode v = if S.length v == onetimeauth_keybytes
then Just (Key v)
else Nothing
{-# INLINE decode #-}
encode (Key v) = v
{-# INLINE encode #-}
-- | An opaque 'auth' authenticator.
newtype Authenticator = Au { unAu :: ByteString } deriving (Eq, Ord, Hashable, Data, Typeable, Generic, NFData)
instance Show Authenticator where
show k = "OneTimeAuth.Authenticator " <> bin2hex (encode k)
instance IsEncoding Authenticator where
decode v = if S.length v == onetimeauth_bytes
then Just (Au v)
else Nothing
{-# INLINE decode #-}
encode (Au v) = v
{-# INLINE encode #-}
onetimeauth_bytes, onetimeauth_keybytes :: Int
-- OneTimeAuth
-- | Size of a @crypto_onetimeauth@ authenticator.
onetimeauth_bytes = fromIntegral c_crypto_onetimeauth_bytes
-- | Size of a @crypto_onetimeauth@ authenticator key.
onetimeauth_keybytes = fromIntegral c_crypto_onetimeauth_keybytes
-- src/libsodium/crypto_onetimeauth/crypto_onetimeauth.c
foreign import ccall "crypto_onetimeauth_bytes"
c_crypto_onetimeauth_bytes :: CSize
foreign import ccall "crypto_onetimeauth_keybytes"
c_crypto_onetimeauth_keybytes :: CSize
foreign import ccall "crypto_onetimeauth"
c_onetimeauth :: Ptr CChar
-- ^ Authenticator output buffer
-> Ptr CChar
-- ^ Constant message buffer
-> CULLong
-- ^ Length of message buffer
-> Ptr CChar
-- ^ Constant key buffer
-> IO CInt
-- ^ Always 0
-- | We don't even include this in the IO monad since all of the
-- buffers are constant.
foreign import ccall "crypto_onetimeauth_verify"
c_onetimeauth_verify :: Ptr CChar
-- ^ Constant authenticator buffer
-> Ptr CChar
-- ^ Constant message buffer
-> CULLong
-- ^ Length of message buffer
-> Ptr CChar
-- ^ Constant key buffer
-> CInt
-- ^ Success if 0, failure if -1