    -- |
    -- Module      : Crypto.Hash.Blake2
    -- License     : BSD-style
    -- Maintainer  : Nicolas Di Prima <nicolas@primetype.co.uk>
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- Module containing the binding functions to work with the
    -- Blake2
    --
    -- Implementation based from [RFC7693](https://tools.ietf.org/html/rfc7693)
    --
    -- Please consider the following when chosing a hash:
    --
    --      Algorithm     | Target | Collision | Digest Size |
    --         Identifier |  Arch  |  Security |   in bytes  |
    --     ---------------+--------+-----------+-------------+
    --      id-blake2b160 | 64-bit |   2**80   |         20  |
    --      id-blake2b256 | 64-bit |   2**128  |         32  |
    --      id-blake2b384 | 64-bit |   2**192  |         48  |
    --      id-blake2b512 | 64-bit |   2**256  |         64  |
    --     ---------------+--------+-----------+-------------+
    --      id-blake2s128 | 32-bit |   2**64   |         16  |
    --      id-blake2s160 | 32-bit |   2**80   |         20  |
    --      id-blake2s224 | 32-bit |   2**112  |         28  |
    --      id-blake2s256 | 32-bit |   2**128  |         32  |
    --     ---------------+--------+-----------+-------------+
    --
    {-# LANGUAGE ForeignFunctionInterface #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE KindSignatures #-}
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE TypeFamilies #-}
    module Crypto.Hash.Blake2
        ( Blake2s(..)
        , Blake2sp(..)
        , Blake2b(..)
        , Blake2bp(..)
        ) where

    import           Crypto.Hash.Types
    import           Foreign.Ptr (Ptr)
    import           Data.Data
    import           Data.Word (Word8, Word32)
    import           GHC.TypeLits (Nat, KnownNat)
    import           Crypto.Internal.Nat

    -- | Fast and secure alternative to SHA1 and HMAC-SHA1
    --
    -- It is espacially known to target 32bits architectures.
    --
    -- Known supported digest sizes:
    --
    -- * Blake2s 160
    -- * Blake2s 224
    -- * Blake2s 256
    --
    data Blake2s (bitlen :: Nat) = Blake2s
        deriving (Int -> Blake2s bitlen -> ShowS
    [Blake2s bitlen] -> ShowS
    Blake2s bitlen -> String
    (Int -> Blake2s bitlen -> ShowS)
    -> (Blake2s bitlen -> String)
    -> ([Blake2s bitlen] -> ShowS)
    -> Show (Blake2s bitlen)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (bitlen :: Nat). Int -> Blake2s bitlen -> ShowS
    forall (bitlen :: Nat). [Blake2s bitlen] -> ShowS
    forall (bitlen :: Nat). Blake2s bitlen -> String
    showList :: [Blake2s bitlen] -> ShowS
    $cshowList :: forall (bitlen :: Nat). [Blake2s bitlen] -> ShowS
    show :: Blake2s bitlen -> String
    $cshow :: forall (bitlen :: Nat). Blake2s bitlen -> String
    showsPrec :: Int -> Blake2s bitlen -> ShowS
    $cshowsPrec :: forall (bitlen :: Nat). Int -> Blake2s bitlen -> ShowS
    Show,Typeable (Blake2s bitlen)
    DataType
    Constr
    Typeable (Blake2s bitlen) =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Blake2s bitlen -> c (Blake2s bitlen))
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (Blake2s bitlen))
    -> (Blake2s bitlen -> Constr)
    -> (Blake2s bitlen -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (Blake2s bitlen)))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (Blake2s bitlen)))
    -> ((forall b. Data b => b -> b)
        -> Blake2s bitlen -> Blake2s bitlen)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> Blake2s bitlen -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Blake2s bitlen -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> Blake2s bitlen -> m (Blake2s bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2s bitlen -> m (Blake2s bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2s bitlen -> m (Blake2s bitlen))
    -> Data (Blake2s bitlen)
    Blake2s bitlen -> DataType
    Blake2s bitlen -> Constr
    (forall b. Data b => b -> b) -> Blake2s bitlen -> Blake2s bitlen
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2s bitlen -> c (Blake2s bitlen)
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2s bitlen)
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> Blake2s bitlen -> u
    forall u. (forall d. Data d => d -> u) -> Blake2s bitlen -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2s bitlen)
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2s bitlen -> DataType
    forall (bitlen :: Nat). KnownNat bitlen => Blake2s bitlen -> Constr
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2s bitlen -> Blake2s bitlen
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2s bitlen -> u
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2s bitlen -> [u]
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2s bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2s bitlen -> c (Blake2s bitlen)
    forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2s bitlen))
    forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2s bitlen))
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2s bitlen)
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2s bitlen -> c (Blake2s bitlen)
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2s bitlen))
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2s bitlen))
    $cBlake2s :: Constr
    $tBlake2s :: DataType
    gmapMo :: (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    $cgmapMo :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    gmapMp :: (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    $cgmapMp :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    gmapM :: (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    $cgmapM :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2s bitlen -> m (Blake2s bitlen)
    gmapQi :: Int -> (forall d. Data d => d -> u) -> Blake2s bitlen -> u
    $cgmapQi :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2s bitlen -> u
    gmapQ :: (forall d. Data d => d -> u) -> Blake2s bitlen -> [u]
    $cgmapQ :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2s bitlen -> [u]
    gmapQr :: (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    $cgmapQr :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    gmapQl :: (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    $cgmapQl :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2s bitlen -> r
    gmapT :: (forall b. Data b => b -> b) -> Blake2s bitlen -> Blake2s bitlen
    $cgmapT :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2s bitlen -> Blake2s bitlen
    dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2s bitlen))
    $cdataCast2 :: forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2s bitlen))
    dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Blake2s bitlen))
    $cdataCast1 :: forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2s bitlen))
    dataTypeOf :: Blake2s bitlen -> DataType
    $cdataTypeOf :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2s bitlen -> DataType
    toConstr :: Blake2s bitlen -> Constr
    $ctoConstr :: forall (bitlen :: Nat). KnownNat bitlen => Blake2s bitlen -> Constr
    gunfold :: (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2s bitlen)
    $cgunfold :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2s bitlen)
    gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2s bitlen -> c (Blake2s bitlen)
    $cgfoldl :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2s bitlen -> c (Blake2s bitlen)
    $cp1Data :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2s bitlen)
    Data)

    instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256)
          => HashAlgorithm (Blake2s bitlen)
          where
        type HashBlockSize           (Blake2s bitlen) = 64
        type HashDigestSize          (Blake2s bitlen) = Div8 bitlen
        type HashInternalContextSize (Blake2s bitlen) = 136
        hashBlockSize :: Blake2s bitlen -> Int
    hashBlockSize  _          = 64
        hashDigestSize :: Blake2s bitlen -> Int
    hashDigestSize _          = Proxy bitlen -> Int
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    byteLen (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen)
        hashInternalContextSize :: Blake2s bitlen -> Int
    hashInternalContextSize _ = 136
        hashInternalInit :: Ptr (Context (Blake2s bitlen)) -> IO ()
    hashInternalInit p :: Ptr (Context (Blake2s bitlen))
    p        = Ptr (Context (Blake2s bitlen)) -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Word32 -> IO ()
    c_blake2s_init Ptr (Context (Blake2s bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))
        hashInternalUpdate :: Ptr (Context (Blake2s bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    hashInternalUpdate        = Ptr (Context (Blake2s bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    c_blake2s_update
        hashInternalFinalize :: Ptr (Context (Blake2s bitlen))
    -> Ptr (Digest (Blake2s bitlen)) -> IO ()
    hashInternalFinalize p :: Ptr (Context (Blake2s bitlen))
    p    = Ptr (Context (Blake2s bitlen))
    -> Word32 -> Ptr (Digest (Blake2s bitlen)) -> IO ()
    forall a. Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
    c_blake2s_finalize Ptr (Context (Blake2s bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))

    foreign import ccall unsafe "cryptonite_blake2s_init"
        c_blake2s_init :: Ptr (Context a) -> Word32 -> IO ()
    foreign import ccall "cryptonite_blake2s_update"
        c_blake2s_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    foreign import ccall unsafe "cryptonite_blake2s_finalize"
        c_blake2s_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()

    -- | Fast cryptographic hash.
    --
    -- It is especially known to target 64bits architectures.
    --
    -- Known supported digest sizes:
    --
    -- * Blake2b 160
    -- * Blake2b 224
    -- * Blake2b 256
    -- * Blake2b 384
    -- * Blake2b 512
    --
    data Blake2b (bitlen :: Nat) = Blake2b
        deriving (Int -> Blake2b bitlen -> ShowS
    [Blake2b bitlen] -> ShowS
    Blake2b bitlen -> String
    (Int -> Blake2b bitlen -> ShowS)
    -> (Blake2b bitlen -> String)
    -> ([Blake2b bitlen] -> ShowS)
    -> Show (Blake2b bitlen)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (bitlen :: Nat). Int -> Blake2b bitlen -> ShowS
    forall (bitlen :: Nat). [Blake2b bitlen] -> ShowS
    forall (bitlen :: Nat). Blake2b bitlen -> String
    showList :: [Blake2b bitlen] -> ShowS
    $cshowList :: forall (bitlen :: Nat). [Blake2b bitlen] -> ShowS
    show :: Blake2b bitlen -> String
    $cshow :: forall (bitlen :: Nat). Blake2b bitlen -> String
    showsPrec :: Int -> Blake2b bitlen -> ShowS
    $cshowsPrec :: forall (bitlen :: Nat). Int -> Blake2b bitlen -> ShowS
    Show,Typeable (Blake2b bitlen)
    DataType
    Constr
    Typeable (Blake2b bitlen) =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Blake2b bitlen -> c (Blake2b bitlen))
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (Blake2b bitlen))
    -> (Blake2b bitlen -> Constr)
    -> (Blake2b bitlen -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (Blake2b bitlen)))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (Blake2b bitlen)))
    -> ((forall b. Data b => b -> b)
        -> Blake2b bitlen -> Blake2b bitlen)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> Blake2b bitlen -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Blake2b bitlen -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> Blake2b bitlen -> m (Blake2b bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2b bitlen -> m (Blake2b bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2b bitlen -> m (Blake2b bitlen))
    -> Data (Blake2b bitlen)
    Blake2b bitlen -> DataType
    Blake2b bitlen -> Constr
    (forall b. Data b => b -> b) -> Blake2b bitlen -> Blake2b bitlen
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2b bitlen -> c (Blake2b bitlen)
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2b bitlen)
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> Blake2b bitlen -> u
    forall u. (forall d. Data d => d -> u) -> Blake2b bitlen -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2b bitlen)
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2b bitlen -> DataType
    forall (bitlen :: Nat). KnownNat bitlen => Blake2b bitlen -> Constr
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2b bitlen -> Blake2b bitlen
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2b bitlen -> u
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2b bitlen -> [u]
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2b bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2b bitlen -> c (Blake2b bitlen)
    forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2b bitlen))
    forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2b bitlen))
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2b bitlen)
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2b bitlen -> c (Blake2b bitlen)
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2b bitlen))
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2b bitlen))
    $cBlake2b :: Constr
    $tBlake2b :: DataType
    gmapMo :: (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    $cgmapMo :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    gmapMp :: (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    $cgmapMp :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    gmapM :: (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    $cgmapM :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2b bitlen -> m (Blake2b bitlen)
    gmapQi :: Int -> (forall d. Data d => d -> u) -> Blake2b bitlen -> u
    $cgmapQi :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2b bitlen -> u
    gmapQ :: (forall d. Data d => d -> u) -> Blake2b bitlen -> [u]
    $cgmapQ :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2b bitlen -> [u]
    gmapQr :: (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    $cgmapQr :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    gmapQl :: (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    $cgmapQl :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2b bitlen -> r
    gmapT :: (forall b. Data b => b -> b) -> Blake2b bitlen -> Blake2b bitlen
    $cgmapT :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2b bitlen -> Blake2b bitlen
    dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2b bitlen))
    $cdataCast2 :: forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2b bitlen))
    dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Blake2b bitlen))
    $cdataCast1 :: forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2b bitlen))
    dataTypeOf :: Blake2b bitlen -> DataType
    $cdataTypeOf :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2b bitlen -> DataType
    toConstr :: Blake2b bitlen -> Constr
    $ctoConstr :: forall (bitlen :: Nat). KnownNat bitlen => Blake2b bitlen -> Constr
    gunfold :: (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2b bitlen)
    $cgunfold :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2b bitlen)
    gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2b bitlen -> c (Blake2b bitlen)
    $cgfoldl :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2b bitlen -> c (Blake2b bitlen)
    $cp1Data :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2b bitlen)
    Data)

    instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512)
          => HashAlgorithm (Blake2b bitlen)
          where
        type HashBlockSize           (Blake2b bitlen) = 128
        type HashDigestSize          (Blake2b bitlen) = Div8 bitlen
        type HashInternalContextSize (Blake2b bitlen) = 248
        hashBlockSize :: Blake2b bitlen -> Int
    hashBlockSize  _          = 128
        hashDigestSize :: Blake2b bitlen -> Int
    hashDigestSize _          = Proxy bitlen -> Int
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    byteLen (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen)
        hashInternalContextSize :: Blake2b bitlen -> Int
    hashInternalContextSize _ = 248
        hashInternalInit :: Ptr (Context (Blake2b bitlen)) -> IO ()
    hashInternalInit p :: Ptr (Context (Blake2b bitlen))
    p        = Ptr (Context (Blake2b bitlen)) -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Word32 -> IO ()
    c_blake2b_init Ptr (Context (Blake2b bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))
        hashInternalUpdate :: Ptr (Context (Blake2b bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    hashInternalUpdate        = Ptr (Context (Blake2b bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    c_blake2b_update
        hashInternalFinalize :: Ptr (Context (Blake2b bitlen))
    -> Ptr (Digest (Blake2b bitlen)) -> IO ()
    hashInternalFinalize p :: Ptr (Context (Blake2b bitlen))
    p    = Ptr (Context (Blake2b bitlen))
    -> Word32 -> Ptr (Digest (Blake2b bitlen)) -> IO ()
    forall a. Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
    c_blake2b_finalize Ptr (Context (Blake2b bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))

    foreign import ccall unsafe "cryptonite_blake2b_init"
        c_blake2b_init :: Ptr (Context a) -> Word32 -> IO ()
    foreign import ccall "cryptonite_blake2b_update"
        c_blake2b_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    foreign import ccall unsafe "cryptonite_blake2b_finalize"
        c_blake2b_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()

    data Blake2sp (bitlen :: Nat) = Blake2sp
        deriving (Int -> Blake2sp bitlen -> ShowS
    [Blake2sp bitlen] -> ShowS
    Blake2sp bitlen -> String
    (Int -> Blake2sp bitlen -> ShowS)
    -> (Blake2sp bitlen -> String)
    -> ([Blake2sp bitlen] -> ShowS)
    -> Show (Blake2sp bitlen)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (bitlen :: Nat). Int -> Blake2sp bitlen -> ShowS
    forall (bitlen :: Nat). [Blake2sp bitlen] -> ShowS
    forall (bitlen :: Nat). Blake2sp bitlen -> String
    showList :: [Blake2sp bitlen] -> ShowS
    $cshowList :: forall (bitlen :: Nat). [Blake2sp bitlen] -> ShowS
    show :: Blake2sp bitlen -> String
    $cshow :: forall (bitlen :: Nat). Blake2sp bitlen -> String
    showsPrec :: Int -> Blake2sp bitlen -> ShowS
    $cshowsPrec :: forall (bitlen :: Nat). Int -> Blake2sp bitlen -> ShowS
    Show,Typeable (Blake2sp bitlen)
    DataType
    Constr
    Typeable (Blake2sp bitlen) =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Blake2sp bitlen -> c (Blake2sp bitlen))
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (Blake2sp bitlen))
    -> (Blake2sp bitlen -> Constr)
    -> (Blake2sp bitlen -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (Blake2sp bitlen)))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (Blake2sp bitlen)))
    -> ((forall b. Data b => b -> b)
        -> Blake2sp bitlen -> Blake2sp bitlen)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> Blake2sp bitlen -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Blake2sp bitlen -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> Blake2sp bitlen -> m (Blake2sp bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2sp bitlen -> m (Blake2sp bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2sp bitlen -> m (Blake2sp bitlen))
    -> Data (Blake2sp bitlen)
    Blake2sp bitlen -> DataType
    Blake2sp bitlen -> Constr
    (forall b. Data b => b -> b) -> Blake2sp bitlen -> Blake2sp bitlen
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2sp bitlen -> c (Blake2sp bitlen)
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2sp bitlen)
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> Blake2sp bitlen -> u
    forall u. (forall d. Data d => d -> u) -> Blake2sp bitlen -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2sp bitlen)
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2sp bitlen -> DataType
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2sp bitlen -> Constr
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2sp bitlen -> Blake2sp bitlen
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2sp bitlen -> u
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2sp bitlen -> [u]
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2sp bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2sp bitlen -> c (Blake2sp bitlen)
    forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2sp bitlen))
    forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2sp bitlen))
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2sp bitlen)
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2sp bitlen -> c (Blake2sp bitlen)
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2sp bitlen))
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2sp bitlen))
    $cBlake2sp :: Constr
    $tBlake2sp :: DataType
    gmapMo :: (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    $cgmapMo :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    gmapMp :: (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    $cgmapMp :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    gmapM :: (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    $cgmapM :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2sp bitlen -> m (Blake2sp bitlen)
    gmapQi :: Int -> (forall d. Data d => d -> u) -> Blake2sp bitlen -> u
    $cgmapQi :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2sp bitlen -> u
    gmapQ :: (forall d. Data d => d -> u) -> Blake2sp bitlen -> [u]
    $cgmapQ :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2sp bitlen -> [u]
    gmapQr :: (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    $cgmapQr :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    gmapQl :: (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    $cgmapQl :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2sp bitlen -> r
    gmapT :: (forall b. Data b => b -> b) -> Blake2sp bitlen -> Blake2sp bitlen
    $cgmapT :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2sp bitlen -> Blake2sp bitlen
    dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2sp bitlen))
    $cdataCast2 :: forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2sp bitlen))
    dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Blake2sp bitlen))
    $cdataCast1 :: forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2sp bitlen))
    dataTypeOf :: Blake2sp bitlen -> DataType
    $cdataTypeOf :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2sp bitlen -> DataType
    toConstr :: Blake2sp bitlen -> Constr
    $ctoConstr :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2sp bitlen -> Constr
    gunfold :: (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2sp bitlen)
    $cgunfold :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2sp bitlen)
    gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2sp bitlen -> c (Blake2sp bitlen)
    $cgfoldl :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2sp bitlen -> c (Blake2sp bitlen)
    $cp1Data :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2sp bitlen)
    Data)

    instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256)
          => HashAlgorithm (Blake2sp bitlen)
          where
        type HashBlockSize           (Blake2sp bitlen) = 64
        type HashDigestSize          (Blake2sp bitlen) = Div8 bitlen
        type HashInternalContextSize (Blake2sp bitlen) = 2185
        hashBlockSize :: Blake2sp bitlen -> Int
    hashBlockSize  _          = 64
        hashDigestSize :: Blake2sp bitlen -> Int
    hashDigestSize _          = Proxy bitlen -> Int
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    byteLen (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen)
        hashInternalContextSize :: Blake2sp bitlen -> Int
    hashInternalContextSize _ = 2185
        hashInternalInit :: Ptr (Context (Blake2sp bitlen)) -> IO ()
    hashInternalInit p :: Ptr (Context (Blake2sp bitlen))
    p        = Ptr (Context (Blake2sp bitlen)) -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Word32 -> IO ()
    c_blake2sp_init Ptr (Context (Blake2sp bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))
        hashInternalUpdate :: Ptr (Context (Blake2sp bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    hashInternalUpdate        = Ptr (Context (Blake2sp bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    c_blake2sp_update
        hashInternalFinalize :: Ptr (Context (Blake2sp bitlen))
    -> Ptr (Digest (Blake2sp bitlen)) -> IO ()
    hashInternalFinalize p :: Ptr (Context (Blake2sp bitlen))
    p    = Ptr (Context (Blake2sp bitlen))
    -> Word32 -> Ptr (Digest (Blake2sp bitlen)) -> IO ()
    forall a. Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
    c_blake2sp_finalize Ptr (Context (Blake2sp bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))

    foreign import ccall unsafe "cryptonite_blake2sp_init"
        c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO ()
    foreign import ccall "cryptonite_blake2sp_update"
        c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    foreign import ccall unsafe "cryptonite_blake2sp_finalize"
        c_blake2sp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()

    data Blake2bp (bitlen :: Nat) = Blake2bp
        deriving (Int -> Blake2bp bitlen -> ShowS
    [Blake2bp bitlen] -> ShowS
    Blake2bp bitlen -> String
    (Int -> Blake2bp bitlen -> ShowS)
    -> (Blake2bp bitlen -> String)
    -> ([Blake2bp bitlen] -> ShowS)
    -> Show (Blake2bp bitlen)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (bitlen :: Nat). Int -> Blake2bp bitlen -> ShowS
    forall (bitlen :: Nat). [Blake2bp bitlen] -> ShowS
    forall (bitlen :: Nat). Blake2bp bitlen -> String
    showList :: [Blake2bp bitlen] -> ShowS
    $cshowList :: forall (bitlen :: Nat). [Blake2bp bitlen] -> ShowS
    show :: Blake2bp bitlen -> String
    $cshow :: forall (bitlen :: Nat). Blake2bp bitlen -> String
    showsPrec :: Int -> Blake2bp bitlen -> ShowS
    $cshowsPrec :: forall (bitlen :: Nat). Int -> Blake2bp bitlen -> ShowS
    Show,Typeable (Blake2bp bitlen)
    DataType
    Constr
    Typeable (Blake2bp bitlen) =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Blake2bp bitlen -> c (Blake2bp bitlen))
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c (Blake2bp bitlen))
    -> (Blake2bp bitlen -> Constr)
    -> (Blake2bp bitlen -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c (Blake2bp bitlen)))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e))
        -> Maybe (c (Blake2bp bitlen)))
    -> ((forall b. Data b => b -> b)
        -> Blake2bp bitlen -> Blake2bp bitlen)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r)
    -> (forall u.
        (forall d. Data d => d -> u) -> Blake2bp bitlen -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Blake2bp bitlen -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d)
        -> Blake2bp bitlen -> m (Blake2bp bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2bp bitlen -> m (Blake2bp bitlen))
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d)
        -> Blake2bp bitlen -> m (Blake2bp bitlen))
    -> Data (Blake2bp bitlen)
    Blake2bp bitlen -> DataType
    Blake2bp bitlen -> Constr
    (forall b. Data b => b -> b) -> Blake2bp bitlen -> Blake2bp bitlen
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2bp bitlen -> c (Blake2bp bitlen)
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2bp bitlen)
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u.
    Int -> (forall d. Data d => d -> u) -> Blake2bp bitlen -> u
    forall u. (forall d. Data d => d -> u) -> Blake2bp bitlen -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2bp bitlen)
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2bp bitlen -> DataType
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2bp bitlen -> Constr
    forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2bp bitlen -> Blake2bp bitlen
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2bp bitlen -> u
    forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2bp bitlen -> [u]
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2bp bitlen)
    forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2bp bitlen -> c (Blake2bp bitlen)
    forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2bp bitlen))
    forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2bp bitlen))
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2bp bitlen)
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2bp bitlen -> c (Blake2bp bitlen)
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2bp bitlen))
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2bp bitlen))
    $cBlake2bp :: Constr
    $tBlake2bp :: DataType
    gmapMo :: (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    $cgmapMo :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    gmapMp :: (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    $cgmapMp :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, MonadPlus m) =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    gmapM :: (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    $cgmapM :: forall (bitlen :: Nat) (m :: * -> *).
    (KnownNat bitlen, Monad m) =>
    (forall d. Data d => d -> m d)
    -> Blake2bp bitlen -> m (Blake2bp bitlen)
    gmapQi :: Int -> (forall d. Data d => d -> u) -> Blake2bp bitlen -> u
    $cgmapQi :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    Int -> (forall d. Data d => d -> u) -> Blake2bp bitlen -> u
    gmapQ :: (forall d. Data d => d -> u) -> Blake2bp bitlen -> [u]
    $cgmapQ :: forall (bitlen :: Nat) u.
    KnownNat bitlen =>
    (forall d. Data d => d -> u) -> Blake2bp bitlen -> [u]
    gmapQr :: (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    $cgmapQr :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    gmapQl :: (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    $cgmapQl :: forall (bitlen :: Nat) r r'.
    KnownNat bitlen =>
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Blake2bp bitlen -> r
    gmapT :: (forall b. Data b => b -> b) -> Blake2bp bitlen -> Blake2bp bitlen
    $cgmapT :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    (forall b. Data b => b -> b) -> Blake2bp bitlen -> Blake2bp bitlen
    dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2bp bitlen))
    $cdataCast2 :: forall (bitlen :: Nat) (t :: * -> * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (Blake2bp bitlen))
    dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Blake2bp bitlen))
    $cdataCast1 :: forall (bitlen :: Nat) (t :: * -> *) (c :: * -> *).
    (KnownNat bitlen, Typeable t) =>
    (forall d. Data d => c (t d)) -> Maybe (c (Blake2bp bitlen))
    dataTypeOf :: Blake2bp bitlen -> DataType
    $cdataTypeOf :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2bp bitlen -> DataType
    toConstr :: Blake2bp bitlen -> Constr
    $ctoConstr :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Blake2bp bitlen -> Constr
    gunfold :: (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2bp bitlen)
    $cgunfold :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (Blake2bp bitlen)
    gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2bp bitlen -> c (Blake2bp bitlen)
    $cgfoldl :: forall (bitlen :: Nat) (c :: * -> *).
    KnownNat bitlen =>
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Blake2bp bitlen -> c (Blake2bp bitlen)
    $cp1Data :: forall (bitlen :: Nat).
    KnownNat bitlen =>
    Typeable (Blake2bp bitlen)
    Data)

    instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512)
          => HashAlgorithm (Blake2bp bitlen)
          where
        type HashBlockSize           (Blake2bp bitlen) = 128
        type HashDigestSize          (Blake2bp bitlen) = Div8 bitlen
        type HashInternalContextSize (Blake2bp bitlen) = 2325
        hashBlockSize :: Blake2bp bitlen -> Int
    hashBlockSize  _          = 128
        hashDigestSize :: Blake2bp bitlen -> Int
    hashDigestSize _          = Proxy bitlen -> Int
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    byteLen (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen)
        hashInternalContextSize :: Blake2bp bitlen -> Int
    hashInternalContextSize _ = 2325
        hashInternalInit :: Ptr (Context (Blake2bp bitlen)) -> IO ()
    hashInternalInit p :: Ptr (Context (Blake2bp bitlen))
    p        = Ptr (Context (Blake2bp bitlen)) -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Word32 -> IO ()
    c_blake2bp_init Ptr (Context (Blake2bp bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))
        hashInternalUpdate :: Ptr (Context (Blake2bp bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    hashInternalUpdate        = Ptr (Context (Blake2bp bitlen)) -> Ptr Word8 -> Word32 -> IO ()
    forall a. Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    c_blake2bp_update
        hashInternalFinalize :: Ptr (Context (Blake2bp bitlen))
    -> Ptr (Digest (Blake2bp bitlen)) -> IO ()
    hashInternalFinalize p :: Ptr (Context (Blake2bp bitlen))
    p    = Ptr (Context (Blake2bp bitlen))
    -> Word32 -> Ptr (Digest (Blake2bp bitlen)) -> IO ()
    forall a. Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()
    c_blake2bp_finalize Ptr (Context (Blake2bp bitlen))
    p (Proxy bitlen -> Word32
    forall (bitlen :: Nat) a (proxy :: Nat -> *).
    (KnownNat bitlen, Num a) =>
    proxy bitlen -> a
    integralNatVal (Proxy bitlen
    forall k (t :: k). Proxy t
    Proxy :: Proxy bitlen))

    foreign import ccall unsafe "cryptonite_blake2bp_init"
        c_blake2bp_init :: Ptr (Context a) -> Word32 -> IO ()
    foreign import ccall "cryptonite_blake2bp_update"
        c_blake2bp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO ()
    foreign import ccall unsafe "cryptonite_blake2bp_finalize"
        c_blake2bp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO ()