{-# LANGUAGE ForeignFunctionInterface   #-}
{-# LANGUAGE DataKinds                  #-}

-- | The portable C-implementation of Sha256.
module Sha256.CHandWritten
       ( name, description
       , Prim, Internals, BufferAlignment
       , BufferPtr
       , additionalBlocks
       , processBlocks
       , processLast
       ) where

import Raaz.Core
import Raaz.Core.Types.Internal
import Raaz.Primitive.HashMemory
import Raaz.Primitive.Sha2.Internal (Sha256, Sha256Mem, process256Last)

name :: String
name :: String
name = String
"sha256-c-handwritten"

description :: String
description :: String
description = String
"Hand written Sha256 Implementation using portable C and Haskell FFI"

type Prim                    = Sha256
type Internals               = Sha256Mem
type BufferAlignment         = 32
type BufferPtr               = AlignedBlockPtr BufferAlignment Prim

additionalBlocks :: BlockCount Sha256
additionalBlocks :: BlockCount Sha256
additionalBlocks = Int -> Proxy Sha256 -> BlockCount Sha256
forall p. Int -> Proxy p -> BlockCount p
blocksOf Int
1 Proxy Sha256
forall k (t :: k). Proxy t
Proxy

------------------------ The foreign function calls  ---------------------

foreign import ccall unsafe
  "raaz/hash/sha256/portable.h raazHashSha256PortableCompress"
   c_sha256_compress  :: BufferPtr
                      -> BlockCount Sha256
                      -> Ptr Sha256
                      -> IO ()


compressBlocks :: BufferPtr
               -> BlockCount Sha256
               -> Internals
               -> IO ()
compressBlocks :: BufferPtr -> BlockCount Sha256 -> Internals -> IO ()
compressBlocks BufferPtr
buf BlockCount Sha256
blks = BufferPtr -> BlockCount Sha256 -> Ptr Sha256 -> IO ()
c_sha256_compress BufferPtr
buf BlockCount Sha256
blks (Ptr Sha256 -> IO ())
-> (Internals -> Ptr Sha256) -> Internals -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Internals -> Ptr Sha256
forall h. Storable h => HashMemory64 h -> Ptr h
hashCellPointer


processBlocks :: BufferPtr
              -> BlockCount Sha256
              -> Internals
              -> IO ()
processBlocks :: BufferPtr -> BlockCount Sha256 -> Internals -> IO ()
processBlocks BufferPtr
buf BlockCount Sha256
blks Internals
mem = BufferPtr -> BlockCount Sha256 -> Internals -> IO ()
compressBlocks BufferPtr
buf BlockCount Sha256
blks Internals
mem IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> BlockCount Sha256 -> Internals -> IO ()
forall len h. LengthUnit len => len -> HashMemory64 h -> IO ()
updateLength BlockCount Sha256
blks Internals
mem

-- | Process the last bytes.
processLast :: BufferPtr
            -> BYTES Int
            -> Internals
            -> IO ()
processLast :: BufferPtr -> BYTES Int -> Internals -> IO ()
processLast = (BufferPtr -> BlockCount Sha256 -> Internals -> IO ())
-> BufferPtr -> BYTES Int -> Internals -> IO ()
forall (n :: Nat).
KnownNat n =>
Compressor256 n
-> AlignedBlockPtr n Sha256 -> BYTES Int -> Internals -> IO ()
process256Last BufferPtr -> BlockCount Sha256 -> Internals -> IO ()
processBlocks