    {-# LANGUAGE CPP, MultiParamTypeClasses #-}

    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Crypto.Nettle.UMAC
    -- Copyright   :  (c) 2013 Stefan Bühler
    -- License     :  MIT-style (see the file COPYING)
    --
    -- Maintainer  :  stbuehler@web.de
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- This module exports the UMAC algorithms supported by nettle:
    --   <http://www.lysator.liu.se/~nisse/nettle/>
    --
    -----------------------------------------------------------------------------

    module Crypto.Nettle.UMAC (
    	  UMAC(..)
    	, UMAC32
    	, UMAC64
    	, UMAC96
    	, UMAC128

    	, umacInitKeyedHash
    	) where

    import Data.SecureMem
    import Data.Tagged
    import qualified Data.ByteString as B
    import qualified Data.ByteString.Internal as B
    import qualified Data.ByteString.Lazy as L
    import Control.Applicative ((<$>))
    import Data.List (foldl')

    import Nettle.Utils
    import Crypto.Nettle.KeyedHash
    import Crypto.Nettle.Hash.ForeignImports

    -- internal functions are not camelCase on purpose
    {-# ANN module "HLint: ignore Use camelCase" #-}

    {-|
    'UMAC' is a class of keyed hash algorithms that take an additional nonce.

    Keys for 'UMAC' are always 16 bytes; there are different digest sizes: 4, 8, 12 and 16 bytes (32, 64, 96 and 128 bits),
    and the variants are named after the digest length in bits.

    On initialization the nonce is set to 0; each finalize returns a new state with an incremented nonce.
    The nonce is interpreted as 16-byte (128-bit) big-endian integer (and for string shorter than 16 bytes padded with zeroes /on the left/; setting empty nonces is not allowed).
    -}
    class UMAC u where
    	-- | digest size in bytes
    	umacDigestSize :: Tagged u Int
    	-- | umac name ("UMAC" ++ digest size in bits)
    	umacName :: Tagged u String
    	umacName = ((String
    "UMAC" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++) (String -> String) -> (Int -> String) -> Int -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> String
    forall a. Show a => a -> String
    show (Int -> String) -> (Int -> Int) -> Int -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int
    8Int -> Int -> Int
    forall a. Num a => a -> a -> a
    *)) (Int -> String) -> Tagged u Int -> Tagged u String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Tagged u Int
    forall u. UMAC u => Tagged u Int
    umacDigestSize
    	-- | initialize a new context from a @key@ with a zero @nonce@
    	umacInit :: B.ByteString {- ^ @key@ argument -} -> u
    	-- | set a @nonce@; can be called anytime before producing the digest
    	umacSetNonce :: u -> B.ByteString {- ^ @nonce@ argument -} -> u
    	-- | append @message@ data to be hashed
    	umacUpdate :: u -> B.ByteString {- ^ @message@ argument -} -> u
    	-- | append lazy @message@ data to be hashed
    	umacUpdateLazy :: u -> L.ByteString {- ^ @message@ argument -} -> u
    	umacUpdateLazy u
    u = (u -> ByteString -> u) -> u -> [ByteString] -> u
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl' u -> ByteString -> u
    forall u. UMAC u => u -> ByteString -> u
    umacUpdate u
    u ([ByteString] -> u)
    -> (ByteString -> [ByteString]) -> ByteString -> u
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> [ByteString]
    L.toChunks
    	-- | produce a digest, and return a new state with incremented nonce
    	umacFinalize :: u -> (B.ByteString, u)

    -- make all (UMAC u) a (KeyedHashAlgorithm u u)
    umacKHDigestSize :: UMAC u => Tagged u Int
    umacKHDigestSize :: forall u. UMAC u => Tagged u Int
    umacKHDigestSize = Tagged u Int
    forall u. UMAC u => Tagged u Int
    umacDigestSize
    umacKHName :: UMAC u => Tagged u String
    umacKHName :: forall u. UMAC u => Tagged u String
    umacKHName = Tagged u String
    forall u. UMAC u => Tagged u String
    umacName
    umacKHInit :: UMAC u => B.ByteString -> u
    umacKHInit :: forall u. UMAC u => ByteString -> u
    umacKHInit = ByteString -> u
    forall u. UMAC u => ByteString -> u
    umacInit
    umacKHUpdate :: UMAC u => u -> B.ByteString -> u
    umacKHUpdate :: forall u. UMAC u => u -> ByteString -> u
    umacKHUpdate = u -> ByteString -> u
    forall u. UMAC u => u -> ByteString -> u
    umacUpdate
    umacKHFinalize :: UMAC u => u -> B.ByteString
    umacKHFinalize :: forall u. UMAC u => u -> ByteString
    umacKHFinalize = (ByteString, u) -> ByteString
    forall a b. (a, b) -> a
    fst ((ByteString, u) -> ByteString)
    -> (u -> (ByteString, u)) -> u -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . u -> (ByteString, u)
    forall u. UMAC u => u -> (ByteString, u)
    umacFinalize

    {-|
    The default 'KeyedHash' generated for UMAC 'KeyedHashAlgorithm' instances use a zero nonce; to set a different nonce you need to use this initialization function (or use the 'UMAC' interface).

    Once the UMAC lives as 'KeyedHash' the nonce cannot be changed anymore, as 'KeyedHash' hides all internal state.
    -}
    umacInitKeyedHash :: (UMAC u, KeyedHashAlgorithm u) => B.ByteString {- ^ @key@ argument -} -> B.ByteString {- ^ @nonce@ argument -} -> Tagged u KeyedHash
    umacInitKeyedHash :: forall u.
    (UMAC u, KeyedHashAlgorithm u) =>
    ByteString -> ByteString -> Tagged u KeyedHash
    umacInitKeyedHash ByteString
    key ByteString
    nonce = u -> KeyedHash
    forall k. KeyedHashAlgorithm k => k -> KeyedHash
    KeyedHash (u -> KeyedHash) -> (u -> u) -> u -> KeyedHash
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (u -> ByteString -> u) -> ByteString -> u -> u
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip u -> ByteString -> u
    forall u. UMAC u => u -> ByteString -> u
    umacSetNonce ByteString
    nonce (u -> KeyedHash) -> Tagged u u -> Tagged u KeyedHash
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> u -> Tagged u u
    forall a. a -> Tagged a a
    tagSelf (ByteString -> u
    forall u. UMAC u => ByteString -> u
    umacInit ByteString
    key)

    class NettleUMAC u where
    	nu_ctx_size :: Tagged u Int
    	nu_digest_size :: Tagged u Int
    	nu_set_key :: Tagged u (Ptr Word8 -> Ptr Word8 -> IO ())
    	nu_set_nonce :: Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    	nu_update :: Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    	nu_digest :: Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    	nu_ctx :: u -> SecureMem
    	nu_Ctx :: SecureMem -> u

    nettleUmacDigestSize :: NettleUMAC u => Tagged u Int
    nettleUmacDigestSize :: forall u. NettleUMAC u => Tagged u Int
    nettleUmacDigestSize = Tagged u Int
    forall u. NettleUMAC u => Tagged u Int
    nu_digest_size
    nettleUmacInit :: NettleUMAC u => B.ByteString -> u
    nettleUmacInit :: forall u. NettleUMAC u => ByteString -> u
    nettleUmacInit ByteString
    key = if ByteString -> Int
    B.length ByteString
    key Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    16 then String -> u
    forall a. HasCallStack => String -> a
    error String
    "wrong key length" else Tagged u u -> u
    forall {k} (s :: k) b. Tagged s b -> b
    untag Tagged u u
    forall u. NettleUMAC u => Tagged u u
    go where
    	go :: NettleUMAC u => Tagged u u
    	go :: forall u. NettleUMAC u => Tagged u u
    go = do
    		size <- Tagged u Int
    forall u. NettleUMAC u => Tagged u Int
    nu_ctx_size
    		set_key <- nu_set_key
    		return $ nu_Ctx $ unsafeCreateSecureMem size $ \Ptr Word8
    ctxptr ->
    			ByteString -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
    withByteStringPtr ByteString
    key ((Word -> Ptr Word8 -> IO ()) -> IO ())
    -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Word
    _ Ptr Word8
    keyptr ->
    			Ptr Word8 -> Ptr Word8 -> IO ()
    set_key Ptr Word8
    ctxptr Ptr Word8
    keyptr
    nettleUmacSetNonce :: NettleUMAC u => u -> B.ByteString -> u
    nettleUmacSetNonce :: forall u. NettleUMAC u => u -> ByteString -> u
    nettleUmacSetNonce u
    c ByteString
    nonce = if ByteString -> Int
    B.length ByteString
    nonce Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    1 Bool -> Bool -> Bool
    || ByteString -> Int
    B.length ByteString
    nonce Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    16 then String -> u
    forall a. HasCallStack => String -> a
    error String
    "invalid nonce length" else Tagged u u -> u
    forall {k} (s :: k) b. Tagged s b -> b
    untag (Tagged u u -> u) -> Tagged u u -> u
    forall a b. (a -> b) -> a -> b
    $ u -> Tagged u u
    forall u. NettleUMAC u => u -> Tagged u u
    go u
    c where
    	go :: NettleUMAC u => u -> Tagged u u
    	go :: forall u. NettleUMAC u => u -> Tagged u u
    go u
    ctx = do
    		set_nonce <- Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall u.
    NettleUMAC u =>
    Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_set_nonce
    		return $ nu_Ctx $ unsafeDupablePerformIO $
    			withSecureMemCopy (nu_ctx ctx) $ \Ptr Word8
    ctxptr ->
    			ByteString -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
    withByteStringPtr ByteString
    nonce ((Word -> Ptr Word8 -> IO ()) -> IO ())
    -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Word
    noncelen Ptr Word8
    nonceptr ->
    				Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    set_nonce Ptr Word8
    ctxptr Word
    noncelen Ptr Word8
    nonceptr
    nettleUmacUpdate :: NettleUMAC u => u -> B.ByteString -> u
    nettleUmacUpdate :: forall u. NettleUMAC u => u -> ByteString -> u
    nettleUmacUpdate u
    c ByteString
    msg = Tagged u u -> u
    forall {k} (s :: k) b. Tagged s b -> b
    untag (Tagged u u -> u) -> Tagged u u -> u
    forall a b. (a -> b) -> a -> b
    $ u -> Tagged u u
    forall u. NettleUMAC u => u -> Tagged u u
    go u
    c where
    	go :: NettleUMAC u => u -> Tagged u u
    	go :: forall u. NettleUMAC u => u -> Tagged u u
    go u
    ctx = do
    		update <- Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall u.
    NettleUMAC u =>
    Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_update
    		return $ nu_Ctx $ unsafeDupablePerformIO $
    			withSecureMemCopy (nu_ctx ctx) $ \Ptr Word8
    ctxptr ->
    			ByteString -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
    withByteStringPtr ByteString
    msg ((Word -> Ptr Word8 -> IO ()) -> IO ())
    -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Word
    msglen Ptr Word8
    msgptr ->
    				Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    update Ptr Word8
    ctxptr Word
    msglen Ptr Word8
    msgptr
    nettleUmacUpdateLazy :: NettleUMAC u => u -> L.ByteString -> u
    nettleUmacUpdateLazy :: forall u. NettleUMAC u => u -> ByteString -> u
    nettleUmacUpdateLazy u
    c ByteString
    msg = Tagged u u -> u
    forall {k} (s :: k) b. Tagged s b -> b
    untag (Tagged u u -> u) -> Tagged u u -> u
    forall a b. (a -> b) -> a -> b
    $ u -> Tagged u u
    forall u. NettleUMAC u => u -> Tagged u u
    go u
    c where
    	go :: NettleUMAC u => u -> Tagged u u
    	go :: forall u. NettleUMAC u => u -> Tagged u u
    go u
    ctx = do
    		update <- Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall u.
    NettleUMAC u =>
    Tagged u (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_update
    		return $ nu_Ctx $ unsafeDupablePerformIO $
    			withSecureMemCopy (nu_ctx ctx) $ \Ptr Word8
    ctxptr ->
    			[ByteString] -> (ByteString -> IO ()) -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    t a -> (a -> m b) -> m ()
    forM_ (ByteString -> [ByteString]
    L.toChunks ByteString
    msg) ((ByteString -> IO ()) -> IO ()) -> (ByteString -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \ByteString
    chunk ->
    			ByteString -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a. ByteString -> (Word -> Ptr Word8 -> IO a) -> IO a
    withByteStringPtr ByteString
    chunk ((Word -> Ptr Word8 -> IO ()) -> IO ())
    -> (Word -> Ptr Word8 -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Word
    chunklen Ptr Word8
    chunkptr ->
    				Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    update Ptr Word8
    ctxptr Word
    chunklen Ptr Word8
    chunkptr
    nettleUmacFinalize :: NettleUMAC u => u -> (B.ByteString, u)
    nettleUmacFinalize :: forall u. NettleUMAC u => u -> (ByteString, u)
    nettleUmacFinalize u
    c = Tagged u (ByteString, u) -> (ByteString, u)
    forall {k} (s :: k) b. Tagged s b -> b
    untag (Tagged u (ByteString, u) -> (ByteString, u))
    -> Tagged u (ByteString, u) -> (ByteString, u)
    forall a b. (a -> b) -> a -> b
    $ u -> Tagged u (ByteString, u)
    forall u. NettleUMAC u => u -> Tagged u (ByteString, u)
    go u
    c where
    	go :: NettleUMAC u => u -> Tagged u (B.ByteString, u)
    	go :: forall u. NettleUMAC u => u -> Tagged u (ByteString, u)
    go u
    ctx = do
    		digestSize <- Tagged u Int
    forall u. NettleUMAC u => Tagged u Int
    nu_digest_size
    		digest <- nu_digest
    		return $ unsafeDupablePerformIO $ do
    			ctx' <- secureMemCopy (nu_ctx ctx)
    			dig <- withSecureMemPtr ctx' $ \Ptr Word8
    ctxptr ->
    				Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    B.create Int
    digestSize ((Ptr Word8 -> IO ()) -> IO ByteString)
    -> (Ptr Word8 -> IO ()) -> IO ByteString
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    digestptr ->
    				Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    digest Ptr Word8
    ctxptr (Int -> Word
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    digestSize) Ptr Word8
    digestptr
    			return (dig, nu_Ctx ctx')

    #define INSTANCE_UMAC(Typ) \
    instance UMAC Typ where \
    	{ umacDigestSize = nettleUmacDigestSize \
    	; umacInit       = nettleUmacInit \
    	; umacSetNonce   = nettleUmacSetNonce \
    	; umacUpdate     = nettleUmacUpdate \
    	; umacUpdateLazy = nettleUmacUpdateLazy \
    	; umacFinalize   = nettleUmacFinalize \
    	} ; \
    instance KeyedHashAlgorithm Typ where \
    	{ implKeyedHashDigestSize = umacKHDigestSize \
    	; implKeyedHashName       = umacKHName \
    	; implKeyedHashInit       = umacKHInit \
    	; implKeyedHashUpdate     = umacKHUpdate \
    	; implKeyedHashFinalize   = umacKHFinalize \
    	}

    {-|
    'UMAC32' is the 32-bit (4 byte) digest variant. See 'umacInitKeyedHash' for the 'KeyedHashAlgorithm' instance.
    -}
    newtype UMAC32 = UMAC32 { UMAC32 -> SecureMem
    umac32_ctx :: SecureMem }
    instance NettleUMAC UMAC32 where
    	nu_ctx_size :: Tagged UMAC32 Int
    nu_ctx_size    = Int -> Tagged UMAC32 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac32_ctx_size
    	nu_digest_size :: Tagged UMAC32 Int
    nu_digest_size = Int -> Tagged UMAC32 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac32_digest_size
    	nu_set_key :: Tagged UMAC32 (Ptr Word8 -> Ptr Word8 -> IO ())
    nu_set_key     = (Ptr Word8 -> Ptr Word8 -> IO ())
    -> Tagged UMAC32 (Ptr Word8 -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8 -> IO ()
    c_umac32_set_key
    	nu_set_nonce :: Tagged UMAC32 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_set_nonce   = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC32 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac32_set_nonce
    	nu_update :: Tagged UMAC32 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_update      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC32 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac32_update
    	nu_digest :: Tagged UMAC32 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_digest      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC32 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac32_digest
    	nu_ctx :: UMAC32 -> SecureMem
    nu_ctx         = UMAC32 -> SecureMem
    umac32_ctx
    	nu_Ctx :: SecureMem -> UMAC32
    nu_Ctx         = SecureMem -> UMAC32
    UMAC32
    INSTANCE_UMAC(UMAC32)

    {-|
    'UMAC64' is the 64-bit (8 byte) digest variant. See 'umacInitKeyedHash' for the 'KeyedHashAlgorithm' instance.
    -}
    newtype UMAC64 = UMAC64 { UMAC64 -> SecureMem
    umac64_ctx :: SecureMem }
    instance NettleUMAC UMAC64 where
    	nu_ctx_size :: Tagged UMAC64 Int
    nu_ctx_size    = Int -> Tagged UMAC64 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac64_ctx_size
    	nu_digest_size :: Tagged UMAC64 Int
    nu_digest_size = Int -> Tagged UMAC64 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac64_digest_size
    	nu_set_key :: Tagged UMAC64 (Ptr Word8 -> Ptr Word8 -> IO ())
    nu_set_key     = (Ptr Word8 -> Ptr Word8 -> IO ())
    -> Tagged UMAC64 (Ptr Word8 -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8 -> IO ()
    c_umac64_set_key
    	nu_set_nonce :: Tagged UMAC64 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_set_nonce   = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC64 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac64_set_nonce
    	nu_update :: Tagged UMAC64 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_update      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC64 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac64_update
    	nu_digest :: Tagged UMAC64 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_digest      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC64 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac64_digest
    	nu_ctx :: UMAC64 -> SecureMem
    nu_ctx         = UMAC64 -> SecureMem
    umac64_ctx
    	nu_Ctx :: SecureMem -> UMAC64
    nu_Ctx         = SecureMem -> UMAC64
    UMAC64
    INSTANCE_UMAC(UMAC64)

    {-|
    'UMAC96' is the 96-bit (12 byte) digest variant. See 'umacInitKeyedHash' for the 'KeyedHashAlgorithm' instance.
    -}
    newtype UMAC96 = UMAC96 { UMAC96 -> SecureMem
    umac96_ctx :: SecureMem }
    instance NettleUMAC UMAC96 where
    	nu_ctx_size :: Tagged UMAC96 Int
    nu_ctx_size    = Int -> Tagged UMAC96 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac96_ctx_size
    	nu_digest_size :: Tagged UMAC96 Int
    nu_digest_size = Int -> Tagged UMAC96 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac96_digest_size
    	nu_set_key :: Tagged UMAC96 (Ptr Word8 -> Ptr Word8 -> IO ())
    nu_set_key     = (Ptr Word8 -> Ptr Word8 -> IO ())
    -> Tagged UMAC96 (Ptr Word8 -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8 -> IO ()
    c_umac96_set_key
    	nu_set_nonce :: Tagged UMAC96 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_set_nonce   = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC96 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac96_set_nonce
    	nu_update :: Tagged UMAC96 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_update      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC96 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac96_update
    	nu_digest :: Tagged UMAC96 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_digest      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC96 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac96_digest
    	nu_ctx :: UMAC96 -> SecureMem
    nu_ctx         = UMAC96 -> SecureMem
    umac96_ctx
    	nu_Ctx :: SecureMem -> UMAC96
    nu_Ctx         = SecureMem -> UMAC96
    UMAC96
    INSTANCE_UMAC(UMAC96)

    {-|
    'UMAC128' is the 128-bit (16 byte) digest variant. See 'umacInitKeyedHash' for the 'KeyedHashAlgorithm' instance.
    -}
    newtype UMAC128 = UMAC128 { UMAC128 -> SecureMem
    umac128_ctx :: SecureMem }
    instance NettleUMAC UMAC128 where
    	nu_ctx_size :: Tagged UMAC128 Int
    nu_ctx_size    = Int -> Tagged UMAC128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac128_ctx_size
    	nu_digest_size :: Tagged UMAC128 Int
    nu_digest_size = Int -> Tagged UMAC128 Int
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Int
    c_umac128_digest_size
    	nu_set_key :: Tagged UMAC128 (Ptr Word8 -> Ptr Word8 -> IO ())
    nu_set_key     = (Ptr Word8 -> Ptr Word8 -> IO ())
    -> Tagged UMAC128 (Ptr Word8 -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Ptr Word8 -> IO ()
    c_umac128_set_key
    	nu_set_nonce :: Tagged UMAC128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_set_nonce   = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac128_set_nonce
    	nu_update :: Tagged UMAC128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_update      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac128_update
    	nu_digest :: Tagged UMAC128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    nu_digest      = (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    -> Tagged UMAC128 (Ptr Word8 -> Word -> Ptr Word8 -> IO ())
    forall {k} (s :: k) b. b -> Tagged s b
    Tagged Ptr Word8 -> Word -> Ptr Word8 -> IO ()
    c_umac128_digest
    	nu_ctx :: UMAC128 -> SecureMem
    nu_ctx         = UMAC128 -> SecureMem
    umac128_ctx
    	nu_Ctx :: SecureMem -> UMAC128
    nu_Ctx         = SecureMem -> UMAC128
    UMAC128
    INSTANCE_UMAC(UMAC128)