File: Hasher.hs

package info (click to toggle)
haskell-foundation 0.0.30-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 932 kB
  • sloc: haskell: 9,124; ansic: 570; makefile: 7
file content (64 lines) | stat: -rw-r--r-- 2,222 bytes parent folder | download | duplicates (4)
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)