-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHash.fs
59 lines (41 loc) · 1.24 KB
/
Hash.fs
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
module Hash
open Org.BouncyCastle.Crypto.Digests
[<Literal>]
let Length = 32
type Hash =
| Hash of byte []
override x.ToString() =
let (Hash bytes) = x
Base16.encode bytes
member x.AsString = x.ToString()
let zero = Hash(Array.zeroCreate Length)
let compute bytes =
let hash = Array.zeroCreate Length
let sha3 = Sha3Digest(256)
sha3.BlockUpdate(bytes, 0, Array.length bytes)
sha3.DoFinal(hash, 0) |> ignore
Hash hash
let computeOfHash (Hash bytes) = compute bytes
let computeMultiple (bytes: byte array seq) =
let hash = Array.zeroCreate Length
let sha3 = Sha3Digest(256)
Seq.iter (fun bytes -> sha3.BlockUpdate(bytes,0,Array.length bytes)) bytes
sha3.DoFinal(hash, 0) |> ignore
Hash hash
let bytes (Hash hash) = hash
let joinHashes : Hash seq -> _ =
Seq.map bytes
>> computeMultiple
let fromBytes bytes =
match Array.length bytes with
| Length -> Some (Hash bytes)
| _ -> None
let toString (h:Hash) =
h.ToString()
let fromString encoded =
match Base16.decode encoded with
| Some decoded when Array.length decoded = Length
-> Hash decoded |> Ok
| _ -> Error "Could not decode hash"
let isValid (Hash hash) =
Array.length hash = Length