raaz-0.3.0: implementation/Blake2b/CHandWritten.hs
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE DataKinds #-}
-- | The portable C-implementation of Blake2b.
module Blake2b.CHandWritten where
import Raaz.Core
import Raaz.Core.Transfer.Unsafe
import Raaz.Core.Types.Internal
import Raaz.Primitive.HashMemory
import Raaz.Primitive.Blake2.Internal
name :: String
name = "blake2b-c-handwritten"
description :: String
description = "Hand written Blake2b Implementation in portable C and Haskell FFI"
type Prim = Blake2b
type Internals = Blake2bMem
type BufferAlignment = 32
type BufferPtr = AlignedBlockPtr BufferAlignment Prim
additionalBlocks :: BlockCount Blake2b
additionalBlocks = blocksOf 1 Proxy
------------------------ The foreign function calls ---------------------
foreign import ccall unsafe
"raaz/hash/blake2/common.h raazHashBlake2bPortableBlockCompress"
c_blake2b_compress :: BufferPtr
-> BlockCount Prim
-> Ptr (BYTES Word64)
-> Ptr (BYTES Word64)
-> Ptr Blake2b
-> IO ()
foreign import ccall unsafe
"raaz/hash/blake2/common.h raazHashBlake2bPortableLastBlock"
c_blake2b_last :: BlockPtr Prim
-> BYTES Int
-> BYTES Word64
-> BYTES Word64
-> Word64
-> Word64
-> Ptr Blake2b
-> IO ()
--
processBlocks :: BufferPtr
-> BlockCount Blake2b
-> Blake2bMem
-> IO ()
processBlocks buf blks b2bmem =
let uPtr = uLengthCellPointer b2bmem
lPtr = lLengthCellPointer b2bmem
hshPtr = hashCell128Pointer b2bmem
in c_blake2b_compress buf blks uPtr lPtr hshPtr
-- | Process the last bytes.
processLast :: BufferPtr
-> BYTES Int
-> Blake2bMem
-> IO ()
processLast buf nbytes b2bmem = do
unsafeTransfer padding buf -- pad the message
processBlocks buf nBlocks b2bmem -- process all but the last block
--
-- Handle the last block
--
let
hshPtr = hashCell128Pointer b2bmem
in do u <- getULength b2bmem
l <- getLLength b2bmem
c_blake2b_last lastBlockPtr remBytes u l f0 f1 hshPtr
where padding = blake2Pad (Proxy :: Proxy Blake2b) nbytes
nBlocks = atMost (transferSize padding) `mappend` toEnum (-1)
-- all but the last block
remBytes = nbytes - inBytes nBlocks
-- Actual bytes in the last block.
lastBlockPtr = forgetAlignment buf `movePtr` nBlocks
--
-- Finalisation FLAGS
--
f0 = complement 0
f1 = 0