package multihash-digestif
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=cb6887fa2e31dc06d95b15d678ca9a0fa258be4c32d06db9df0b7981bdb8a5f6
sha512=364de8a501ae3a10cb9d12693c985546bb2a43ee8e229d12e6a120b1a666c54af976f08727f39f6bea62728a7499b302bd8d4641da92ab0eeef419e77738be1a
Description
This library provides self-describing hash functions using digestif
Published: 23 Oct 2022
README
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
end
An 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 a8
And 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