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 65 66 67 68 69 70 71 72 73 74 75 76
module List = Core.List module String = Core.String module Char = Core.Char module Int = Core.Int module Str = Re.Str (* 16 hex chars and 128 chars/string length for hash under hex string format *) let _HASH_LENGTH = 128 let _HEX_SPACE = 16 let _KEY_LENGTH = _HEX_SPACE * _HASH_LENGTH let regexp = Str.regexp "^[a-f0-9]+$" let id value = value let is_hash text = Str.string_match regexp text 0 && String.length text = _HASH_LENGTH let validate_key list = let filtered = List.filter list ~f:is_hash in if List.length filtered = _KEY_LENGTH then Some list else None let to_hex text = "0x" ^ text let tag_index entries = let length = List.length entries in let indexes = List.init length ~f:id in List.zip_exn indexes entries let calculate_index (position, key) = (position * _HEX_SPACE) + key let index_at ~list position = List.nth_exn list position let replace_index ~matrix pairs = pairs |> List.map ~f:(index_at ~list:matrix) let verify_at ~digest ~list (position, hash) = let commitment = List.nth_exn list position in digest hash = commitment let verify_with ~matrix ~digest pairs = pairs |> List.map ~f:(verify_at ~digest ~list:matrix) |> List.reduce_exn ~f:( && ) let concat_hashes left right = left ^ "-" ^ right let indexed_keys msg = msg |> Hash.digest |> String.to_list |> List.map ~f:Char.to_string |> List.map ~f:to_hex |> List.map ~f:Int.of_string |> tag_index |> List.map ~f:calculate_index let nullchar = Char.of_int_exn 0 let pad ~basis msg = let length = String.length msg in let remainder = Int.( % ) length basis in let zerofill = String.make (basis - remainder) nullchar in Cstruct.of_string (msg ^ zerofill) let nonzero char = char != nullchar let unpad msg = String.filter ~f:nonzero msg