1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
module Foundation.Hashing.Hasher
( Hasher(..)
) where
import Basement.Compat.Base
import Basement.IntegralConv
import Foundation.Array (UArray)
import qualified Basement.UArray as A
import Data.Bits
-- | Incremental Hashing state. Represent an hashing algorithm
--
-- the base primitive of this class is `hashMix8`, append
-- mix a Word8 in the state
--
-- The class allow to define faster mixing function that works on
-- bigger Word size and any unboxed array of any PrimType elements
class Hasher st where
{-# MINIMAL hashNew, hashNewParam, hashMix8, hashEnd #-}
-- | Associate type when finalizing the state with 'hashEnd'
type HashResult st
-- | Associate type when initializing the state (e.g. a Key or seed)
type HashInitParam st
-- | Create a new Hashing context
hashNew :: st
-- | Create a new Hashing context
hashNewParam :: HashInitParam st -> st
-- | Finalize the state and returns the hash result
hashEnd :: st -> HashResult st
-- | Mix a Word8 (Byte) into the state and return the new state
hashMix8 :: Word8 -> st -> st
-- | Mix a Word16 into the state and return the new state
hashMix16 :: Word16 -> st -> st
hashMix16 w st = hashMix8 w2 $ hashMix8 w1 st
where
!w1 = integralDownsize (w `unsafeShiftR` 8)
!w2 = integralDownsize w
-- | Mix a Word32 into the state and return the new state
hashMix32 :: Word32 -> st -> st
hashMix32 w st = hashMix8 w4 $ hashMix8 w3 $ hashMix8 w2 $ hashMix8 w1 st
where
!w1 = integralDownsize (w `unsafeShiftR` 24)
!w2 = integralDownsize (w `unsafeShiftR` 16)
!w3 = integralDownsize (w `unsafeShiftR` 8)
!w4 = integralDownsize w
-- | Mix a Word64 into the state and return the new state
hashMix64 :: Word64 -> st -> st
hashMix64 w st = hashMix32 w2 $ hashMix32 w1 st
where
!w1 = integralDownsize (w `unsafeShiftR` 32)
!w2 = integralDownsize w
-- | Mix an arbitrary sized unboxed array and return the new state
hashMixBytes :: A.PrimType e => UArray e -> st -> st
hashMixBytes ba st = A.foldl' (flip hashMix8) st (A.unsafeRecast ba)
|