package multihash-digestif
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=cb6887fa2e31dc06d95b15d678ca9a0fa258be4c32d06db9df0b7981bdb8a5f6
sha512=364de8a501ae3a10cb9d12693c985546bb2a43ee8e229d12e6a120b1a666c54af976f08727f39f6bea62728a7499b302bd8d4641da92ab0eeef419e77738be1a
doc/README.html
ocaml-multihash
Multihashes are self-describing hashes. That means that they encode both the hash digest of some value and also the digest length and the hash function identifier as per the multicodec.
# #require "multihash";;
# #require "digestif.ocaml";;
# #require "multihash-digestif";;Usage
The following section explains how to use multihash and multihash-digestif.
Multihash
The multihash library is implementation-agnostic. It provides a functor for creating a new module which can actually perform the digesting of values. This might be useful because OCaml has quite a few hashing libraries including:
# #show_module_type Multihash__Multihash_intf.Hasher;;
module type Hasher =
sig
val digest :
Multicodec.multihash ->
Cstruct.t -> (Cstruct.t, [ `Msg of string | `Unsupported ]) result
val digest_string :
Multicodec.multihash ->
string -> (string, [ `Msg of string | `Unsupported ]) result
val iter :
Multicodec.multihash ->
((Cstruct.t -> unit) -> unit) ->
(Cstruct.t, [ `Msg of string | `Unsupported ]) result
val iter_string :
Multicodec.multihash ->
((string -> unit) -> unit) ->
(string, [ `Msg of string | `Unsupported ]) result
val is_supported : Multicodec.multihash -> bool
endAn implementation must provide a means to digest a value and also a function detailing which hash functions are supported by the implementation.
Multihash-digestif
multihash-digestif is a multihash library implemented with digestif. Note this library will force you to decide between the C and OCaml implementation of digestif just like any other library with a digestif dependency.
module Md = Multihash_digestif
let s = "Merkle–Damgård"It might be nice to alias the library as we've done here to Md. Creating a new multihash from some string is as simple as.
# let v = Md.of_string `Sha2_256 s |> Result.get_ok;;
val v : string Md.t = <abstr>Note that a multihash is also "tagged" with the internal representation of the digest. We expose two main representations, string and Cstruct.t. This is mainly to help with avoiding copying bytes when using this library with other libraries. So Md.of_string keeps the digest in the string representation. Note that there are copying conversion functions in Md.Conv.
Having now digested the data, it can be converted to the full sequence of bytes. We write the bytes out as the internal representation. Unfortunately the bytes aren't necessarily UTF-8 and that breaks MDX for some reason, so we'll convert them to Cstructs.
# let data = Md.write v |> Cstruct.of_string;;
val data : Cstruct.t = {Cstruct.buffer = <abstr>; off = 0; len = 34}
# let () = hexdump data;;
12 20 41 dd 7b 64 43 54 2e 75 70 1a a9 8a 0c 23
59 51 a2 8a 0d 85 1b 11 56 4d 20 02 2a b1 1d 25
89 a8And of course the hash function used and the length are recoverable from the data by reading it back in.
# let v = Md.read_buff data |> Result.get_ok;;
val v : Cstruct.t Md.t = <abstr>
# let (ident, length, digest) =
let ident = Multicodec.multihash_to_string (Md.get_hash v) in
(ident, Md.get_length v, Md.get_digest v);;
val ident : string = "sha2-256"
val length : int = 32
val digest : Cstruct.t = {Cstruct.buffer = <abstr>; off = 2; len = 32}
# let () = hexdump digest;;
41 dd 7b 64 43 54 2e 75 70 1a a9 8a 0c 23 59 51
a2 8a 0d 85 1b 11 56 4d 20 02 2a b1 1d 25 89 a8