2 | module Data.Hashable.SipHash
25 | shl : Bits64 -> Bits64 -> Bits64
26 | shl = prim__shl_Bits64
29 | shr : Bits64 -> Bits64 -> Bits64
30 | shr = prim__shr_Bits64
33 | bor : Bits64 -> Bits64 -> Bits64
34 | bor = prim__or_Bits64
37 | xor : Bits64 -> Bits64 -> Bits64
38 | xor = prim__xor_Bits64
41 | and : Int -> Int -> Int
46 | rotl : Bits64 -> (b : Bits64) -> Bits64
47 | rotl x b = (x `shl` b) `bor` (x `shr` (64 - b))
51 | fullSize : Int -> Int
53 | let left = x `prim__and_Int` 7
54 | in if (x `prim__and_Int` 7) == 0
59 | compress : IORef State -> IO ()
61 | MkState v0 v1 v2 v3 <- readIORef stref
76 | writeIORef stref $
MkState v0 v1 v2 v3
80 | siphashInit : IO (IORef State)
81 | siphashInit = newIORef $
MkState
82 | { v0 = 0x736f6d6570736575
83 | , v1 = 0x646f72616e646f6d
84 | , v2 = 0x6c7967656e657261
85 | , v3 = 0x7465646279746573
90 | repeat : (count : Nat) -> IO () -> IO ()
91 | repeat Z _ = pure ()
92 | repeat (S k) act = act >> repeat k act
94 | siphashLoop : IORef State -> Buffer -> Int -> Int -> IO ()
95 | siphashLoop stref buf idx len = if idx >= len
98 | m <- getBits64 buf idx
99 | repeat CROUNDS $
compress stref
100 | siphashLoop stref buf (assert_smaller idx $
idx + 8) len
103 | siphashLeftover : IORef State -> Buffer -> Int -> Int -> Int -> IO Bits64
104 | siphashLeftover stref buf size left idx = do
105 | x <- getBits64 buf idx
106 | pure $
x `bor` (cast size `shl` 56)
108 | siphash : Buffer -> IO Bits64
110 | stref <- siphashInit
111 | size <- fullSize <$> rawSize buf
112 | siphashLoop stref buf 0 size
113 | let left = size `and` 7
114 | b <- siphashLeftover stref buf size (size - left) left
115 | modifyIORef stref $
{ v3 $= (`xor` b) }
116 | repeat DROUNDS $
compress stref
117 | modifyIORef stref $
{ v0 $= (`xor` b) }
118 | MkState v0 v1 v2 v3 <- readIORef stref
119 | pure $
(v0 `xor` v1) `xor` (v2 `xor` v3)
122 | siphashString : String -> Bits64
123 | siphashString str = unsafePerformIO $
do
124 | Just buf <- newBuffer $
fullSize $
stringByteLength str
125 | | Nothing => assert_total $
idris_crash "Error allocating buffer"
126 | setString buf 0 str