    {-# LANGUAGE ForeignFunctionInterface   #-}
    -- | The portable C-implementation of SHA1
    module Raaz.Hash.Blake2.Implementation.CPortable
           ( implementation2b
           , implementation2s
           ) where

    import Foreign.Ptr              ( Ptr )
    import Data.Word
    import Raaz.Core
    import Raaz.Hash.Internal
    import Raaz.Hash.Blake2.Internal

    -- | The portable C implementation of BLAKE2b.
    implementation2b :: Implementation BLAKE2b
    implementation2b :: Implementation BLAKE2b
    implementation2b =  HashI BLAKE2b Blake2bMem -> SomeHashI BLAKE2b
    forall h m. HashM h m => HashI h m -> SomeHashI h
    SomeHashI HashI BLAKE2b Blake2bMem
    cPortable2b

    -- | The portable C implementation of BLAKE2s.
    implementation2s :: Implementation BLAKE2s
    implementation2s :: Implementation BLAKE2s
    implementation2s =  HashI BLAKE2s Blake2sMem -> SomeHashI BLAKE2s
    forall h m. HashM h m => HashI h m -> SomeHashI h
    SomeHashI HashI BLAKE2s Blake2sMem
    cPortable2s

    cPortable2b :: HashI BLAKE2b Blake2bMem
    cPortable2b :: HashI BLAKE2b Blake2bMem
    cPortable2b = String
    -> String -> Compress2b -> Last2b -> HashI BLAKE2b Blake2bMem
    blake2bImplementation
                  "blake2b-cportable"
                  "BLAKE2b Implementation using portable C and Haskell FFI"
                  Compress2b
    forall a.
    Enum a =>
    Pointer
    -> a
    -> Ptr (BYTES Word64)
    -> Ptr (BYTES Word64)
    -> Ptr BLAKE2b
    -> IO ()
    compressIt
                  Last2b
    c_blake2b_last
      where compressIt :: Pointer
    -> a
    -> Ptr (BYTES Word64)
    -> Ptr (BYTES Word64)
    -> Ptr BLAKE2b
    -> IO ()
    compressIt ptr :: Pointer
    ptr = Pointer
    -> Int
    -> Ptr (BYTES Word64)
    -> Ptr (BYTES Word64)
    -> Ptr BLAKE2b
    -> IO ()
    c_blake2b_compress Pointer
    ptr (Int
     -> Ptr (BYTES Word64)
     -> Ptr (BYTES Word64)
     -> Ptr BLAKE2b
     -> IO ())
    -> (a -> Int)
    -> a
    -> Ptr (BYTES Word64)
    -> Ptr (BYTES Word64)
    -> Ptr BLAKE2b
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Int
    forall a. Enum a => a -> Int
    fromEnum

    cPortable2s :: HashI BLAKE2s Blake2sMem
    cPortable2s :: HashI BLAKE2s Blake2sMem
    cPortable2s = String
    -> String -> Compress2s -> Last2s -> HashI BLAKE2s Blake2sMem
    blake2sImplementation
                  "blake2s-cportable"
                  "BLAKE2s Implementation using portable C and Haskell FFI"
                  Compress2s
    forall a.
    Enum a =>
    Pointer -> a -> BYTES Word64 -> Ptr BLAKE2s -> IO ()
    compressIt
                  Last2s
    c_blake2s_last
      where compressIt :: Pointer -> a -> BYTES Word64 -> Ptr BLAKE2s -> IO ()
    compressIt ptr :: Pointer
    ptr = Pointer -> Int -> BYTES Word64 -> Ptr BLAKE2s -> IO ()
    c_blake2s_compress Pointer
    ptr (Int -> BYTES Word64 -> Ptr BLAKE2s -> IO ())
    -> (a -> Int) -> a -> BYTES Word64 -> Ptr BLAKE2s -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Int
    forall a. Enum a => a -> Int
    fromEnum

    ------------------------- FFI For Blake2b -------------------------------------

    foreign import ccall unsafe
      "raaz/hash/blake2/common.h raazHashBlake2bPortableBlockCompress"
      c_blake2b_compress  :: Pointer
                          -> Int
                          -> Ptr (BYTES Word64)
                          -> Ptr (BYTES Word64)
                          -> Ptr BLAKE2b
                          -> IO ()

    foreign import ccall unsafe
      "raaz/hash/blake2/common.h raazHashBlake2bPortableLastBlock"
      c_blake2b_last   :: Pointer
                       -> BYTES Int
                       -> BYTES Word64
                       -> BYTES Word64
                       -> Word64
                       -> Word64
                       -> Ptr BLAKE2b
                       -> IO ()

    ------------------------- FFI For Blake2s -------------------------------------

    foreign import ccall unsafe
      "raaz/hash/blake2/common.h raazHashBlake2sPortableBlockCompress"
      c_blake2s_compress  :: Pointer
                          -> Int
                          -> BYTES Word64
                          -> Ptr BLAKE2s
                          -> IO ()

    foreign import ccall unsafe
      "raaz/hash/blake2/common.h raazHashBlake2sPortableLastBlock"
      c_blake2s_last   :: Pointer
                       -> BYTES Int
                       -> BYTES Word64
                       -> Word32
                       -> Word32
                       -> Ptr BLAKE2s
                       -> IO ()

    {-

    void raazHashBlake2bPortableBlockCompress( Block2b *mesg, int nblocks,
    					   Word2b *Upper, Word2b *Lower,
    					   Blake2b h)

    void raazHashBlake2bPortableLastBlock( Block2b mesg, int nbytes,
    				       Word2b upper, Word2b lower,
    				       Word2b f0 , Word2b f1,
    				       Blake2b h)
    -}