-- |
-- 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]