mfmts: Implements multiformats specification

[ agpl, codec, hash, library, protocol ] [ Propose Tags ] [ Report a vulnerability ]
Versions [RSS] 1.0.0.0, 1.0.0.1, 1.1.0.0, 1.2.0.0, 1.2.0.1
Change log CHANGELOG.md
Dependencies array (>=0.5 && <0.6), base (>=4.18 && <5), basesystems (>=1.2 && <1.3), bytestring (>=0.12 && <0.13), containers (>=0.7 && <0.8), crypton (>=1.1 && <1.2), deepseq (>=1.4 && <1.5), ram (>=0.20.1 && <0.23), text (>=2.1 && <2.2), xcodec (>=2.0 && <2.1) [details]
License AGPL-3.0-or-later
Author Zoey McBride
Maintainer zoeymcbride@mailbox.org
Uploaded by z0 at 2026-07-21T14:48:30Z
Category Hash, Codec, Protocol
Source repo head: git clone https://git.sr.ht/~z0/mfmts
Distributions
Reverse Dependencies 1 direct, 0 indirect [details]
Downloads 51 total (19 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs uploaded by user
Build status unknown [no reports yet]

Readme for mfmts-1.2.0.1

[back to package description]

mfmts hackage.haskell.orgbuilds.sr.ht status

This project implements the specifications described by Protocol Lab's multiformats written in Haskell, and split across several directories described below.

cid - Content identifiers for hashed data

Provides functionality for the multiformats CID binary format. These modules provide parsing CIDs from multibase prefixed digit strings, extracting CID data from byte strings and serializing CIDs stored in memory into its binary format.

Multiformats CID GitHub README example in GHCI:

λ> {-# LANGUAGE OverloadedStrings #-}
λ> import MultiFormats.CID (CID)
λ> import MultiFormats.CID.Parser qualified as CID
λ> import MultiFormats.CID.Errors qualified as CID
λ> CID.parser "zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA" :: CID.Okay CID
Right CIDv1(DataCodec=MultiCodec(raw=0x55), HashCodec=MultiHash(sha2-256=0x12), HashDigest[32]=0x6e6ff7950a36187a801613426e858dce686cd7d7e3c0fc42ee0330072d245c95)

multibase - Multibase prefix data transcoding

Implements multibase encoders and decoders for numeric basesystems identified by a specified prefix symbol. It uses Transcoders from the xcodec library, allowing for different types of bytestring data to be specified as type parameters.

Multibase GitHub README example in GHCI:

λ> {-# LANGUAGE OverloadedStrings #-}
λ> import MultiFormats.MultiBase.DigitTranscoder (decodeFromPrefix)
λ> import Data.ByteString.Short (ShortByteString)
λ> import Data.ByteString.Lazy (LazyByteString)
λ> type Sbs = ShortByteString
λ> type Lbs = LazyByteString
λ> -- uppercase hexadecimal (F)
λ> decodeFromPrefix "F4D756C74696261736520697320617765736F6D6521205C6F2F" :: Maybe Sbs
Just "Multibase is awesome! \\o/"
λ> -- base32 no padding (B)
λ> decodeFromPrefix "BJV2WY5DJMJQXGZJANFZSAYLXMVZW63LFEEQFY3ZP" :: Maybe Lbs
Just "Multibase is awesome! \\o/"
λ> -- bitcoin base58 (z)
λ> decodeFromPrefix "zYAjKoNbau5KiqmHPmSxYCvn66dA1vLmwbt" :: Maybe Sbs
Just "Multibase is awesome! \\o/"
λ> -- base64 with padding (M)
λ> decodeFromPrefix "MTXVsdGliYXNlIGlzIGF3ZXNvbWUhIFxvLw==" :: Maybe Lbs
Just "Multibase is awesome! \\o/"

multicodec - Magic number specifications

Provides lookup table and query functions for codecs defined from multiformats multicodec. These are magic number identifiers that represent certain data encoded within CIDs, mulithash and other related projects. This module is generated by a Python script in the ipfshs repo by using the CSV file provided from the multicodec GitHub.

Example of looking up codecs:

λ> import MultiFormats.MultiCodec qualified as MC
λ> -- Resolving from codec values:
λ> MC.resolveCodecName $ MC.MultiCodec 0x1
Just "cidv1"
λ> -- Resolving from names:
λ> MC.resolveCodecValue "cidv1"
Just MultiCodec(0x1, "cidv1")
λ> MC.resolveCodecValue "cidv0"
Nothing

multihash - Multicodec hash function identifiers

Multihashes are a type of multicodec for identifying hash functions. This module provides a lookup table for hash functions from the multicodec module, a way to get hash digests from specific functions over bytestrings, and to verify multicodec values as valid multihash codecs.

Example of looking up hash functions and applying them:

λ> import MultiFormats.MultiCodec qualified as MC
λ> import MultiFormats.MultiHash qualified as MH
λ> -- Here's an example of how we can verify names and codec values as valid
λ> -- hash functions.
λ> MH.resolveHashCodec $ MC.MultiCodec 0x12
Just MultiHash(0x12, "sha2-256")
λ> MH.resolveHashName "sha2-256"
Just MultiHash(0x12, "sha2-256")
λ> -- Building a function call that hashes the string "Hello World!" using the
λ> -- sha2-256 algorithm, then outputs the digest as hexadecimal:
λ> import Data.BaseSystem.Lazy (encoder, base16lower)
λ> import Data.ByteString.Builder qualified as Builder
λ> import Data.Maybe (fromJust)
λ> let sha256 = MH.multiHashFunction $ fromJust (MH.resolveHashName "sha2-256")
λ> let input = Builder.string8 "Hello World!"
λ> encoder base16lower $ sha256 input
"7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"

varint - Unsigned variable length integers

Provides parsing and serialization for unsigned binary varints, with the caveat from the multiformats specification that requires them always to be minimally encoded.

Varint GitHub README example in GHCI using packValue from the xcodec library to transfer constants into bytestrings. We can then use extractVarInt to get the varint representation from the bytes:

λ> import Data.ByteString.Short (ShortByteString)
λ> import MultiFormats.VarInt (VarInt, extractVarInt)
λ> import MultiFormats.VarInt.Errors qualified as VarInt
λ> import XCodec.Transcoder (packValue)
λ> -- Alias to suppress type warnings
λ> let packInteger x = packValue (x :: Integer)
λ> -- 7-bit values fit into 1 byte:
λ> extractVarInt (packInteger 0x01) :: VarInt.Okay (VarInt, ShortByteString)
Right (1,"")
λ> extractVarInt (packInteger 0x7f) :: VarInt.Okay (VarInt, ShortByteString)
Right (127,"")
λ> -- 8-bit and larger values have MSB=1 until a byte with MSB=0 is found:
λ> extractVarInt (packInteger 0x8001) :: VarInt.Okay (VarInt, ShortByteString)
Right (128,"")
λ> extractVarInt (packInteger 0xff01) :: VarInt.Okay (VarInt, ShortByteString)
Right (255,"")
λ> extractVarInt (packInteger 0xac02) :: VarInt.Okay (VarInt, ShortByteString)
Right (300,"")
λ> extractVarInt (packInteger 0x808001) :: VarInt.Okay (VarInt, ShortByteString)
Right (16384,"")

Development

This project is part of ipfshs; unit tests are provided on the main page and bugs can be reported on its ticket tracker. Patches and pull requests can be submitted with git send-email. To build and test this project against all of ipfshs read this section on setting up an ipfshs development environment.

This project can also be built as a standalone library with cabal.

$ git clone https://git.sr.ht/~z0/mfmts
$ cd mfmts
$ cabal build

Licensing

The mfmts project and its modules are free software and licensed under the AGPLv3 license. See LICENSE.txt.

Copyright © 2026 Zoey McBride | zoeymcbride@mailbox.org