3 | module Data.Hashable.SipHashV2
17 | record HashState where
24 | initHashState : HashState
25 | initHashState = MkST
26 | { v0 = 0x736f6d6570736575
27 | , v1 = 0x646f72616e646f6d
28 | , v2 = 0x6c7967656e657261
29 | , v3 = 0x7465646279746573
32 | record PartialHash where
33 | constructor MkPartial
39 | initPartial : PartialHash
40 | initPartial = MkPartial 0 0 0 initHashState
43 | shl : Bits64 -> Bits64 -> Bits64
44 | shl = prim__shl_Bits64
47 | shr : Bits64 -> Bits64 -> Bits64
48 | shr = prim__shr_Bits64
51 | bor : Bits64 -> Bits64 -> Bits64
52 | bor = prim__or_Bits64
55 | xor : Bits64 -> Bits64 -> Bits64
56 | xor = prim__xor_Bits64
59 | and : Bits64 -> Bits64 -> Bits64
60 | and = prim__and_Bits64
63 | shr16 : Bits16 -> Bits16 -> Bits16
64 | shr16 = prim__shr_Bits16
67 | shr32 : Bits32 -> Bits32 -> Bits32
68 | shr32 = prim__shr_Bits32
71 | andInt : Int -> Int -> Int
72 | andInt = prim__and_Int
76 | rotl : Bits64 -> (b : Bits64) -> Bits64
77 | rotl x b = (x `shl` b) `bor` (x `shr` (64 - b))
81 | fullSize : Int -> Int
83 | let left = x `andInt` 7
84 | in if (x `andInt` 7) == 0
88 | compress : HashState -> HashState
89 | compress (MkST v0 v1 v2 v3) =
104 | in MkST v0 v1 v2 v3
108 | repeat : (rounds : Nat) -> (f : a -> a) -> a -> a
110 | repeat (S k) f x = repeat k f (f x)
113 | hashBits64 : HashState -> Bits64 -> HashState
114 | hashBits64 (MkST v0 v1 v2 v3) m =
115 | let v3 = v3 `xor` m
116 | MkST v0 v1 v2 v3 = repeat CROUNDS compress $
MkST v0 v1 v2 v3
118 | in MkST v0 v1 v2 v3
121 | finish : PartialHash -> Bits64
122 | finish (MkPartial tail index length hst) =
123 | let MkST v0 v1 v2 v3 = hst
124 | rest = ((length `and` 0xff) `shl` 56) `bor` tail
126 | MkST v0 v1 v2 v3 = repeat CROUNDS compress $
MkST v0 v1 v2 v3
129 | MkST v0 v1 v2 v3 = repeat DROUNDS compress $
MkST v0 v1 v2 v3
130 | in (v0 `xor` v1) `xor` (v2 `xor` v3)
133 | addBits8 : PartialHash -> Bits8 -> PartialHash
134 | addBits8 (MkPartial tail index len hs) x = case index of
136 | 56 => MkPartial 0 0 (len + 1) $
hashBits64 hs (tail `bor` (cast x `shl` 56))
138 | _ => MkPartial (tail `bor` (cast x `shl` index)) (index + 8) (len + 1) hs
141 | addBits16 : PartialHash -> Bits16 -> PartialHash
142 | addBits16 ph x = addBits8 (addBits8 ph $
cast x) (cast $
x `shr16` 8)
145 | addBits32 : PartialHash -> Bits32 -> PartialHash
146 | addBits32 ph x = addBits16 (addBits16 ph $
cast x) (cast $
x `shr32` 16)
149 | addBits64 : PartialHash -> Bits64 -> PartialHash
150 | addBits64 (MkPartial tail index length hst) x = MkPartial tail index (length + 8) $
hashBits64 hst x
152 | hashBuffer' : PartialHash -> Buffer -> Int -> Int -> IO PartialHash
153 | hashBuffer' ph buf len idx = if idx >= len
156 | word <- getBits64 buf idx
157 | let ph = addBits64 ph word
158 | hashBuffer' ph buf len (assert_smaller idx $
idx + 8)
160 | hashBuffer : PartialHash -> Buffer -> IO PartialHash
161 | hashBuffer ph buf = do
162 | rawLen <- rawSize buf
163 | let len = fullSize rawLen
164 | Just buf' <- resizeBuffer buf len
165 | | Nothing => hashBuffer' ph buf (rawLen `andInt` (-
7)) 0
166 | hashBuffer' ph buf' len 0