@@ -0,0 +1,72 @@
1+module Data.Hash
2+
3+%access public
4+%default partial
5+
6+||| A type that can be hashed
7+class Hashable a where
8+ saltedHash64 : a -> Bits64 -> Bits64 -- value to hash, salt, hash
9+
10+||| Computes a hash
11+hash : Hashable a => a -> Bits64
12+hash x = saltedHash64 x 0x16fc397cf62f64d3
13+
14+||| Given a user provided salt, Computes a hash
15+saltedHash : Hashable a => Bits64 -> a -> Bits64
16+saltedHash salt x = saltedHash64 x salt
17+
18+
19+||| Nth byte of a Bits64
20+private
21+byte : Bits64 -> Bits64 -> Bits64
22+byte n w = prim__lshrB64 (prim__andB64 mask w) offset
23+ where offset = 8*n
24+ mask = prim__shlB64 0xff (the Bits64 offset)
25+
26+instance Hashable Bits64 where
27+ saltedHash64 w salt = foldr (\b,acc => (acc `prim__shlB64` 10) + acc + b)
28+ salt
29+ [byte (fromInteger n) w | n <- [7,6..0]] -- djb2 hash function. Not meant for crypto
30+
31+instance Hashable Integer where
32+ saltedHash64 i = saltedHash64 (mod64 i)
33+ where mod64 : Integer -> Bits64
34+ mod64 i = fromInteger (abs i `mod` 0xffffffffffffffff)
35+
36+instance Hashable () where
37+ saltedHash64 _ salt = salt
38+
39+instance Hashable Bool where
40+ saltedHash64 True = saltedHash64 (the Bits64 1)
41+ saltedHash64 False = saltedHash64 (the Bits64 0)
42+
43+instance Hashable Int where
44+ saltedHash64 w = saltedHash64 (prim__zextInt_B64 w)
45+
46+instance Hashable Char where
47+ saltedHash64 w = saltedHash64 (the Int (cast w))
48+
49+instance Hashable Bits8 where
50+ saltedHash64 w = saltedHash64 (prim__zextB8_B64 w)
51+
52+instance Hashable Bits16 where
53+ saltedHash64 w = saltedHash64 (prim__zextB16_B64 w)
54+
55+instance Hashable Bits32 where
56+ saltedHash64 w = saltedHash64 (prim__zextB32_B64 w)
57+
58+instance Hashable a => Hashable (Maybe a) where
59+ saltedHash64 Nothing salt = salt
60+ saltedHash64 (Just k) salt = saltedHash64 k salt
61+
62+instance (Hashable a, Hashable b) => Hashable (a, b) where
63+ saltedHash64 (a,b) salt = saltedHash64 b (saltedHash64 a salt)
64+
65+instance Hashable a => Hashable (List a) where
66+ saltedHash64 l salt = foldr (\c,acc => saltedHash64 c acc) salt l
67+
68+instance Hashable a => Hashable (Vect n a) where
69+ saltedHash64 l salt = foldr (\c,acc => saltedHash64 c acc) salt l
70+
71+instance Hashable String where
72+ saltedHash64 s = saltedHash64 (unpack s)