mfmts: Implements multiformats specification

[ agpl, codec, hash, library, protocol ] [ Propose Tags ] [ Report a vulnerability ]

Implments the multiformats specification used in IPFS and other distributed systems.


[Skip to Readme]

Flags

Manual Flags

NameDescriptionDefault
ci

CI Build options

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 1.0.0.0, 1.0.0.1, 1.1.0.0
Change log CHANGELOG.md
Dependencies array (>=0.5 && <0.6), base (>=4.18 && <5), basesystems (>=1.1 && <1.2), bytestring (>=0.12 && <0.13), containers (>=0.7 && <0.8), crypton (>=1.1 && <1.2), ram (>=0.20.1 && <0.23), text (>=2.1 && <2.2) [details]
License AGPL-3.0-or-later
Author Zoey McBride
Maintainer zoeymcbride@mailbox.org
Uploaded by z0 at 2026-05-19T15:54:53Z
Category Hash, Codec, Protocol
Source repo head: git clone https://git.sr.ht/~z0/mfmts
Distributions
Downloads 19 total (6 in the last 30 days)
Rating (no votes yet) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2026-05-19 [all 1 reports]

Readme for mfmts-1.1.0.0

[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.

cid - Content identitiers 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.

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(0x55, "raw"),
    HashCodec=MultiHash(0x12, "sha2-256"),
    HashDigest=[base58btc]("8S6sXBSX8wVLcT88GnuZpbvmaxetTmPri26tufEByBKS"),
    HashSize=32
}

multibase - Multibase prefix data transcoding

Implements encoders and decoders for numeric basesytems identitified by a specified prefix symbol. It implements transcoders from the basesystems 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)
λ> type Str = ShortByteString
λ> -- uppercase hexadecimal
λ> decodeFromPrefix "F4D756C74696261736520697320617765736F6D6521205C6F2F" :: Maybe Str
Just "Multibase is awesome! \\o/"
λ> -- base32 no padding
λ> decodeFromPrefix "BJV2WY5DJMJQXGZJANFZSAYLXMVZW63LFEEQFY3ZP" :: Maybe Str
Just "Multibase is awesome! \\o/"
λ> -- bitcoin base58
λ> decodeFromPrefix "zYAjKoNbau5KiqmHPmSxYCvn66dA1vLmwbt" :: Maybe Str
Just "Multibase is awesome! \\o/"
λ> -- base64 with padding
λ> decodeFromPrefix "MTXVsdGliYXNlIGlzIGF3ZXNvbWUhIFxvLw==" :: Maybe Str
Just "Multibase is awesome! \\o/"

multicodec - Magic number specifications

Provides lookup table and query functions for codecs defined from multiformats multicodec. These are magic numbers that represent certain data encoded within CIDs, mulithash and other related projects. This module has code which is generated by a python script in the ipfshs repo, and is automatically generated from CSV.

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 code provides a lookup table for hash functions from the multicodec module, and 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)
λ> import Data.BaseSystem.DigitSystem (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 multiformats unsigned binary varints, with the special caveat from multiformats that requires them always to be minimally encoded, so this project also verifies that the varint inputs comply with the rules of the multiformats specifiation.

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

λ> import Data.BaseSystem.BinaryTranscoder (packValue)
λ> import Data.ByteString.Short (ShortByteString)
λ> import MultiFormats.VarInt (VarInt, extractVarInt)
λ> import MultiFormats.VarInt.Errors qualified as VarInt
λ> -- Make alias so we don't get 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 their MSB set until a zero MSB byte 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

Unit tests are provided on the main ipfshs repo, and bugs can be reported on ipfshs ticket tracker.

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