{-# 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