raaz-0.3.11: core/Raaz/Primitive/HashMemory.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-- |
--
-- Module : Raaz.Primitive.HashMemory
-- Description : Memory elements for typical hashes.
-- Copyright : (c) Piyush P Kurur, 2019
-- License : Apache-2.0 OR BSD-3-Clause
-- Maintainer : Piyush P Kurur <ppk@iitpkd.ac.in>
-- Stability : experimental
--
module Raaz.Primitive.HashMemory
( HashMemory128, HashMemory64
, hashCellPointer, hashCell128Pointer
, lengthCellPointer, uLengthCellPointer, lLengthCellPointer
, getLength, getULength, getLLength
, updateLength, updateLength128
) where
import Foreign.Storable ( Storable(..) )
import Raaz.Core
-- | Similar to `HashMemory128` but keeps track of length as a 64-bit quantity.
data HashMemory64 h = HashMemory64 { hashCell :: MemoryCell h
, lengthCell :: MemoryCell (BYTES Word64)
}
-- | Memory element that keeps track of a hash and the total bytes
-- processed (as a 128 bit quantity). Such a memory element is useful
-- for building the memory element for cryptographic hashes.
data HashMemory128 h = HashMemory128 { hashCell128 :: MemoryCell h
, uLengthCell :: MemoryCell (BYTES Word64)
, lLengthCell :: MemoryCell (BYTES Word64)
}
-- | Get the length.
getLength :: HashMemory64 h -> IO (BYTES Word64)
getLength = extract . lengthCell
-- | Get the higher order 64-bits.
getULength :: HashMemory128 h -> IO (BYTES Word64)
getULength = extract . uLengthCell
-- | Get the lower order 64-bits
getLLength :: HashMemory128 h -> IO (BYTES Word64)
getLLength = extract . lLengthCell
-- | Get the pointer to the hash.
hashCellPointer :: Storable h
=> HashMemory64 h
-> Ptr h
hashCellPointer = unsafeGetCellPointer . hashCell
-- | Get the pointer to the array which stores the digest
hashCell128Pointer :: Storable h
=> HashMemory128 h
-> Ptr h
hashCell128Pointer = unsafeGetCellPointer . hashCell128
-- | Get the pointer to upper half of the length bytes.
lengthCellPointer :: Storable h
=> HashMemory64 h
-> Ptr (BYTES Word64)
lengthCellPointer = unsafeGetCellPointer . lengthCell
-- | Get the pointer to upper half of the length bytes.
uLengthCellPointer :: Storable h
=> HashMemory128 h
-> Ptr (BYTES Word64)
uLengthCellPointer = unsafeGetCellPointer . uLengthCell
-- | Get the pointer to the lower half of the length bytes.
lLengthCellPointer :: Storable h
=> HashMemory128 h
-> Ptr (BYTES Word64)
lLengthCellPointer = unsafeGetCellPointer . lLengthCell
-- | Update the 128 bit length stored in the hash memory.
updateLength128 :: LengthUnit len
=> len
-> HashMemory128 h
-> IO ()
updateLength128 len hmem =
do l <- getLLength hmem
initialise (l + lenBytes) $ lLengthCell hmem
when (l > maxBound - lenBytes) $
modifyMem (+(1 :: BYTES Word64)) $ uLengthCell hmem
where lenBytes = fromIntegral $ inBytes len
-- | Update the 64-bit length stored in the hash memory.
updateLength :: LengthUnit len
=> len
-> HashMemory64 h
-> IO ()
updateLength len = modifyMem (+lenBytes) . lengthCell
where lenBytes = fromIntegral $ inBytes len :: BYTES Word64
instance Storable h => Memory (HashMemory128 h) where
memoryAlloc = HashMemory128 <$> memoryAlloc <*> memoryAlloc <*> memoryAlloc
unsafeToPointer = unsafeToPointer . hashCell128
instance Storable h => Memory (HashMemory64 h) where
memoryAlloc = HashMemory64 <$> memoryAlloc <*> memoryAlloc
unsafeToPointer = unsafeToPointer . hashCell
instance Storable h => Initialisable (HashMemory128 h) h where
initialise h hmem = do initialise h $ hashCell128 hmem
initialise (0 :: BYTES Word64) $ uLengthCell hmem
initialise (0 :: BYTES Word64) $ lLengthCell hmem
instance Storable h => Initialisable (HashMemory64 h) h where
initialise h hmem = do initialise h $ hashCell hmem
initialise (0 :: BYTES Word64) $ lengthCell hmem
instance Storable h => Extractable (HashMemory128 h) h where
extract = extract . hashCell128
instance Storable h => Extractable (HashMemory64 h) h where
extract = extract . hashCell