    -- |
    -- Module      : Crypto.MAC.SHA3
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- provide a simple SHA3 MAC mechanism with
    --
    -- > mac = hash(key|message)
    --
    module Crypto.MAC.SHA3
        ( MAC512(..)
        , MAC384(..)
        , MAC256(..)
        , MAC224(..)
        , mac512
        , mac384
        , mac256
        , mac224
        ) where

    import Data.Byteable
    import Data.ByteString (ByteString)
    import Crypto.Hash

    -- | SHA3_512 MAC
    data MAC512 = MAC512 { MAC512 -> Digest SHA3_512
    getDigest512 :: Digest SHA3_512 }

    instance Byteable MAC512 where
        toBytes :: MAC512 -> ByteString
    toBytes (MAC512 b :: Digest SHA3_512
    b) = Digest SHA3_512 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_512
    b
    instance Eq MAC512 where
        (MAC512 b1 :: Digest SHA3_512
    b1) == :: MAC512 -> MAC512 -> Bool
    == (MAC512 b2 :: Digest SHA3_512
    b2) = ByteString -> ByteString -> Bool
    forall a. Byteable a => a -> a -> Bool
    constEqBytes (Digest SHA3_512 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_512
    b1) (Digest SHA3_512 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_512
    b2)

    -- | SHA3_384 MAC
    data MAC384 = MAC384 { MAC384 -> Digest SHA3_384
    getDigest384 :: Digest SHA3_384 }

    instance Byteable MAC384 where
        toBytes :: MAC384 -> ByteString
    toBytes (MAC384 b :: Digest SHA3_384
    b) = Digest SHA3_384 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_384
    b
    instance Eq MAC384 where
        (MAC384 b1 :: Digest SHA3_384
    b1) == :: MAC384 -> MAC384 -> Bool
    == (MAC384 b2 :: Digest SHA3_384
    b2) = ByteString -> ByteString -> Bool
    forall a. Byteable a => a -> a -> Bool
    constEqBytes (Digest SHA3_384 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_384
    b1) (Digest SHA3_384 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_384
    b2)

    -- | SHA3_256 MAC
    data MAC256 = MAC256 { MAC256 -> Digest SHA3_256
    getDigest256 :: Digest SHA3_256 }

    instance Byteable MAC256 where
        toBytes :: MAC256 -> ByteString
    toBytes (MAC256 b :: Digest SHA3_256
    b) = Digest SHA3_256 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_256
    b
    instance Eq MAC256 where
        (MAC256 b1 :: Digest SHA3_256
    b1) == :: MAC256 -> MAC256 -> Bool
    == (MAC256 b2 :: Digest SHA3_256
    b2) = ByteString -> ByteString -> Bool
    forall a. Byteable a => a -> a -> Bool
    constEqBytes (Digest SHA3_256 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_256
    b1) (Digest SHA3_256 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_256
    b2)

    -- | SHA3_224 MAC
    data MAC224 = MAC224 { MAC224 -> Digest SHA3_224
    getDigest224 :: Digest SHA3_224 }

    instance Byteable MAC224 where
        toBytes :: MAC224 -> ByteString
    toBytes (MAC224 b :: Digest SHA3_224
    b) = Digest SHA3_224 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_224
    b
    instance Eq MAC224 where
        (MAC224 b1 :: Digest SHA3_224
    b1) == :: MAC224 -> MAC224 -> Bool
    == (MAC224 b2 :: Digest SHA3_224
    b2) = ByteString -> ByteString -> Bool
    forall a. Byteable a => a -> a -> Bool
    constEqBytes (Digest SHA3_224 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_224
    b1) (Digest SHA3_224 -> ByteString
    forall a. Byteable a => a -> ByteString
    toBytes Digest SHA3_224
    b2)

    -- | compute a MAC using a simple SHA3_512 key|msg
    mac512 :: ByteString -- ^ secret
           -> ByteString -- ^ message
           -> MAC512
    mac512 :: ByteString -> ByteString -> MAC512
    mac512 secret :: ByteString
    secret msg :: ByteString
    msg = Digest SHA3_512 -> MAC512
    MAC512 (Digest SHA3_512 -> MAC512) -> Digest SHA3_512 -> MAC512
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_512 -> Digest SHA3_512
    forall a. HashAlgorithm a => Context a -> Digest a
    hashFinalize (Context SHA3_512 -> Digest SHA3_512)
    -> Context SHA3_512 -> Digest SHA3_512
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_512 -> [ByteString] -> Context SHA3_512
    forall a. HashAlgorithm a => Context a -> [ByteString] -> Context a
    hashUpdates Context SHA3_512
    forall a. HashAlgorithm a => Context a
    hashInit [ByteString
    secret,ByteString
    msg]

    -- | compute a MAC using a simple SHA3_384 key|msg
    mac384 :: ByteString -- ^ secret
           -> ByteString -- ^ message
           -> MAC384
    mac384 :: ByteString -> ByteString -> MAC384
    mac384 secret :: ByteString
    secret msg :: ByteString
    msg = Digest SHA3_384 -> MAC384
    MAC384 (Digest SHA3_384 -> MAC384) -> Digest SHA3_384 -> MAC384
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_384 -> Digest SHA3_384
    forall a. HashAlgorithm a => Context a -> Digest a
    hashFinalize (Context SHA3_384 -> Digest SHA3_384)
    -> Context SHA3_384 -> Digest SHA3_384
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_384 -> [ByteString] -> Context SHA3_384
    forall a. HashAlgorithm a => Context a -> [ByteString] -> Context a
    hashUpdates Context SHA3_384
    forall a. HashAlgorithm a => Context a
    hashInit [ByteString
    secret,ByteString
    msg]

    -- | compute a MAC using a simple SHA3_256 key|msg
    mac256 :: ByteString -- ^ secret
           -> ByteString -- ^ message
           -> MAC256
    mac256 :: ByteString -> ByteString -> MAC256
    mac256 secret :: ByteString
    secret msg :: ByteString
    msg = Digest SHA3_256 -> MAC256
    MAC256 (Digest SHA3_256 -> MAC256) -> Digest SHA3_256 -> MAC256
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_256 -> Digest SHA3_256
    forall a. HashAlgorithm a => Context a -> Digest a
    hashFinalize (Context SHA3_256 -> Digest SHA3_256)
    -> Context SHA3_256 -> Digest SHA3_256
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_256 -> [ByteString] -> Context SHA3_256
    forall a. HashAlgorithm a => Context a -> [ByteString] -> Context a
    hashUpdates Context SHA3_256
    forall a. HashAlgorithm a => Context a
    hashInit [ByteString
    secret,ByteString
    msg]

    -- | compute a MAC using a simple SHA3_224 key|msg
    mac224 :: ByteString -- ^ secret
           -> ByteString -- ^ message
           -> MAC224
    mac224 :: ByteString -> ByteString -> MAC224
    mac224 secret :: ByteString
    secret msg :: ByteString
    msg = Digest SHA3_224 -> MAC224
    MAC224 (Digest SHA3_224 -> MAC224) -> Digest SHA3_224 -> MAC224
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_224 -> Digest SHA3_224
    forall a. HashAlgorithm a => Context a -> Digest a
    hashFinalize (Context SHA3_224 -> Digest SHA3_224)
    -> Context SHA3_224 -> Digest SHA3_224
    forall a b. (a -> b) -> a -> b
    $ Context SHA3_224 -> [ByteString] -> Context SHA3_224
    forall a. HashAlgorithm a => Context a -> [ByteString] -> Context a
    hashUpdates Context SHA3_224
    forall a. HashAlgorithm a => Context a
    hashInit [ByteString
    secret,ByteString
    msg]