diff --git a/CHANGE_LOG.md b/CHANGE_LOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGE_LOG.md
@@ -0,0 +1,14 @@
+Hackage [`mfmts`](http://hackage-content.haskell.org/package/mfmts) package
+change log:
+=====================================================================
+
+## Version 1.0.0.0
+
+Introducing this package to Hackage! This release introduces the basic structure
+for the project and provides the following libraries:
+
+- `mfmts-varint` for processing variable length integer inputs.
+- `mfmts-multicodec` for providing a lookup method for codec values/names.
+- `mfmts-multibase` for converting data to/from multibase encodings.
+- `mfmts-multihash` for identifing hash functions from multicodecs.
+- `mfmts-cid` for encoding/decoding multiformat content idenitifiers.
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,661 @@
+                    GNU AFFERO GENERAL PUBLIC LICENSE
+                       Version 3, 19 November 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
+
+  A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate.  Many developers of free software are heartened and
+encouraged by the resulting cooperation.  However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
+
+  The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community.  It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server.  Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
+
+  An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals.  This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU Affero General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Remote Network Interaction; Use with the GNU General Public License.
+
+  Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software.  This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source.  For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code.  There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+<https://www.gnu.org/licenses/>.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,91 @@
+mfmts
+=====
+
+This project contains my implementation of the [multiformats specifiation](
+https://github.com/multiformats/multiformats) split across several individual
+libraries.
+
+`mfmts-multibase` - Multibase BaseSystems encoding + decoding
+-------------------------------------------------------------
+
+Implements encoders and decoders for numeric basesytems and mutliformats
+specification for multibase prefix encoded strings.
+
+#### *References:*
+- Multibase GitHub - [https://github.com/multiformats/multibase](
+https://github.com/multiformats/multibase)
+
+`mfmts-varints` - Unsigned VarInts
+----------------------------------
+
+Provides parsing and serialization for multiformats unsigned binary varints.
+
+#### *References:*
+- Varint GitHub - [https://github.com/multiformats/unsigned-varint](
+https://github.com/multiformats/unsigned-varint)
+
+`mfmts-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 uses a python script
+to generate haskell code from the freshest `table.csv` on multicodec's GitHub.
+
+#### *References:*
+- Multicodec GitHub - [https://github.com/multiformats/multicodec](
+https://github.com/multiformats/multicodec)
+- Multicodec Table CSV - [
+https://github.com/multiformats/multicodec/blob/master/table.csv](
+https://github.com/multiformats/multicodec/blob/master/table.csv)
+
+`mfmts-multihash` - Multicodec hash function identifiers
+--------------------------------------------------------
+
+Provides a lookup table for hash functions in the `mfmts-codec` table and
+validates they have an implementation backend. This module is also used to
+verify the Multihash's Multicodec as part of decoding ContentIDs.
+
+#### *References:*
+- Multihash GitHub - [
+https://github.com/multiformats/multihash](
+https://github.com/multiformats/multihash)
+- Go implementation - [
+https://github.com/multiformats/go-multihash/blob/master/multihash.go](
+https://github.com/multiformats/go-multihash/blob/master/multihash.go)
+
+`mfmts-cid` - CID/ContentID
+---------------------------
+
+Provides Parsing (from String), Extracting (from ByteString) and Serialization
+(to ByteString) for ContentIDs/CIDs.
+
+#### *References:*
+- CID GitHub - [https://github.com/multiformats/cid](
+https://github.com/multiformats/cid)
+- Go implementation - [https://github.com/ipfs/go-cid](
+https://github.com/ipfs/go-cid)
+
+Unit testing
+------------
+
+Some modules in this directory have unit tests that are generated within the
+python folder as JSON formats. Code for unit tests sets are found at the [main
+ipfshs repo](https://git.sr.ht/~z0/ipfshs).
+
+Reporting bugs
+--------------
+
+Report bugs to the ipfshs [ticket tracker](https://todo.sr.ht/~z0/ipfshs).
+Please include a detailed description of your issue and steps or inputs to
+reproduce it.
+
+Licensing
+---------
+
+The `mfmts` project and its modules are free software and licensed under the
+[AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html) license. See
+[LICENSE.txt](LICENSE.txt).
+
+Copyright (C) 2026 Zoey McBride
+<[zoeymcbride@mailbox.org](mailto:zoeymcbride@mailbox.org)>
diff --git a/cid/MultiFormats/CID.hs b/cid/MultiFormats/CID.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID.hs
@@ -0,0 +1,100 @@
+-- | Module      : MultiFormats.CID
+--   Description : Implements multiformats CID
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This module provides a way for extracting, parsing and serializing CID data.
+-- See: https://github.com/multiformats/cid
+module MultiFormats.CID
+  ( CID (CID),
+    getDataCodec,
+    getHashCodec,
+    getHashDigest,
+    getVersion,
+  )
+where
+
+import Data.BaseSystem (encoder)
+import Data.BaseSystems (base58btc)
+import Data.Bifunctor (first)
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import MultiFormats.CID.Errors
+import MultiFormats.CID.Extractor
+import MultiFormats.CID.Internal
+import MultiFormats.CID.Internal.CIDDecoder
+import MultiFormats.CID.Internal.CIDVersion
+import MultiFormats.CID.Parser
+import MultiFormats.CID.Serializer
+import MultiFormats.MultiCodec (MultiCodec)
+import MultiFormats.MultiHash (MultiHash)
+import Text.Printf (printf)
+
+-- | Wraps CIDData to implement multi-version Parser, Extractor & Serializer.
+newtype CID = CID CIDData deriving (Eq)
+
+-- | Repl/Unit test friendly Show.
+instance Show CID where
+  show cid =
+    let version = getVersion cid
+        datacodec = getDataCodec cid
+        hashcodec = getHashCodec cid
+        hashdigest = getHashDigest cid
+     in printf
+          "%s(DataCodec=%s, HashCodec=%s, HashDigest[%s]=%s)"
+          (show version)
+          (show datacodec)
+          (show hashcodec)
+          (show showbase)
+          (encoder showbase hashdigest)
+    where
+      -- Sets the base implementation to show the hash digest with.
+      showbase = base58btc
+
+-- | Parses a CIDv1 from a MultiBase encoded string OR a CIDv0 from a base58btc
+-- encoded string. Fails when there is extra bytes past the CID.
+instance Parser CID where
+  parser cidstr = do
+    -- Decode to bytes based on the String's encoding.
+    CIDDecoder cidbytes <- parser cidstr
+    -- Extracts the CID's data from bytes.
+    (cid, trailing) <- extractor cidbytes
+    -- Fail if there is any leftovers.
+    if Bytes.length trailing > 0
+      then Left (InvalidData TrailingBytes)
+      else Right cid
+
+-- | Extracts a CID from a ByteString. Allows trailing bytes.
+instance Extractor CID where
+  extractor bytes = do
+    -- First, extract the version from bytes
+    (CIDVersion version, rest) <- extractor bytes
+    -- Apply the constructor if the CID was successfully extracted from bytes
+    first CID <$> case version of
+      CIDv0 -> extractCIDv0 rest
+      CIDv1 -> extractCIDv1 rest
+
+-- | Serializes a CID from representation.
+instance Serializer CID where
+  serializer (CID ciddata) =
+    case cidVersion ciddata of
+      CIDv0 -> serializeCIDv0 ciddata
+      CIDv1 -> serializeCIDv1 ciddata
+
+-- | Gets VersionEnum from a CID.
+getVersion :: CID -> VersionEnum
+getVersion (CID ciddata) = cidVersion ciddata
+
+-- | Gets data-type MultiCodec from a CID.
+getDataCodec :: CID -> MultiCodec
+getDataCodec (CID ciddata) = cidDataCodec ciddata
+
+-- | Gets MultiHash codec from a CID.
+getHashCodec :: CID -> MultiHash
+getHashCodec (CID ciddata) = cidHashCodec ciddata
+
+-- | Gets the hash digest from a CID.
+getHashDigest :: CID -> ByteString
+getHashDigest (CID ciddata) = cidHashDigest ciddata
diff --git a/cid/MultiFormats/CID/Errors.hs b/cid/MultiFormats/CID/Errors.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Errors.hs
@@ -0,0 +1,57 @@
+-- | Module      : MultiFormats.CID.Errors
+--   Description : Provides Errors for CIDs
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.CID.Errors
+  ( Error (..),
+    Okay,
+    DataError (..),
+    EncodingError (..),
+    HashError (..),
+  )
+where
+
+import MultiFormats.VarInt.Errors qualified as VarInt
+
+-- | Functor for wrapping CID processing function's return values.
+type Okay t = Either Error t
+
+-- | Sums up everything that can go wrong in the CID modules.
+data Error
+  = InvalidData DataError
+  | InvalidEncoding EncodingError
+  | InvalidVarInt VarInt.Error
+  | InvalidHash HashError
+  deriving (Eq, Show)
+
+-- | Errors with the CID itself, general/user caused errors.
+data DataError
+  = -- | When the total input is empty.
+    EmptyCID
+  | -- | When the Item's codec can't be resolved from the MultiCodec table.
+    UnknownCodec
+  | -- | When String data was processed, but has extra unaccounted bytes.
+    TrailingBytes
+  deriving (Eq, Show)
+
+-- | Errors arrising from the decoding process.
+data EncodingError
+  = -- | When the leading byte indicates CIDv0 but is malformed.
+    MalformedCIDv0
+  | -- | When the CIDv1 is detected, but has an invalid leading codec.
+    ExpectedCIDv1
+  | -- | When the String encoding has an unknown/unimplemented prefix char.
+    UnknownBasePrefix
+  | -- | When the given string has an invalid character.
+    ImproperDigit
+  deriving (Eq, Show)
+
+-- | Errors with the CID's MultiHash.
+data HashError
+  = -- | If the given hash codec isn't for a hash function.
+    ExpectedHashCodec
+  | -- | If the encoded hash length doesn't match the digest size.
+    IncorrectLength
+  deriving (Eq, Show)
diff --git a/cid/MultiFormats/CID/Extractor.hs b/cid/MultiFormats/CID/Extractor.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Extractor.hs
@@ -0,0 +1,31 @@
+-- | Module      : MultiFormats.CID.Extractor
+--   Description : Provides extracting types for CID
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This file provides a type-class `Extractor` for extracting CID data from a
+-- ByteString. It also provides the type-alias `Extraction` for the function
+-- signature of extracting valid data from the top of a ByteString.
+module MultiFormats.CID.Extractor
+  ( Extractor (extractor),
+    Extraction,
+  )
+where
+
+import Data.Bifunctor (Bifunctor (first))
+import Data.ByteString (ByteString)
+import MultiFormats.CID.Errors
+import MultiFormats.VarInt (VarInt, extractVarInt)
+
+-- | Extracts `a` from ByteString.
+type Extraction a = ByteString -> Okay (a, ByteString)
+
+-- | Generic function signature for extracting CID components.
+class Extractor a where
+  extractor :: Extraction a
+
+-- | Extractor for VarInts in CID data. Converts VarInt.Error to CID.Error.
+instance Extractor VarInt where
+  extractor = first InvalidVarInt . extractVarInt
diff --git a/cid/MultiFormats/CID/Internal.hs b/cid/MultiFormats/CID/Internal.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Internal.hs
@@ -0,0 +1,107 @@
+-- | Module      : MultiFormats.CID.Internal
+--   Description : Internal implementation for CID
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This file provides implemtations for serialization and extraction for
+-- versioned CID data (when we know ahead-of-time to be CIDv0 or CIDv1).
+module MultiFormats.CID.Internal
+  ( CIDData (CIDData, cidVersion, cidDataCodec, cidHashCodec, cidHashDigest),
+
+    -- * Extraction over CIDVersion
+    extractCIDv1,
+    extractCIDv0,
+
+    -- * Serialization over CIDVersion
+    serializeCIDv1,
+    serializeCIDv0,
+
+    -- * Constructs CIDv0 from ByteString
+    mkCIDv0,
+  )
+where
+
+import Data.Bifunctor (first)
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import Data.Maybe (fromJust)
+import MultiFormats.CID.Errors
+import MultiFormats.CID.Extractor
+import MultiFormats.CID.Internal.CIDCodec
+import MultiFormats.CID.Internal.CIDHash
+import MultiFormats.CID.Internal.CIDVersion
+import MultiFormats.CID.Serializer
+import MultiFormats.MultiCodec (MultiCodec, resolveCodecValue)
+import MultiFormats.MultiHash (MultiHash, resolveHashName)
+import MultiFormats.VarInt (VarInt)
+
+-- | Define the CID as a constructor of CIDData
+data CIDData = CIDData
+  { -- | Specifies the version (CIDv0 or CIDv1) of this CID.
+    cidVersion :: VersionEnum,
+    -- | Describes the content type of the hashed data.
+    cidDataCodec :: MultiCodec,
+    -- | Contains the hash functoin used.
+    cidHashCodec :: MultiHash,
+    -- | Stores the hash function's output.
+    cidHashDigest :: ByteString
+  }
+  deriving (Eq)
+
+-- | Applies the extraction after version# for CIDv0 was extracted.
+extractCIDv0 :: Extraction CIDData
+extractCIDv0 ondata = first mkCIDv0 <$> splitDigestCIDv0 ondata
+  where
+    -- Get the hash digest from ByteString if there is enough bytes.
+    splitDigestCIDv0 digest
+      | Bytes.length digest < hashlen = Left (InvalidHash IncorrectLength)
+      | otherwise = Right (Bytes.splitAt hashlen digest)
+      where
+        hashlen = cidv0HashLength
+
+-- | Applies the extraction after version# for CIDv1 was extracted.
+extractCIDv1 :: Extraction CIDData
+extractCIDv1 oncodec = do
+  -- Extract the 1st MultiCodec from the bytes.
+  (CIDCodec multicodec, onhash) <- extractor oncodec
+  -- Extract the 2nd MultiCodec and get CIDHash
+  (CIDHash multihash hashdigest, stop) <- extractor onhash
+  -- return the CIDv1 data with the trailing bytes.
+  return (CIDData CIDv1 multicodec multihash hashdigest, stop)
+
+-- | Serializes CIDv0 by adding the Codec Byte to its digest
+serializeCIDv0 :: Serialization CIDData
+serializeCIDv0 ciddata =
+  return $ Bytes.cons cidv0Byte1st (cidHashDigest ciddata)
+
+-- | Serializes CIDv1 into VarInts of its components.
+serializeCIDv1 :: Serialization CIDData
+serializeCIDv1 ciddata =
+  let digest = cidHashDigest ciddata
+      digestlength = Bytes.length digest
+   in Bytes.concat
+        <$> sequence
+          [ serializer cidv1VarInt1st,
+            serializer (cidDataCodec ciddata),
+            serializer (cidHashCodec ciddata),
+            serializer (fromIntegral digestlength :: VarInt),
+            pure digest
+          ]
+
+-- | Provides the contructor for CIDv0s, see:
+-- https://github.com/multiformats/cid?tab=readme-ov-file#cidv0
+mkCIDv0 :: ByteString -> CIDData
+mkCIDv0 digest =
+  CIDData
+    { cidVersion = CIDv0,
+      cidDataCodec = codec "dag-pb",
+      cidHashCodec = hash "sha2-256",
+      cidHashDigest = digest
+    }
+  where
+    -- Forces a resolve from MultiCodec
+    codec str = fromJust $ resolveCodecValue str
+    -- Forces a resolve from MultiHash
+    hash str = fromJust $ resolveHashName str
diff --git a/cid/MultiFormats/CID/Internal/CIDCodec.hs b/cid/MultiFormats/CID/Internal/CIDCodec.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Internal/CIDCodec.hs
@@ -0,0 +1,18 @@
+-- | Module      : MultiFormats.CID.Internal.CIDCodec
+--   Description : Implements extracting codecs from CIDs.
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.CID.Internal.CIDCodec (CIDCodec (CIDCodec)) where
+
+import Data.Bifunctor (first)
+import MultiFormats.CID.Extractor (Extractor (extractor))
+import MultiFormats.MultiCodec (MultiCodec (MultiCodec))
+
+-- | Represents a MultiCodec value embedded within CID data.
+newtype CIDCodec = CIDCodec MultiCodec deriving (Eq)
+
+-- | Extracts the MultiCodec from VarInt in bytes and wraps in CIDCodec.
+instance Extractor CIDCodec where
+  extractor bytes = first (CIDCodec . MultiCodec) <$> extractor bytes
diff --git a/cid/MultiFormats/CID/Internal/CIDDecoder.hs b/cid/MultiFormats/CID/Internal/CIDDecoder.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Internal/CIDDecoder.hs
@@ -0,0 +1,29 @@
+-- | Module      : MultiFormats.CID.Internal.CIDDecoder
+--   Description : Parses CID bytes from a multibase encoded string
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.CID.Internal.CIDDecoder (CIDDecoder (CIDDecoder)) where
+
+import Data.ByteString (ByteString)
+import MultiFormats.CID.Errors
+import MultiFormats.CID.Internal.CIDVersion (isCIDv0Str)
+import MultiFormats.CID.Parser
+import MultiFormats.MultiBase (decodeCIDv0, decodeFromPrefix, hasValidPrefix)
+
+-- | Implements decoding CID from String's base encoding.
+newtype CIDDecoder = CIDDecoder ByteString
+
+-- | Decodes a CID to bytes.
+instance Parser CIDDecoder where
+  parser str =
+    let choosedecoder
+          | null str = Left (InvalidData EmptyCID)
+          | isCIDv0Str str = Right decodeCIDv0
+          | hasValidPrefix str = Right decodeFromPrefix
+          | otherwise = Left (InvalidEncoding UnknownBasePrefix)
+     in choosedecoder >>= \decoder ->
+          case decoder str of
+            Nothing -> Left (InvalidEncoding ImproperDigit)
+            Just bytes -> Right (CIDDecoder bytes)
diff --git a/cid/MultiFormats/CID/Internal/CIDHash.hs b/cid/MultiFormats/CID/Internal/CIDHash.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Internal/CIDHash.hs
@@ -0,0 +1,42 @@
+-- | Module      : MultiFormats.CID.Internal.CIDHash
+--   Description : Implements extraction and verification of multihash CID data
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.CID.Internal.CIDHash (CIDHash (CIDHash)) where
+
+import Data.Bifunctor (first)
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import MultiFormats.CID.Errors
+import MultiFormats.CID.Extractor (Extractor (extractor))
+import MultiFormats.CID.Internal.CIDCodec (CIDCodec (CIDCodec))
+import MultiFormats.MultiHash (MultiHash, resolveHashCodec)
+import MultiFormats.VarInt (VarInt)
+
+data CIDHash = CIDHash
+  { -- | Stores the MultiCodec for the hash function used.
+    cidHashCodec :: MultiHash,
+    -- | Stores the hash function's output.
+    cidHashDigest :: ByteString
+  }
+  deriving (Eq)
+
+-- | Extracts the MultiHash codec and hash digest via a varint size following
+-- the MultiHash codec.
+instance Extractor CIDHash where
+  extractor bytes = do
+    -- Get the CodecCode from the first varint
+    (CIDCodec codec, onsize) <- extractor bytes
+    -- Get the digest size from the first varint, make CID.Error if on Left
+    (usize :: VarInt, rest) <- extractor onsize
+    -- When codec is a valid hash and the given size is available in the bytes,
+    -- take #size elements from bytes and construct the CIDHash
+    case resolveHashCodec codec of
+      Nothing -> Left (InvalidHash ExpectedHashCodec)
+      Just hash
+        | isize > Bytes.length rest -> Left (InvalidHash IncorrectLength)
+        | otherwise -> Right (first (CIDHash hash) $ Bytes.splitAt isize rest)
+        where
+          isize = fromIntegral usize
diff --git a/cid/MultiFormats/CID/Internal/CIDVersion.hs b/cid/MultiFormats/CID/Internal/CIDVersion.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Internal/CIDVersion.hs
@@ -0,0 +1,108 @@
+-- | Module      : MultiFormats.CID.Internal.CIDVersion
+--   Description : Implements extraction versioning from CID data.
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.CID.Internal.CIDVersion
+  ( VersionEnum (CIDv0, CIDv1),
+    CIDVersion (CIDVersion),
+
+    -- * Extractions
+    extractVersion0,
+    extractVersion1,
+
+    -- * Helper functions
+    isCIDv0Str,
+
+    -- * Constants
+    cidv0Bytes,
+    cidv0HashLength,
+    cidv0Byte1st,
+    cidv1VarInt1st,
+  )
+where
+
+import Data.Bifunctor (Bifunctor (first))
+import Data.ByteString qualified as Bytes
+import Data.Word (Word8)
+import MultiFormats.CID.Errors
+import MultiFormats.CID.Extractor (Extraction, Extractor (extractor))
+import MultiFormats.VarInt (VarInt)
+
+-- | Implements available CID versions.
+data VersionEnum = CIDv0 | CIDv1 deriving (Show, Eq, Enum)
+
+-- | Wraps Version type to implement Extractor.
+newtype CIDVersion = CIDVersion VersionEnum deriving (Eq)
+
+-- | Extracts and validates the CID versioning information from bytes.
+instance Extractor CIDVersion where
+  extractor cidbytes =
+    case Bytes.uncons cidbytes of
+      Nothing -> Left (InvalidData EmptyCID)
+      -- Only CIDv0 will start with 0x12, and it must be followed w/ a
+      -- special byte; if it doesn't have both, the encoding is invalid.
+      Just (0x12, _) -> first CIDVersion <$> extractVersion0 cidbytes
+      -- Without the magic bytes, CIDvX > CIDv0 is done in VarInts, so we get
+      -- the Version information from the first varint (0x1 for CIDv1).
+      Just _VarInt -> first CIDVersion <$> extractVersion1 cidbytes
+
+-- | Performs extraction for CIDv1.
+extractVersion1 :: Extraction VersionEnum
+extractVersion1 bytes =
+  extractor bytes >>= \(varint1, rest) ->
+    if invalidCIDv1 varint1
+      then Left (InvalidEncoding ExpectedCIDv1)
+      else Right (CIDv1, rest)
+  where
+    invalidCIDv1 v1 = v1 /= cidv1VarInt1st
+
+-- | Performs extraction for CIDv0.
+extractVersion0 :: Extraction VersionEnum
+extractVersion0 bytes =
+  let (lead, rest) = Bytes.splitAt 2 bytes
+   in case Bytes.unpack lead of
+        [b1, b2]
+          | invalidCIDv0 b1 b2 -> Left (InvalidEncoding MalformedCIDv0)
+          | otherwise -> Right (CIDv0, rest)
+        _Not2 -> Left (InvalidEncoding MalformedCIDv0)
+  where
+    invalidCIDv0 b1 b2 =
+      b1 /= cidv0Byte1st
+        || b2 /= cidv0Byte2nd
+        || Bytes.length bytes /= cidv0Bytes
+
+-- | This prefixes a CIDv0 instead of a multibase prefix.
+cidv0StringPrefix :: String
+cidv0StringPrefix = "Qm"
+
+-- | The length of a CIDv0 string, base58 encoded.
+cidv0StringLength :: Int
+cidv0StringLength = 46
+
+-- | Required length in bytes of all CIDv0 encodings.
+cidv0Bytes :: Int
+cidv0Bytes = 34
+
+-- | Length of hash digest in CIDv0, ie the length without its versioning
+-- information, since those are the only items in CIDv0.
+cidv0HashLength :: Int
+cidv0HashLength = cidv0Bytes - 2
+
+-- | Required first byte of all CIDv0 encodings.
+cidv0Byte1st :: Word8
+cidv0Byte1st = 0x12
+
+-- | Required second byte of all CIDv0 encodings.
+cidv0Byte2nd :: Word8
+cidv0Byte2nd = 0x20
+
+-- | Required first VarInt of all CIDv1 encodings.
+cidv1VarInt1st :: VarInt
+cidv1VarInt1st = 1
+
+-- | Checks if a string meets CIDv0 criteria.
+isCIDv0Str :: String -> Bool
+isCIDv0Str str =
+  take 2 str == cidv0StringPrefix && length str == cidv0StringLength
diff --git a/cid/MultiFormats/CID/Parser.hs b/cid/MultiFormats/CID/Parser.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Parser.hs
@@ -0,0 +1,20 @@
+-- | Module      : MultiFormats.CID.Parser
+--   Description : Provides parsing types for CID
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This file provides a type-class `Parser` for parsing CID data from a
+-- multibase encoded string. It also provides the type-alias `ParseMethod` for
+-- the function signature Parsing some type a from String.
+module MultiFormats.CID.Parser (Parser (parser), ParseMethod) where
+
+import MultiFormats.CID.Errors (Okay)
+
+-- | Function signature for parsing a String into some `a`.
+type ParseMethod a = String -> Okay a
+
+-- | Generic function signature for parsing CID components from Strings.
+class Parser a where
+  parser :: ParseMethod a
diff --git a/cid/MultiFormats/CID/Serializer.hs b/cid/MultiFormats/CID/Serializer.hs
new file mode 100644
--- /dev/null
+++ b/cid/MultiFormats/CID/Serializer.hs
@@ -0,0 +1,41 @@
+-- | Module      : MultiFormats.CID.Serializer
+--   Description : Provides serialization types for CID
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- This file provides a type-class `Serializer` for serializing CID data to
+-- ByteString. It also provides the type-alias `Serialization` for the function
+-- signature of some serialization over type a.
+module MultiFormats.CID.Serializer
+  ( Serialization,
+    Serializer (serializer),
+  )
+where
+
+import Data.Bifunctor (Bifunctor (first))
+import Data.ByteString (ByteString)
+import MultiFormats.CID.Errors
+import MultiFormats.MultiCodec (MultiCodec, multiCodecValue)
+import MultiFormats.MultiHash (MultiHash, multiHashCodec)
+import MultiFormats.VarInt (VarInt, serializeVarInt)
+
+-- | Represents a function that implements serialization.
+type Serialization a = a -> Okay ByteString
+
+-- | Generic function signature for serializing CID components.
+class Serializer a where
+  serializer :: Serialization a
+
+-- | Serializer for VarInts in CID data. Converts VarInt.Error to CID.Error.
+instance Serializer VarInt where
+  serializer = first InvalidVarInt . serializeVarInt
+
+-- | Composes with Serializer VarInt.
+instance Serializer MultiCodec where
+  serializer = serializer . multiCodecValue
+
+-- | Composes with Serializer MultiCodec.
+instance Serializer MultiHash where
+  serializer = serializer . multiHashCodec
diff --git a/mfmts.cabal b/mfmts.cabal
new file mode 100644
--- /dev/null
+++ b/mfmts.cabal
@@ -0,0 +1,138 @@
+cabal-version:   3.0
+version:         1.0.0.0
+name:            mfmts
+build-type:      Simple
+author:          Zoey McBride
+maintainer:      zoeymcbride@mailbox.org
+license:         AGPL-3.0-or-later
+license-file:    LICENSE.txt
+extra-doc-files: README.md, CHANGE_LOG.md
+category:        Hash, Codec, Protocol
+synopsis:        Implements multiformats specification
+description:
+    Implments the multiformats specification used in IPFS and other distributed
+    systems.
+
+source-repository head
+  type:     git
+  location: https://git.sr.ht/~z0/mfmts
+
+-- | Base language settings. Imported for all libraries.
+common haskell-settings
+    default-language: GHC2021
+    default-extensions: StrictData
+    ghc-options: -Wall -Wextra -Wno-unused-top-binds
+
+-- | Packages everything into a single library for distribution.
+library
+    import: haskell-settings
+    hs-source-dirs:
+        cid
+        multibase
+        multicodec
+        multihash
+        varint
+    exposed-modules:
+        MultiFormats.VarInt,
+        MultiFormats.VarInt.Errors,
+        MultiFormats.MultiCodec,
+        MultiFormats.MultiBase,
+        MultiFormats.MultiBaseSystems,
+        MultiFormats.MultiHash,
+        MultiFormats.CID,
+        MultiFormats.CID.Errors,
+        MultiFormats.CID.Serializer,
+        MultiFormats.CID.Extractor,
+        MultiFormats.CID.Parser,
+        MultiFormats.CID.Internal,
+        MultiFormats.CID.Internal.CIDCodec,
+        MultiFormats.CID.Internal.CIDDecoder,
+        MultiFormats.CID.Internal.CIDHash,
+        MultiFormats.CID.Internal.CIDVersion,
+    build-depends:
+        array >= 0.5.8 && < 0.6,
+        base >= 4.18.3 && < 4.19,
+        basesystems >= 1.0.0 && < 1.1,
+        bytestring >= 0.11.5 && < 0.12,
+        containers >= 0.6.7 && < 0.7,
+        text >= 1.2.5 && < 1.3,
+        crypton >= 1.0.6 && < 1.1,
+        memory >= 0.18.0 && < 0.19,
+
+
+-- | Implements unsigned variable length integers.
+library mfmts-varint
+    import: haskell-settings
+    hs-source-dirs: varint
+    exposed-modules:
+        MultiFormats.VarInt,
+        MultiFormats.VarInt.Errors,
+    build-depends:
+        base >= 4.18.3 && < 4.19,
+        bytestring >= 0.11.5 && < 0.12,
+        containers >= 0.6.7 && < 0.7,
+
+-- | Lookup table for MultiCodecs. Generated from Python.
+library mfmts-multicodec
+    import: haskell-settings
+    hs-source-dirs: multicodec
+    exposed-modules:
+        MultiFormats.MultiCodec,
+    build-depends:
+        base >= 4.18.3 && < 4.19,
+        bytestring >= 0.11.5 && < 0.12,
+        containers >= 0.6.7 && < 0.7,
+        mfmts-varint
+
+-- | Encode/decode mutibase strings with identifying prefix.
+library mfmts-multibase
+    import: haskell-settings
+    hs-source-dirs: multibase
+    exposed-modules:
+        MultiFormats.MultiBase,
+        MultiFormats.MultiBaseSystems,
+    build-depends:
+        base >= 4.18.3 && < 4.19,
+        array >= 0.5.8 && < 0.6,
+        bytestring >= 0.11.5 && < 0.12,
+        containers >= 0.6.7 && < 0.7,
+        text >= 1.2.5 && < 1.3,
+        basesystems >= 1.0.0 && < 1.1,
+
+-- | Associates MultiCodecs for hash functions with implementations.
+library mfmts-multihash
+    import: haskell-settings
+    hs-source-dirs: multihash
+    exposed-modules:
+        MultiFormats.MultiHash,
+    build-depends:
+        base >= 4.18.3 && < 4.19,
+        bytestring >= 0.11.5 && < 0.12,
+        containers >= 0.6.7 && < 0.7,
+        crypton >= 1.0.6 && < 1.1,
+        memory >= 0.18.0 && < 0.19,
+        mfmts-multicodec
+
+-- | Modules for reading/writing CIDs.
+library mfmts-cid
+    import: haskell-settings
+    hs-source-dirs: cid
+    exposed-modules:
+        MultiFormats.CID,
+        MultiFormats.CID.Errors,
+        MultiFormats.CID.Serializer,
+        MultiFormats.CID.Extractor,
+        MultiFormats.CID.Parser,
+        MultiFormats.CID.Internal,
+        MultiFormats.CID.Internal.CIDCodec,
+        MultiFormats.CID.Internal.CIDDecoder,
+        MultiFormats.CID.Internal.CIDHash,
+        MultiFormats.CID.Internal.CIDVersion,
+    build-depends:
+        base >= 4.18.3 && < 4.19,
+        bytestring >= 0.11.5 && < 0.12,
+        basesystems >= 1.0.0 && < 1.1,
+        mfmts-multibase,
+        mfmts-multihash,
+        mfmts-multicodec,
+        mfmts-varint,
diff --git a/multibase/MultiFormats/MultiBase.hs b/multibase/MultiFormats/MultiBase.hs
new file mode 100644
--- /dev/null
+++ b/multibase/MultiFormats/MultiBase.hs
@@ -0,0 +1,108 @@
+-- | Module      : MultiFormats.MultiBase
+--   Description : Functions for working with multibase data.
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.MultiBase
+  ( MultiBase (prefixChar, baseEncoder, baseDecoder),
+    mkMultiBase,
+
+    -- * Decoders
+    decodeFromPrefix,
+    decodeCIDv0,
+
+    -- * Query functions for MultiBase information
+    hasValidPrefix,
+    resolvePrefix,
+    resolveMultiBase,
+  )
+where
+
+import Data.BaseSystem (BaseSystem, Decoder, Encoder)
+import Data.BaseSystem qualified as Bases
+import Data.BaseSystems qualified as Bases
+import Data.Function (on)
+import Data.List (uncons)
+import Data.Map.Strict qualified as Map
+import Data.Maybe (isJust)
+import Text.Printf (printf)
+
+data MultiBase = MultiBase
+  { prefixChar :: Char,
+    baseEncoder :: Encoder,
+    baseDecoder :: Decoder,
+    baseName :: String
+  }
+
+instance Eq MultiBase where
+  (==) = (==) `on` prefixChar
+
+instance Ord MultiBase where
+  compare = compare `on` prefixChar
+
+instance Show MultiBase where
+  show mb = printf "multi%s('%c')" (baseName mb) (prefixChar mb)
+
+-- | Implements encoder/decoder for multibase systems when the prefix is known
+-- ahead of time.
+instance BaseSystem MultiBase where
+  encoder mb bytes = prefixChar mb : baseEncoder mb bytes
+  decoder _ = decodeFromPrefix
+
+-- | Constructs a Multibase from a BaseSystem.
+mkMultiBase :: (Show b, BaseSystem b) => b -> Char -> MultiBase
+mkMultiBase bs prefix =
+  MultiBase
+    { prefixChar = prefix,
+      baseEncoder = Bases.encoder bs,
+      baseDecoder = Bases.decoder bs,
+      baseName = show bs
+    }
+
+-- | Resolves a MultiBase system from a Char.
+resolvePrefix :: Char -> Maybe MultiBase
+resolvePrefix prefix = Map.lookup prefix prefixTable <*> pure prefix
+  where
+    -- https://github.com/multiformats/multibase/blob/master/multibase.csv
+    prefixTable =
+      Map.fromList
+        [ ('0', mkMultiBase Bases.base2),
+          ('9', mkMultiBase Bases.base10),
+          ('f', mkMultiBase Bases.base16lower),
+          ('F', mkMultiBase Bases.base16upper),
+          ('b', mkMultiBase Bases.base32lowerNP),
+          ('B', mkMultiBase Bases.base32upperNP),
+          ('c', mkMultiBase Bases.base32lower),
+          ('C', mkMultiBase Bases.base32upper),
+          ('v', mkMultiBase Bases.base32hexlowerNP),
+          ('V', mkMultiBase Bases.base32hexupperNP),
+          ('t', mkMultiBase Bases.base32hexlower),
+          ('T', mkMultiBase Bases.base32hexupper),
+          ('z', mkMultiBase Bases.base58btc),
+          ('m', mkMultiBase Bases.base64NP),
+          ('M', mkMultiBase Bases.base64),
+          ('u', mkMultiBase Bases.base64urlNP),
+          ('U', mkMultiBase Bases.base64url)
+        ]
+
+-- | Resolves a MultiBase system from the first Char in a String.
+resolveMultiBase :: String -> Maybe MultiBase
+resolveMultiBase str = uncons str >>= \(ch, _) -> resolvePrefix ch
+
+-- | Checks if a given char is an implemented MultiBase prefix.
+hasValidPrefix :: String -> Bool
+hasValidPrefix [] = False
+hasValidPrefix (prefix : _) = isJust $ resolvePrefix prefix
+
+-- | Provides decoder for MultiBase strings with any implemented prefix
+-- character.
+decodeFromPrefix :: Decoder
+decodeFromPrefix str =
+  uncons str >>= \(prefix, rest) -> do
+    decode <- baseDecoder <$> resolvePrefix prefix
+    decode rest
+
+-- | Decodes for CIDv0 from base58btc w/o MultiBase prefix.
+decodeCIDv0 :: Decoder
+decodeCIDv0 = Bases.decoder Bases.base58btc
diff --git a/multibase/MultiFormats/MultiBaseSystems.hs b/multibase/MultiFormats/MultiBaseSystems.hs
new file mode 100644
--- /dev/null
+++ b/multibase/MultiFormats/MultiBaseSystems.hs
@@ -0,0 +1,102 @@
+-- | Module      : MultiFormats.MultiBaseSystems
+--   Description : Provides default instances of multibase
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.MultiBaseSystems
+  ( base2,
+    base10,
+    base16lower,
+    base16upper,
+    base32lower,
+    base32lowerNP,
+    base32upper,
+    base32upperNP,
+    base32hexlower,
+    base32hexlowerNP,
+    base32hexupper,
+    base32hexupperNP,
+    base58btc,
+    base64,
+    base64NP,
+    base64url,
+    base64urlNP,
+  )
+where
+
+import Data.Maybe (fromJust)
+import MultiFormats.MultiBase
+
+-- | Unwraps Maybe from multibaseSystems lookup for implementing MultiBase from
+-- Char.
+multibasePrefix :: Char -> MultiBase
+multibasePrefix = fromJust . resolvePrefix
+
+-- | Binary has prefix '0'.
+base2 :: MultiBase
+base2 = multibasePrefix '0'
+
+-- | Decimal has prefix '9'.
+base10 :: MultiBase
+base10 = multibasePrefix '9'
+
+-- | Hex-lower has prefix 'f'.
+base16lower :: MultiBase
+base16lower = multibasePrefix 'f'
+
+-- | Hex-upper has prefix 'F'.
+base16upper :: MultiBase
+base16upper = multibasePrefix 'F'
+
+-- | base32lower (no pad) has prefix 'b'.
+base32lowerNP :: MultiBase
+base32lowerNP = multibasePrefix 'b'
+
+-- | base32uppper (no pad) has prefix 'B'.
+base32upperNP :: MultiBase
+base32upperNP = multibasePrefix 'B'
+
+-- | base32lower (with pad) has prefix 'c'.
+base32lower :: MultiBase
+base32lower = multibasePrefix 'c'
+
+-- | base32upper (with pad) has prefix 'C'.
+base32upper :: MultiBase
+base32upper = multibasePrefix 'C'
+
+-- | Hex-base32lower (no pad) has prefix 'v'.
+base32hexlowerNP :: MultiBase
+base32hexlowerNP = multibasePrefix 'v'
+
+-- | Hex-base32upper (no pad) has prefix 'V'.
+base32hexupperNP :: MultiBase
+base32hexupperNP = multibasePrefix 'V'
+
+-- | Hex-base32lower (with pad) has prefix 't'.
+base32hexlower :: MultiBase
+base32hexlower = multibasePrefix 't'
+
+-- | Hex-base32upper (with pad) has prefix 'T'.
+base32hexupper :: MultiBase
+base32hexupper = multibasePrefix 'T'
+
+-- | Bitcoin base58 has prefix 'z'.
+base58btc :: MultiBase
+base58btc = multibasePrefix 'z'
+
+-- | base64 (no pad) has prefix 'm'.
+base64NP :: MultiBase
+base64NP = multibasePrefix 'm'
+
+-- | base64 (with pad) has prefix 'M'.
+base64 :: MultiBase
+base64 = multibasePrefix 'M'
+
+-- | base64url (no pad) has prefix 'u'.
+base64urlNP :: MultiBase
+base64urlNP = multibasePrefix 'u'
+
+-- | base64url (with pad) has prefix 'U'.
+base64url :: MultiBase
+base64url = multibasePrefix 'U'
diff --git a/multicodec/MultiFormats/MultiCodec.hs b/multicodec/MultiFormats/MultiCodec.hs
new file mode 100644
--- /dev/null
+++ b/multicodec/MultiFormats/MultiCodec.hs
@@ -0,0 +1,1299 @@
+-- | Module      : MultiFormats.MultiCodec
+--   Description : Implements lookup table for multicodecs
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- Provides a lookup table for multicodec values and names. This file is
+-- generated automatically by `python/MultiCodec/generate_module.py` and was
+-- last updated on <DATE>.
+module MultiFormats.MultiCodec
+  ( MultiCodec (MultiCodec, multiCodecValue),
+    resolveCodecValue,
+    resolveCodecName,
+    gitCommitHash,
+    gitCommitDate,
+  )
+where
+
+import Data.Map (Map)
+import Data.Map qualified as LazyMap
+import Data.Maybe (fromMaybe)
+import MultiFormats.VarInt (VarInt)
+
+-- | Represents MultiCodec code.
+newtype MultiCodec = MultiCodec {multiCodecValue :: VarInt} deriving (Eq, Ord)
+
+instance Show MultiCodec where
+  show codec = fromMaybe "<invalid codec>" $ resolveCodecName codec
+
+-- | Resolves MultiCodec code from its string name.
+resolveCodecValue :: String -> Maybe MultiCodec
+resolveCodecValue name = MultiCodec <$> LazyMap.lookup name nameToCodec
+
+-- | Resolves MultiCodec name from its numeric code.
+resolveCodecName :: MultiCodec -> Maybe String
+resolveCodecName (MultiCodec codec) = LazyMap.lookup codec codecToName
+
+-- | The git hash for table.csv used to generate this file.
+gitCommitHash :: String
+gitCommitHash = "8167547c160b7904b755b9a7eef7c391e90552e4"
+
+-- | This is the date the table.csv was commited.
+gitCommitDate :: String
+gitCommitDate = "2026-02-13 15:12:08 +0100"
+
+nameToCodec :: Map String VarInt
+nameToCodec =
+  LazyMap.fromList
+    [ ("identity", 0x00),
+      ("cidv1", 0x01),
+      ("cidv2", 0x02),
+      ("cidv3", 0x03),
+      ("ip4", 0x04),
+      ("tcp", 0x06),
+      ("sha1", 0x11),
+      ("sha2-256", 0x12),
+      ("sha2-512", 0x13),
+      ("sha3-512", 0x14),
+      ("sha3-384", 0x15),
+      ("sha3-256", 0x16),
+      ("sha3-224", 0x17),
+      ("shake-128", 0x18),
+      ("shake-256", 0x19),
+      ("keccak-224", 0x1a),
+      ("keccak-256", 0x1b),
+      ("keccak-384", 0x1c),
+      ("keccak-512", 0x1d),
+      ("blake3", 0x1e),
+      ("sha2-384", 0x20),
+      ("dccp", 0x21),
+      ("murmur3-x64-64", 0x22),
+      ("murmur3-32", 0x23),
+      ("ip6", 0x29),
+      ("ip6zone", 0x2a),
+      ("ipcidr", 0x2b),
+      ("path", 0x2f),
+      ("multicodec", 0x30),
+      ("multihash", 0x31),
+      ("multiaddr", 0x32),
+      ("multibase", 0x33),
+      ("varsig", 0x34),
+      ("dns", 0x35),
+      ("dns4", 0x36),
+      ("dns6", 0x37),
+      ("dnsaddr", 0x38),
+      ("protobuf", 0x50),
+      ("cbor", 0x51),
+      ("raw", 0x55),
+      ("dbl-sha2-256", 0x56),
+      ("rlp", 0x60),
+      ("bencode", 0x63),
+      ("dag-pb", 0x70),
+      ("dag-cbor", 0x71),
+      ("libp2p-key", 0x72),
+      ("git-raw", 0x78),
+      ("torrent-info", 0x7b),
+      ("torrent-file", 0x7c),
+      ("blake3-hashseq", 0x80),
+      ("leofcoin-block", 0x81),
+      ("leofcoin-tx", 0x82),
+      ("leofcoin-pr", 0x83),
+      ("sctp", 0x84),
+      ("dag-jose", 0x85),
+      ("dag-cose", 0x86),
+      ("lbry", 0x8c),
+      ("eth-block", 0x90),
+      ("eth-block-list", 0x91),
+      ("eth-tx-trie", 0x92),
+      ("eth-tx", 0x93),
+      ("eth-tx-receipt-trie", 0x94),
+      ("eth-tx-receipt", 0x95),
+      ("eth-state-trie", 0x96),
+      ("eth-account-snapshot", 0x97),
+      ("eth-storage-trie", 0x98),
+      ("eth-receipt-log-trie", 0x99),
+      ("eth-receipt-log", 0x9a),
+      ("aes-128", 0xa0),
+      ("aes-192", 0xa1),
+      ("aes-256", 0xa2),
+      ("chacha-128", 0xa3),
+      ("chacha-256", 0xa4),
+      ("bitcoin-block", 0xb0),
+      ("bitcoin-tx", 0xb1),
+      ("bitcoin-witness-commitment", 0xb2),
+      ("zcash-block", 0xc0),
+      ("zcash-tx", 0xc1),
+      ("caip-50", 0xca),
+      ("streamid", 0xce),
+      ("stellar-block", 0xd0),
+      ("stellar-tx", 0xd1),
+      ("md4", 0xd4),
+      ("md5", 0xd5),
+      ("decred-block", 0xe0),
+      ("decred-tx", 0xe1),
+      ("ipld", 0xe2),
+      ("ipfs", 0xe3),
+      ("swarm", 0xe4),
+      ("ipns", 0xe5),
+      ("zeronet", 0xe6),
+      ("secp256k1-pub", 0xe7),
+      ("dnslink", 0xe8),
+      ("bls12_381-g1-pub", 0xea),
+      ("bls12_381-g2-pub", 0xeb),
+      ("x25519-pub", 0xec),
+      ("ed25519-pub", 0xed),
+      ("bls12_381-g1g2-pub", 0xee),
+      ("sr25519-pub", 0xef),
+      ("dash-block", 0xf0),
+      ("dash-tx", 0xf1),
+      ("swarm-manifest", 0xfa),
+      ("swarm-feed", 0xfb),
+      ("beeson", 0xfc),
+      ("udp", 0x0111),
+      ("webrtc-direct", 0x0118),
+      ("webrtc", 0x0119),
+      ("p2p-circuit", 0x0122),
+      ("dag-json", 0x0129),
+      ("udt", 0x012d),
+      ("utp", 0x012e),
+      ("crc32", 0x0132),
+      ("crc64-ecma", 0x0164),
+      ("crc64-nvme", 0x0165),
+      ("unix", 0x0190),
+      ("thread", 0x0196),
+      ("p2p", 0x01a5),
+      ("https", 0x01bb),
+      ("onion", 0x01bc),
+      ("onion3", 0x01bd),
+      ("garlic64", 0x01be),
+      ("garlic32", 0x01bf),
+      ("tls", 0x01c0),
+      ("sni", 0x01c1),
+      ("noise", 0x01c6),
+      ("shs", 0x01c8),
+      ("quic", 0x01cc),
+      ("quic-v1", 0x01cd),
+      ("webtransport", 0x01d1),
+      ("certhash", 0x01d2),
+      ("ws", 0x01dd),
+      ("wss", 0x01de),
+      ("p2p-websocket-star", 0x01df),
+      ("http", 0x01e0),
+      ("http-path", 0x01e1),
+      ("swhid-1-snp", 0x01f0),
+      ("json", 0x0200),
+      ("messagepack", 0x0201),
+      ("car", 0x0202),
+      ("x509-certificate", 0x0210),
+      ("ipns-record", 0x0300),
+      ("libp2p-peer-record", 0x0301),
+      ("libp2p-relay-rsvp", 0x0302),
+      ("memorytransport", 0x0309),
+      ("car-index-sorted", 0x0400),
+      ("car-multihash-index-sorted", 0x0401),
+      ("transport-bitswap", 0x0900),
+      ("transport-graphsync-filecoinv1", 0x0910),
+      ("transport-ipfs-gateway-http", 0x0920),
+      ("transport-filecoin-piece-http", 0x0930),
+      ("multidid", 0x0d1d),
+      ("fr32-sha256-trunc254-padbintree", 0x1011),
+      ("sha2-256-trunc254-padded", 0x1012),
+      ("sha2-224", 0x1013),
+      ("sha2-512-224", 0x1014),
+      ("sha2-512-256", 0x1015),
+      ("murmur3-x64-128", 0x1022),
+      ("ripemd-128", 0x1052),
+      ("ripemd-160", 0x1053),
+      ("ripemd-256", 0x1054),
+      ("ripemd-320", 0x1055),
+      ("x11", 0x1100),
+      ("p256-pub", 0x1200),
+      ("p384-pub", 0x1201),
+      ("p521-pub", 0x1202),
+      ("ed448-pub", 0x1203),
+      ("x448-pub", 0x1204),
+      ("rsa-pub", 0x1205),
+      ("sm2-pub", 0x1206),
+      ("vlad", 0x1207),
+      ("provenance-log", 0x1208),
+      ("provenance-log-entry", 0x1209),
+      ("provenance-log-script", 0x120a),
+      ("mlkem-512-pub", 0x120b),
+      ("mlkem-768-pub", 0x120c),
+      ("mlkem-1024-pub", 0x120d),
+      ("mldsa-44-pub", 0x1210),
+      ("mldsa-65-pub", 0x1211),
+      ("mldsa-87-pub", 0x1212),
+      ("slhdsa-sha2-128s-pub", 0x1220),
+      ("slhdsa-shake-128s-pub", 0x1221),
+      ("slhdsa-sha2-128f-pub", 0x1222),
+      ("slhdsa-shake-128f-pub", 0x1223),
+      ("slhdsa-sha2-192s-pub", 0x1224),
+      ("slhdsa-shake-192s-pub", 0x1225),
+      ("slhdsa-sha2-192f-pub", 0x1226),
+      ("slhdsa-shake-192f-pub", 0x1227),
+      ("slhdsa-sha2-256s-pub", 0x1228),
+      ("slhdsa-shake-256s-pub", 0x1229),
+      ("slhdsa-sha2-256f-pub", 0x122a),
+      ("slhdsa-shake-256f-pub", 0x122b),
+      ("multisig", 0x1239),
+      ("multikey", 0x123a),
+      ("nonce", 0x123b),
+      ("ed25519-priv", 0x1300),
+      ("secp256k1-priv", 0x1301),
+      ("x25519-priv", 0x1302),
+      ("sr25519-priv", 0x1303),
+      ("rsa-priv", 0x1305),
+      ("p256-priv", 0x1306),
+      ("p384-priv", 0x1307),
+      ("p521-priv", 0x1308),
+      ("bls12_381-g1-priv", 0x1309),
+      ("bls12_381-g2-priv", 0x130a),
+      ("bls12_381-g1g2-priv", 0x130b),
+      ("bls12_381-g1-pub-share", 0x130c),
+      ("bls12_381-g2-pub-share", 0x130d),
+      ("bls12_381-g1-priv-share", 0x130e),
+      ("bls12_381-g2-priv-share", 0x130f),
+      ("sm2-priv", 0x1310),
+      ("ed448-priv", 0x1311),
+      ("x448-priv", 0x1312),
+      ("mlkem-512-priv", 0x1313),
+      ("mlkem-768-priv", 0x1314),
+      ("mlkem-1024-priv", 0x1315),
+      ("jwk_jcs-priv", 0x1316),
+      ("lamport-sha3-512-pub", 0x1a14),
+      ("lamport-sha3-384-pub", 0x1a15),
+      ("lamport-sha3-256-pub", 0x1a16),
+      ("lamport-sha3-512-priv", 0x1a24),
+      ("lamport-sha3-384-priv", 0x1a25),
+      ("lamport-sha3-256-priv", 0x1a26),
+      ("lamport-sha3-512-priv-share", 0x1a34),
+      ("lamport-sha3-384-priv-share", 0x1a35),
+      ("lamport-sha3-256-priv-share", 0x1a36),
+      ("lamport-sha3-512-sig", 0x1a44),
+      ("lamport-sha3-384-sig", 0x1a45),
+      ("lamport-sha3-256-sig", 0x1a46),
+      ("lamport-sha3-512-sig-share", 0x1a54),
+      ("lamport-sha3-384-sig-share", 0x1a55),
+      ("lamport-sha3-256-sig-share", 0x1a56),
+      ("kangarootwelve", 0x1d01),
+      ("aes-gcm-256", 0x2000),
+      ("silverpine", 0x3f42),
+      ("sm3-256", 0x534d),
+      ("sha256a", 0x7012),
+      ("chacha20-poly1305", 0xa000),
+      ("blake2b-8", 0xb201),
+      ("blake2b-16", 0xb202),
+      ("blake2b-24", 0xb203),
+      ("blake2b-32", 0xb204),
+      ("blake2b-40", 0xb205),
+      ("blake2b-48", 0xb206),
+      ("blake2b-56", 0xb207),
+      ("blake2b-64", 0xb208),
+      ("blake2b-72", 0xb209),
+      ("blake2b-80", 0xb20a),
+      ("blake2b-88", 0xb20b),
+      ("blake2b-96", 0xb20c),
+      ("blake2b-104", 0xb20d),
+      ("blake2b-112", 0xb20e),
+      ("blake2b-120", 0xb20f),
+      ("blake2b-128", 0xb210),
+      ("blake2b-136", 0xb211),
+      ("blake2b-144", 0xb212),
+      ("blake2b-152", 0xb213),
+      ("blake2b-160", 0xb214),
+      ("blake2b-168", 0xb215),
+      ("blake2b-176", 0xb216),
+      ("blake2b-184", 0xb217),
+      ("blake2b-192", 0xb218),
+      ("blake2b-200", 0xb219),
+      ("blake2b-208", 0xb21a),
+      ("blake2b-216", 0xb21b),
+      ("blake2b-224", 0xb21c),
+      ("blake2b-232", 0xb21d),
+      ("blake2b-240", 0xb21e),
+      ("blake2b-248", 0xb21f),
+      ("blake2b-256", 0xb220),
+      ("blake2b-264", 0xb221),
+      ("blake2b-272", 0xb222),
+      ("blake2b-280", 0xb223),
+      ("blake2b-288", 0xb224),
+      ("blake2b-296", 0xb225),
+      ("blake2b-304", 0xb226),
+      ("blake2b-312", 0xb227),
+      ("blake2b-320", 0xb228),
+      ("blake2b-328", 0xb229),
+      ("blake2b-336", 0xb22a),
+      ("blake2b-344", 0xb22b),
+      ("blake2b-352", 0xb22c),
+      ("blake2b-360", 0xb22d),
+      ("blake2b-368", 0xb22e),
+      ("blake2b-376", 0xb22f),
+      ("blake2b-384", 0xb230),
+      ("blake2b-392", 0xb231),
+      ("blake2b-400", 0xb232),
+      ("blake2b-408", 0xb233),
+      ("blake2b-416", 0xb234),
+      ("blake2b-424", 0xb235),
+      ("blake2b-432", 0xb236),
+      ("blake2b-440", 0xb237),
+      ("blake2b-448", 0xb238),
+      ("blake2b-456", 0xb239),
+      ("blake2b-464", 0xb23a),
+      ("blake2b-472", 0xb23b),
+      ("blake2b-480", 0xb23c),
+      ("blake2b-488", 0xb23d),
+      ("blake2b-496", 0xb23e),
+      ("blake2b-504", 0xb23f),
+      ("blake2b-512", 0xb240),
+      ("blake2s-8", 0xb241),
+      ("blake2s-16", 0xb242),
+      ("blake2s-24", 0xb243),
+      ("blake2s-32", 0xb244),
+      ("blake2s-40", 0xb245),
+      ("blake2s-48", 0xb246),
+      ("blake2s-56", 0xb247),
+      ("blake2s-64", 0xb248),
+      ("blake2s-72", 0xb249),
+      ("blake2s-80", 0xb24a),
+      ("blake2s-88", 0xb24b),
+      ("blake2s-96", 0xb24c),
+      ("blake2s-104", 0xb24d),
+      ("blake2s-112", 0xb24e),
+      ("blake2s-120", 0xb24f),
+      ("blake2s-128", 0xb250),
+      ("blake2s-136", 0xb251),
+      ("blake2s-144", 0xb252),
+      ("blake2s-152", 0xb253),
+      ("blake2s-160", 0xb254),
+      ("blake2s-168", 0xb255),
+      ("blake2s-176", 0xb256),
+      ("blake2s-184", 0xb257),
+      ("blake2s-192", 0xb258),
+      ("blake2s-200", 0xb259),
+      ("blake2s-208", 0xb25a),
+      ("blake2s-216", 0xb25b),
+      ("blake2s-224", 0xb25c),
+      ("blake2s-232", 0xb25d),
+      ("blake2s-240", 0xb25e),
+      ("blake2s-248", 0xb25f),
+      ("blake2s-256", 0xb260),
+      ("skein256-8", 0xb301),
+      ("skein256-16", 0xb302),
+      ("skein256-24", 0xb303),
+      ("skein256-32", 0xb304),
+      ("skein256-40", 0xb305),
+      ("skein256-48", 0xb306),
+      ("skein256-56", 0xb307),
+      ("skein256-64", 0xb308),
+      ("skein256-72", 0xb309),
+      ("skein256-80", 0xb30a),
+      ("skein256-88", 0xb30b),
+      ("skein256-96", 0xb30c),
+      ("skein256-104", 0xb30d),
+      ("skein256-112", 0xb30e),
+      ("skein256-120", 0xb30f),
+      ("skein256-128", 0xb310),
+      ("skein256-136", 0xb311),
+      ("skein256-144", 0xb312),
+      ("skein256-152", 0xb313),
+      ("skein256-160", 0xb314),
+      ("skein256-168", 0xb315),
+      ("skein256-176", 0xb316),
+      ("skein256-184", 0xb317),
+      ("skein256-192", 0xb318),
+      ("skein256-200", 0xb319),
+      ("skein256-208", 0xb31a),
+      ("skein256-216", 0xb31b),
+      ("skein256-224", 0xb31c),
+      ("skein256-232", 0xb31d),
+      ("skein256-240", 0xb31e),
+      ("skein256-248", 0xb31f),
+      ("skein256-256", 0xb320),
+      ("skein512-8", 0xb321),
+      ("skein512-16", 0xb322),
+      ("skein512-24", 0xb323),
+      ("skein512-32", 0xb324),
+      ("skein512-40", 0xb325),
+      ("skein512-48", 0xb326),
+      ("skein512-56", 0xb327),
+      ("skein512-64", 0xb328),
+      ("skein512-72", 0xb329),
+      ("skein512-80", 0xb32a),
+      ("skein512-88", 0xb32b),
+      ("skein512-96", 0xb32c),
+      ("skein512-104", 0xb32d),
+      ("skein512-112", 0xb32e),
+      ("skein512-120", 0xb32f),
+      ("skein512-128", 0xb330),
+      ("skein512-136", 0xb331),
+      ("skein512-144", 0xb332),
+      ("skein512-152", 0xb333),
+      ("skein512-160", 0xb334),
+      ("skein512-168", 0xb335),
+      ("skein512-176", 0xb336),
+      ("skein512-184", 0xb337),
+      ("skein512-192", 0xb338),
+      ("skein512-200", 0xb339),
+      ("skein512-208", 0xb33a),
+      ("skein512-216", 0xb33b),
+      ("skein512-224", 0xb33c),
+      ("skein512-232", 0xb33d),
+      ("skein512-240", 0xb33e),
+      ("skein512-248", 0xb33f),
+      ("skein512-256", 0xb340),
+      ("skein512-264", 0xb341),
+      ("skein512-272", 0xb342),
+      ("skein512-280", 0xb343),
+      ("skein512-288", 0xb344),
+      ("skein512-296", 0xb345),
+      ("skein512-304", 0xb346),
+      ("skein512-312", 0xb347),
+      ("skein512-320", 0xb348),
+      ("skein512-328", 0xb349),
+      ("skein512-336", 0xb34a),
+      ("skein512-344", 0xb34b),
+      ("skein512-352", 0xb34c),
+      ("skein512-360", 0xb34d),
+      ("skein512-368", 0xb34e),
+      ("skein512-376", 0xb34f),
+      ("skein512-384", 0xb350),
+      ("skein512-392", 0xb351),
+      ("skein512-400", 0xb352),
+      ("skein512-408", 0xb353),
+      ("skein512-416", 0xb354),
+      ("skein512-424", 0xb355),
+      ("skein512-432", 0xb356),
+      ("skein512-440", 0xb357),
+      ("skein512-448", 0xb358),
+      ("skein512-456", 0xb359),
+      ("skein512-464", 0xb35a),
+      ("skein512-472", 0xb35b),
+      ("skein512-480", 0xb35c),
+      ("skein512-488", 0xb35d),
+      ("skein512-496", 0xb35e),
+      ("skein512-504", 0xb35f),
+      ("skein512-512", 0xb360),
+      ("skein1024-8", 0xb361),
+      ("skein1024-16", 0xb362),
+      ("skein1024-24", 0xb363),
+      ("skein1024-32", 0xb364),
+      ("skein1024-40", 0xb365),
+      ("skein1024-48", 0xb366),
+      ("skein1024-56", 0xb367),
+      ("skein1024-64", 0xb368),
+      ("skein1024-72", 0xb369),
+      ("skein1024-80", 0xb36a),
+      ("skein1024-88", 0xb36b),
+      ("skein1024-96", 0xb36c),
+      ("skein1024-104", 0xb36d),
+      ("skein1024-112", 0xb36e),
+      ("skein1024-120", 0xb36f),
+      ("skein1024-128", 0xb370),
+      ("skein1024-136", 0xb371),
+      ("skein1024-144", 0xb372),
+      ("skein1024-152", 0xb373),
+      ("skein1024-160", 0xb374),
+      ("skein1024-168", 0xb375),
+      ("skein1024-176", 0xb376),
+      ("skein1024-184", 0xb377),
+      ("skein1024-192", 0xb378),
+      ("skein1024-200", 0xb379),
+      ("skein1024-208", 0xb37a),
+      ("skein1024-216", 0xb37b),
+      ("skein1024-224", 0xb37c),
+      ("skein1024-232", 0xb37d),
+      ("skein1024-240", 0xb37e),
+      ("skein1024-248", 0xb37f),
+      ("skein1024-256", 0xb380),
+      ("skein1024-264", 0xb381),
+      ("skein1024-272", 0xb382),
+      ("skein1024-280", 0xb383),
+      ("skein1024-288", 0xb384),
+      ("skein1024-296", 0xb385),
+      ("skein1024-304", 0xb386),
+      ("skein1024-312", 0xb387),
+      ("skein1024-320", 0xb388),
+      ("skein1024-328", 0xb389),
+      ("skein1024-336", 0xb38a),
+      ("skein1024-344", 0xb38b),
+      ("skein1024-352", 0xb38c),
+      ("skein1024-360", 0xb38d),
+      ("skein1024-368", 0xb38e),
+      ("skein1024-376", 0xb38f),
+      ("skein1024-384", 0xb390),
+      ("skein1024-392", 0xb391),
+      ("skein1024-400", 0xb392),
+      ("skein1024-408", 0xb393),
+      ("skein1024-416", 0xb394),
+      ("skein1024-424", 0xb395),
+      ("skein1024-432", 0xb396),
+      ("skein1024-440", 0xb397),
+      ("skein1024-448", 0xb398),
+      ("skein1024-456", 0xb399),
+      ("skein1024-464", 0xb39a),
+      ("skein1024-472", 0xb39b),
+      ("skein1024-480", 0xb39c),
+      ("skein1024-488", 0xb39d),
+      ("skein1024-496", 0xb39e),
+      ("skein1024-504", 0xb39f),
+      ("skein1024-512", 0xb3a0),
+      ("skein1024-520", 0xb3a1),
+      ("skein1024-528", 0xb3a2),
+      ("skein1024-536", 0xb3a3),
+      ("skein1024-544", 0xb3a4),
+      ("skein1024-552", 0xb3a5),
+      ("skein1024-560", 0xb3a6),
+      ("skein1024-568", 0xb3a7),
+      ("skein1024-576", 0xb3a8),
+      ("skein1024-584", 0xb3a9),
+      ("skein1024-592", 0xb3aa),
+      ("skein1024-600", 0xb3ab),
+      ("skein1024-608", 0xb3ac),
+      ("skein1024-616", 0xb3ad),
+      ("skein1024-624", 0xb3ae),
+      ("skein1024-632", 0xb3af),
+      ("skein1024-640", 0xb3b0),
+      ("skein1024-648", 0xb3b1),
+      ("skein1024-656", 0xb3b2),
+      ("skein1024-664", 0xb3b3),
+      ("skein1024-672", 0xb3b4),
+      ("skein1024-680", 0xb3b5),
+      ("skein1024-688", 0xb3b6),
+      ("skein1024-696", 0xb3b7),
+      ("skein1024-704", 0xb3b8),
+      ("skein1024-712", 0xb3b9),
+      ("skein1024-720", 0xb3ba),
+      ("skein1024-728", 0xb3bb),
+      ("skein1024-736", 0xb3bc),
+      ("skein1024-744", 0xb3bd),
+      ("skein1024-752", 0xb3be),
+      ("skein1024-760", 0xb3bf),
+      ("skein1024-768", 0xb3c0),
+      ("skein1024-776", 0xb3c1),
+      ("skein1024-784", 0xb3c2),
+      ("skein1024-792", 0xb3c3),
+      ("skein1024-800", 0xb3c4),
+      ("skein1024-808", 0xb3c5),
+      ("skein1024-816", 0xb3c6),
+      ("skein1024-824", 0xb3c7),
+      ("skein1024-832", 0xb3c8),
+      ("skein1024-840", 0xb3c9),
+      ("skein1024-848", 0xb3ca),
+      ("skein1024-856", 0xb3cb),
+      ("skein1024-864", 0xb3cc),
+      ("skein1024-872", 0xb3cd),
+      ("skein1024-880", 0xb3ce),
+      ("skein1024-888", 0xb3cf),
+      ("skein1024-896", 0xb3d0),
+      ("skein1024-904", 0xb3d1),
+      ("skein1024-912", 0xb3d2),
+      ("skein1024-920", 0xb3d3),
+      ("skein1024-928", 0xb3d4),
+      ("skein1024-936", 0xb3d5),
+      ("skein1024-944", 0xb3d6),
+      ("skein1024-952", 0xb3d7),
+      ("skein1024-960", 0xb3d8),
+      ("skein1024-968", 0xb3d9),
+      ("skein1024-976", 0xb3da),
+      ("skein1024-984", 0xb3db),
+      ("skein1024-992", 0xb3dc),
+      ("skein1024-1000", 0xb3dd),
+      ("skein1024-1008", 0xb3de),
+      ("skein1024-1016", 0xb3df),
+      ("skein1024-1024", 0xb3e0),
+      ("xxh-32", 0xb3e1),
+      ("xxh-64", 0xb3e2),
+      ("xxh3-64", 0xb3e3),
+      ("xxh3-128", 0xb3e4),
+      ("poseidon-bls12_381-a2-fc1", 0xb401),
+      ("poseidon-bls12_381-a2-fc1-sc", 0xb402),
+      ("rdfc-1", 0xb403),
+      ("ssz", 0xb501),
+      ("ssz-sha2-256-bmt", 0xb502),
+      ("sha2-256-chunked", 0xb510),
+      ("json-jcs", 0xb601),
+      ("bittorrent-pieces-root", 0xb702),
+      ("iscc", 0xcc01),
+      ("zeroxcert-imprint-256", 0xce11),
+      ("bcrypt-pbkdf", 0xd00d),
+      ("es256k", 0xd0e7),
+      ("bls12_381-g1-sig", 0xd0ea),
+      ("bls12_381-g2-sig", 0xd0eb),
+      ("eddsa", 0xd0ed),
+      ("eip-191", 0xd191),
+      ("jwk_jcs-pub", 0xeb51),
+      ("ed2k", 0xed20),
+      ("fil-commitment-unsealed", 0xf101),
+      ("fil-commitment-sealed", 0xf102),
+      ("shelter-contract-manifest", 0x511e00),
+      ("shelter-contract-text", 0x511e01),
+      ("shelter-contract-data", 0x511e02),
+      ("shelter-file-manifest", 0x511e03),
+      ("shelter-file-chunk", 0x511e04),
+      ("plaintextv2", 0x706c61),
+      ("holochain-adr-v0", 0x807124),
+      ("holochain-adr-v1", 0x817124),
+      ("holochain-key-v0", 0x947124),
+      ("holochain-key-v1", 0x957124),
+      ("holochain-sig-v0", 0xa27124),
+      ("holochain-sig-v1", 0xa37124),
+      ("skynet-ns", 0xb19910),
+      ("arweave-ns", 0xb29910),
+      ("subspace-ns", 0xb39910),
+      ("kumandra-ns", 0xb49910),
+      ("massa", 0xb59910),
+      ("massa-mainnet", 0xb59911),
+      ("massa-buildnet", 0xb59912),
+      ("massa-deweb", 0xb59913),
+      ("massa-gossip", 0xb59914),
+      ("massa-mns", 0xb59915),
+      ("massa-sc", 0xb59916),
+      ("massa-gossip-id", 0xb59917),
+      ("es256", 0xd01200),
+      ("es384", 0xd01201),
+      ("es512", 0xd01202),
+      ("rs256", 0xd01205),
+      ("es256k-msig", 0xd01300),
+      ("bls12_381-g1-msig", 0xd01301),
+      ("bls12_381-g2-msig", 0xd01302),
+      ("eddsa-msig", 0xd01303),
+      ("bls12_381-g1-share-msig", 0xd01304),
+      ("bls12_381-g2-share-msig", 0xd01305),
+      ("lamport-msig", 0xd01306),
+      ("lamport-share-msig", 0xd01307),
+      ("es256-msig", 0xd01308),
+      ("es384-msig", 0xd01309),
+      ("es521-msig", 0xd0130a),
+      ("rs256-msig", 0xd0130b),
+      ("scion", 0xd02000)
+    ]
+
+codecToName :: Map VarInt String
+codecToName =
+  LazyMap.fromList
+    [ (0x00, "identity"),
+      (0x01, "cidv1"),
+      (0x02, "cidv2"),
+      (0x03, "cidv3"),
+      (0x04, "ip4"),
+      (0x06, "tcp"),
+      (0x11, "sha1"),
+      (0x12, "sha2-256"),
+      (0x13, "sha2-512"),
+      (0x14, "sha3-512"),
+      (0x15, "sha3-384"),
+      (0x16, "sha3-256"),
+      (0x17, "sha3-224"),
+      (0x18, "shake-128"),
+      (0x19, "shake-256"),
+      (0x1a, "keccak-224"),
+      (0x1b, "keccak-256"),
+      (0x1c, "keccak-384"),
+      (0x1d, "keccak-512"),
+      (0x1e, "blake3"),
+      (0x20, "sha2-384"),
+      (0x21, "dccp"),
+      (0x22, "murmur3-x64-64"),
+      (0x23, "murmur3-32"),
+      (0x29, "ip6"),
+      (0x2a, "ip6zone"),
+      (0x2b, "ipcidr"),
+      (0x2f, "path"),
+      (0x30, "multicodec"),
+      (0x31, "multihash"),
+      (0x32, "multiaddr"),
+      (0x33, "multibase"),
+      (0x34, "varsig"),
+      (0x35, "dns"),
+      (0x36, "dns4"),
+      (0x37, "dns6"),
+      (0x38, "dnsaddr"),
+      (0x50, "protobuf"),
+      (0x51, "cbor"),
+      (0x55, "raw"),
+      (0x56, "dbl-sha2-256"),
+      (0x60, "rlp"),
+      (0x63, "bencode"),
+      (0x70, "dag-pb"),
+      (0x71, "dag-cbor"),
+      (0x72, "libp2p-key"),
+      (0x78, "git-raw"),
+      (0x7b, "torrent-info"),
+      (0x7c, "torrent-file"),
+      (0x80, "blake3-hashseq"),
+      (0x81, "leofcoin-block"),
+      (0x82, "leofcoin-tx"),
+      (0x83, "leofcoin-pr"),
+      (0x84, "sctp"),
+      (0x85, "dag-jose"),
+      (0x86, "dag-cose"),
+      (0x8c, "lbry"),
+      (0x90, "eth-block"),
+      (0x91, "eth-block-list"),
+      (0x92, "eth-tx-trie"),
+      (0x93, "eth-tx"),
+      (0x94, "eth-tx-receipt-trie"),
+      (0x95, "eth-tx-receipt"),
+      (0x96, "eth-state-trie"),
+      (0x97, "eth-account-snapshot"),
+      (0x98, "eth-storage-trie"),
+      (0x99, "eth-receipt-log-trie"),
+      (0x9a, "eth-receipt-log"),
+      (0xa0, "aes-128"),
+      (0xa1, "aes-192"),
+      (0xa2, "aes-256"),
+      (0xa3, "chacha-128"),
+      (0xa4, "chacha-256"),
+      (0xb0, "bitcoin-block"),
+      (0xb1, "bitcoin-tx"),
+      (0xb2, "bitcoin-witness-commitment"),
+      (0xc0, "zcash-block"),
+      (0xc1, "zcash-tx"),
+      (0xca, "caip-50"),
+      (0xce, "streamid"),
+      (0xd0, "stellar-block"),
+      (0xd1, "stellar-tx"),
+      (0xd4, "md4"),
+      (0xd5, "md5"),
+      (0xe0, "decred-block"),
+      (0xe1, "decred-tx"),
+      (0xe2, "ipld"),
+      (0xe3, "ipfs"),
+      (0xe4, "swarm"),
+      (0xe5, "ipns"),
+      (0xe6, "zeronet"),
+      (0xe7, "secp256k1-pub"),
+      (0xe8, "dnslink"),
+      (0xea, "bls12_381-g1-pub"),
+      (0xeb, "bls12_381-g2-pub"),
+      (0xec, "x25519-pub"),
+      (0xed, "ed25519-pub"),
+      (0xee, "bls12_381-g1g2-pub"),
+      (0xef, "sr25519-pub"),
+      (0xf0, "dash-block"),
+      (0xf1, "dash-tx"),
+      (0xfa, "swarm-manifest"),
+      (0xfb, "swarm-feed"),
+      (0xfc, "beeson"),
+      (0x0111, "udp"),
+      (0x0118, "webrtc-direct"),
+      (0x0119, "webrtc"),
+      (0x0122, "p2p-circuit"),
+      (0x0129, "dag-json"),
+      (0x012d, "udt"),
+      (0x012e, "utp"),
+      (0x0132, "crc32"),
+      (0x0164, "crc64-ecma"),
+      (0x0165, "crc64-nvme"),
+      (0x0190, "unix"),
+      (0x0196, "thread"),
+      (0x01a5, "p2p"),
+      (0x01bb, "https"),
+      (0x01bc, "onion"),
+      (0x01bd, "onion3"),
+      (0x01be, "garlic64"),
+      (0x01bf, "garlic32"),
+      (0x01c0, "tls"),
+      (0x01c1, "sni"),
+      (0x01c6, "noise"),
+      (0x01c8, "shs"),
+      (0x01cc, "quic"),
+      (0x01cd, "quic-v1"),
+      (0x01d1, "webtransport"),
+      (0x01d2, "certhash"),
+      (0x01dd, "ws"),
+      (0x01de, "wss"),
+      (0x01df, "p2p-websocket-star"),
+      (0x01e0, "http"),
+      (0x01e1, "http-path"),
+      (0x01f0, "swhid-1-snp"),
+      (0x0200, "json"),
+      (0x0201, "messagepack"),
+      (0x0202, "car"),
+      (0x0210, "x509-certificate"),
+      (0x0300, "ipns-record"),
+      (0x0301, "libp2p-peer-record"),
+      (0x0302, "libp2p-relay-rsvp"),
+      (0x0309, "memorytransport"),
+      (0x0400, "car-index-sorted"),
+      (0x0401, "car-multihash-index-sorted"),
+      (0x0900, "transport-bitswap"),
+      (0x0910, "transport-graphsync-filecoinv1"),
+      (0x0920, "transport-ipfs-gateway-http"),
+      (0x0930, "transport-filecoin-piece-http"),
+      (0x0d1d, "multidid"),
+      (0x1011, "fr32-sha256-trunc254-padbintree"),
+      (0x1012, "sha2-256-trunc254-padded"),
+      (0x1013, "sha2-224"),
+      (0x1014, "sha2-512-224"),
+      (0x1015, "sha2-512-256"),
+      (0x1022, "murmur3-x64-128"),
+      (0x1052, "ripemd-128"),
+      (0x1053, "ripemd-160"),
+      (0x1054, "ripemd-256"),
+      (0x1055, "ripemd-320"),
+      (0x1100, "x11"),
+      (0x1200, "p256-pub"),
+      (0x1201, "p384-pub"),
+      (0x1202, "p521-pub"),
+      (0x1203, "ed448-pub"),
+      (0x1204, "x448-pub"),
+      (0x1205, "rsa-pub"),
+      (0x1206, "sm2-pub"),
+      (0x1207, "vlad"),
+      (0x1208, "provenance-log"),
+      (0x1209, "provenance-log-entry"),
+      (0x120a, "provenance-log-script"),
+      (0x120b, "mlkem-512-pub"),
+      (0x120c, "mlkem-768-pub"),
+      (0x120d, "mlkem-1024-pub"),
+      (0x1210, "mldsa-44-pub"),
+      (0x1211, "mldsa-65-pub"),
+      (0x1212, "mldsa-87-pub"),
+      (0x1220, "slhdsa-sha2-128s-pub"),
+      (0x1221, "slhdsa-shake-128s-pub"),
+      (0x1222, "slhdsa-sha2-128f-pub"),
+      (0x1223, "slhdsa-shake-128f-pub"),
+      (0x1224, "slhdsa-sha2-192s-pub"),
+      (0x1225, "slhdsa-shake-192s-pub"),
+      (0x1226, "slhdsa-sha2-192f-pub"),
+      (0x1227, "slhdsa-shake-192f-pub"),
+      (0x1228, "slhdsa-sha2-256s-pub"),
+      (0x1229, "slhdsa-shake-256s-pub"),
+      (0x122a, "slhdsa-sha2-256f-pub"),
+      (0x122b, "slhdsa-shake-256f-pub"),
+      (0x1239, "multisig"),
+      (0x123a, "multikey"),
+      (0x123b, "nonce"),
+      (0x1300, "ed25519-priv"),
+      (0x1301, "secp256k1-priv"),
+      (0x1302, "x25519-priv"),
+      (0x1303, "sr25519-priv"),
+      (0x1305, "rsa-priv"),
+      (0x1306, "p256-priv"),
+      (0x1307, "p384-priv"),
+      (0x1308, "p521-priv"),
+      (0x1309, "bls12_381-g1-priv"),
+      (0x130a, "bls12_381-g2-priv"),
+      (0x130b, "bls12_381-g1g2-priv"),
+      (0x130c, "bls12_381-g1-pub-share"),
+      (0x130d, "bls12_381-g2-pub-share"),
+      (0x130e, "bls12_381-g1-priv-share"),
+      (0x130f, "bls12_381-g2-priv-share"),
+      (0x1310, "sm2-priv"),
+      (0x1311, "ed448-priv"),
+      (0x1312, "x448-priv"),
+      (0x1313, "mlkem-512-priv"),
+      (0x1314, "mlkem-768-priv"),
+      (0x1315, "mlkem-1024-priv"),
+      (0x1316, "jwk_jcs-priv"),
+      (0x1a14, "lamport-sha3-512-pub"),
+      (0x1a15, "lamport-sha3-384-pub"),
+      (0x1a16, "lamport-sha3-256-pub"),
+      (0x1a24, "lamport-sha3-512-priv"),
+      (0x1a25, "lamport-sha3-384-priv"),
+      (0x1a26, "lamport-sha3-256-priv"),
+      (0x1a34, "lamport-sha3-512-priv-share"),
+      (0x1a35, "lamport-sha3-384-priv-share"),
+      (0x1a36, "lamport-sha3-256-priv-share"),
+      (0x1a44, "lamport-sha3-512-sig"),
+      (0x1a45, "lamport-sha3-384-sig"),
+      (0x1a46, "lamport-sha3-256-sig"),
+      (0x1a54, "lamport-sha3-512-sig-share"),
+      (0x1a55, "lamport-sha3-384-sig-share"),
+      (0x1a56, "lamport-sha3-256-sig-share"),
+      (0x1d01, "kangarootwelve"),
+      (0x2000, "aes-gcm-256"),
+      (0x3f42, "silverpine"),
+      (0x534d, "sm3-256"),
+      (0x7012, "sha256a"),
+      (0xa000, "chacha20-poly1305"),
+      (0xb201, "blake2b-8"),
+      (0xb202, "blake2b-16"),
+      (0xb203, "blake2b-24"),
+      (0xb204, "blake2b-32"),
+      (0xb205, "blake2b-40"),
+      (0xb206, "blake2b-48"),
+      (0xb207, "blake2b-56"),
+      (0xb208, "blake2b-64"),
+      (0xb209, "blake2b-72"),
+      (0xb20a, "blake2b-80"),
+      (0xb20b, "blake2b-88"),
+      (0xb20c, "blake2b-96"),
+      (0xb20d, "blake2b-104"),
+      (0xb20e, "blake2b-112"),
+      (0xb20f, "blake2b-120"),
+      (0xb210, "blake2b-128"),
+      (0xb211, "blake2b-136"),
+      (0xb212, "blake2b-144"),
+      (0xb213, "blake2b-152"),
+      (0xb214, "blake2b-160"),
+      (0xb215, "blake2b-168"),
+      (0xb216, "blake2b-176"),
+      (0xb217, "blake2b-184"),
+      (0xb218, "blake2b-192"),
+      (0xb219, "blake2b-200"),
+      (0xb21a, "blake2b-208"),
+      (0xb21b, "blake2b-216"),
+      (0xb21c, "blake2b-224"),
+      (0xb21d, "blake2b-232"),
+      (0xb21e, "blake2b-240"),
+      (0xb21f, "blake2b-248"),
+      (0xb220, "blake2b-256"),
+      (0xb221, "blake2b-264"),
+      (0xb222, "blake2b-272"),
+      (0xb223, "blake2b-280"),
+      (0xb224, "blake2b-288"),
+      (0xb225, "blake2b-296"),
+      (0xb226, "blake2b-304"),
+      (0xb227, "blake2b-312"),
+      (0xb228, "blake2b-320"),
+      (0xb229, "blake2b-328"),
+      (0xb22a, "blake2b-336"),
+      (0xb22b, "blake2b-344"),
+      (0xb22c, "blake2b-352"),
+      (0xb22d, "blake2b-360"),
+      (0xb22e, "blake2b-368"),
+      (0xb22f, "blake2b-376"),
+      (0xb230, "blake2b-384"),
+      (0xb231, "blake2b-392"),
+      (0xb232, "blake2b-400"),
+      (0xb233, "blake2b-408"),
+      (0xb234, "blake2b-416"),
+      (0xb235, "blake2b-424"),
+      (0xb236, "blake2b-432"),
+      (0xb237, "blake2b-440"),
+      (0xb238, "blake2b-448"),
+      (0xb239, "blake2b-456"),
+      (0xb23a, "blake2b-464"),
+      (0xb23b, "blake2b-472"),
+      (0xb23c, "blake2b-480"),
+      (0xb23d, "blake2b-488"),
+      (0xb23e, "blake2b-496"),
+      (0xb23f, "blake2b-504"),
+      (0xb240, "blake2b-512"),
+      (0xb241, "blake2s-8"),
+      (0xb242, "blake2s-16"),
+      (0xb243, "blake2s-24"),
+      (0xb244, "blake2s-32"),
+      (0xb245, "blake2s-40"),
+      (0xb246, "blake2s-48"),
+      (0xb247, "blake2s-56"),
+      (0xb248, "blake2s-64"),
+      (0xb249, "blake2s-72"),
+      (0xb24a, "blake2s-80"),
+      (0xb24b, "blake2s-88"),
+      (0xb24c, "blake2s-96"),
+      (0xb24d, "blake2s-104"),
+      (0xb24e, "blake2s-112"),
+      (0xb24f, "blake2s-120"),
+      (0xb250, "blake2s-128"),
+      (0xb251, "blake2s-136"),
+      (0xb252, "blake2s-144"),
+      (0xb253, "blake2s-152"),
+      (0xb254, "blake2s-160"),
+      (0xb255, "blake2s-168"),
+      (0xb256, "blake2s-176"),
+      (0xb257, "blake2s-184"),
+      (0xb258, "blake2s-192"),
+      (0xb259, "blake2s-200"),
+      (0xb25a, "blake2s-208"),
+      (0xb25b, "blake2s-216"),
+      (0xb25c, "blake2s-224"),
+      (0xb25d, "blake2s-232"),
+      (0xb25e, "blake2s-240"),
+      (0xb25f, "blake2s-248"),
+      (0xb260, "blake2s-256"),
+      (0xb301, "skein256-8"),
+      (0xb302, "skein256-16"),
+      (0xb303, "skein256-24"),
+      (0xb304, "skein256-32"),
+      (0xb305, "skein256-40"),
+      (0xb306, "skein256-48"),
+      (0xb307, "skein256-56"),
+      (0xb308, "skein256-64"),
+      (0xb309, "skein256-72"),
+      (0xb30a, "skein256-80"),
+      (0xb30b, "skein256-88"),
+      (0xb30c, "skein256-96"),
+      (0xb30d, "skein256-104"),
+      (0xb30e, "skein256-112"),
+      (0xb30f, "skein256-120"),
+      (0xb310, "skein256-128"),
+      (0xb311, "skein256-136"),
+      (0xb312, "skein256-144"),
+      (0xb313, "skein256-152"),
+      (0xb314, "skein256-160"),
+      (0xb315, "skein256-168"),
+      (0xb316, "skein256-176"),
+      (0xb317, "skein256-184"),
+      (0xb318, "skein256-192"),
+      (0xb319, "skein256-200"),
+      (0xb31a, "skein256-208"),
+      (0xb31b, "skein256-216"),
+      (0xb31c, "skein256-224"),
+      (0xb31d, "skein256-232"),
+      (0xb31e, "skein256-240"),
+      (0xb31f, "skein256-248"),
+      (0xb320, "skein256-256"),
+      (0xb321, "skein512-8"),
+      (0xb322, "skein512-16"),
+      (0xb323, "skein512-24"),
+      (0xb324, "skein512-32"),
+      (0xb325, "skein512-40"),
+      (0xb326, "skein512-48"),
+      (0xb327, "skein512-56"),
+      (0xb328, "skein512-64"),
+      (0xb329, "skein512-72"),
+      (0xb32a, "skein512-80"),
+      (0xb32b, "skein512-88"),
+      (0xb32c, "skein512-96"),
+      (0xb32d, "skein512-104"),
+      (0xb32e, "skein512-112"),
+      (0xb32f, "skein512-120"),
+      (0xb330, "skein512-128"),
+      (0xb331, "skein512-136"),
+      (0xb332, "skein512-144"),
+      (0xb333, "skein512-152"),
+      (0xb334, "skein512-160"),
+      (0xb335, "skein512-168"),
+      (0xb336, "skein512-176"),
+      (0xb337, "skein512-184"),
+      (0xb338, "skein512-192"),
+      (0xb339, "skein512-200"),
+      (0xb33a, "skein512-208"),
+      (0xb33b, "skein512-216"),
+      (0xb33c, "skein512-224"),
+      (0xb33d, "skein512-232"),
+      (0xb33e, "skein512-240"),
+      (0xb33f, "skein512-248"),
+      (0xb340, "skein512-256"),
+      (0xb341, "skein512-264"),
+      (0xb342, "skein512-272"),
+      (0xb343, "skein512-280"),
+      (0xb344, "skein512-288"),
+      (0xb345, "skein512-296"),
+      (0xb346, "skein512-304"),
+      (0xb347, "skein512-312"),
+      (0xb348, "skein512-320"),
+      (0xb349, "skein512-328"),
+      (0xb34a, "skein512-336"),
+      (0xb34b, "skein512-344"),
+      (0xb34c, "skein512-352"),
+      (0xb34d, "skein512-360"),
+      (0xb34e, "skein512-368"),
+      (0xb34f, "skein512-376"),
+      (0xb350, "skein512-384"),
+      (0xb351, "skein512-392"),
+      (0xb352, "skein512-400"),
+      (0xb353, "skein512-408"),
+      (0xb354, "skein512-416"),
+      (0xb355, "skein512-424"),
+      (0xb356, "skein512-432"),
+      (0xb357, "skein512-440"),
+      (0xb358, "skein512-448"),
+      (0xb359, "skein512-456"),
+      (0xb35a, "skein512-464"),
+      (0xb35b, "skein512-472"),
+      (0xb35c, "skein512-480"),
+      (0xb35d, "skein512-488"),
+      (0xb35e, "skein512-496"),
+      (0xb35f, "skein512-504"),
+      (0xb360, "skein512-512"),
+      (0xb361, "skein1024-8"),
+      (0xb362, "skein1024-16"),
+      (0xb363, "skein1024-24"),
+      (0xb364, "skein1024-32"),
+      (0xb365, "skein1024-40"),
+      (0xb366, "skein1024-48"),
+      (0xb367, "skein1024-56"),
+      (0xb368, "skein1024-64"),
+      (0xb369, "skein1024-72"),
+      (0xb36a, "skein1024-80"),
+      (0xb36b, "skein1024-88"),
+      (0xb36c, "skein1024-96"),
+      (0xb36d, "skein1024-104"),
+      (0xb36e, "skein1024-112"),
+      (0xb36f, "skein1024-120"),
+      (0xb370, "skein1024-128"),
+      (0xb371, "skein1024-136"),
+      (0xb372, "skein1024-144"),
+      (0xb373, "skein1024-152"),
+      (0xb374, "skein1024-160"),
+      (0xb375, "skein1024-168"),
+      (0xb376, "skein1024-176"),
+      (0xb377, "skein1024-184"),
+      (0xb378, "skein1024-192"),
+      (0xb379, "skein1024-200"),
+      (0xb37a, "skein1024-208"),
+      (0xb37b, "skein1024-216"),
+      (0xb37c, "skein1024-224"),
+      (0xb37d, "skein1024-232"),
+      (0xb37e, "skein1024-240"),
+      (0xb37f, "skein1024-248"),
+      (0xb380, "skein1024-256"),
+      (0xb381, "skein1024-264"),
+      (0xb382, "skein1024-272"),
+      (0xb383, "skein1024-280"),
+      (0xb384, "skein1024-288"),
+      (0xb385, "skein1024-296"),
+      (0xb386, "skein1024-304"),
+      (0xb387, "skein1024-312"),
+      (0xb388, "skein1024-320"),
+      (0xb389, "skein1024-328"),
+      (0xb38a, "skein1024-336"),
+      (0xb38b, "skein1024-344"),
+      (0xb38c, "skein1024-352"),
+      (0xb38d, "skein1024-360"),
+      (0xb38e, "skein1024-368"),
+      (0xb38f, "skein1024-376"),
+      (0xb390, "skein1024-384"),
+      (0xb391, "skein1024-392"),
+      (0xb392, "skein1024-400"),
+      (0xb393, "skein1024-408"),
+      (0xb394, "skein1024-416"),
+      (0xb395, "skein1024-424"),
+      (0xb396, "skein1024-432"),
+      (0xb397, "skein1024-440"),
+      (0xb398, "skein1024-448"),
+      (0xb399, "skein1024-456"),
+      (0xb39a, "skein1024-464"),
+      (0xb39b, "skein1024-472"),
+      (0xb39c, "skein1024-480"),
+      (0xb39d, "skein1024-488"),
+      (0xb39e, "skein1024-496"),
+      (0xb39f, "skein1024-504"),
+      (0xb3a0, "skein1024-512"),
+      (0xb3a1, "skein1024-520"),
+      (0xb3a2, "skein1024-528"),
+      (0xb3a3, "skein1024-536"),
+      (0xb3a4, "skein1024-544"),
+      (0xb3a5, "skein1024-552"),
+      (0xb3a6, "skein1024-560"),
+      (0xb3a7, "skein1024-568"),
+      (0xb3a8, "skein1024-576"),
+      (0xb3a9, "skein1024-584"),
+      (0xb3aa, "skein1024-592"),
+      (0xb3ab, "skein1024-600"),
+      (0xb3ac, "skein1024-608"),
+      (0xb3ad, "skein1024-616"),
+      (0xb3ae, "skein1024-624"),
+      (0xb3af, "skein1024-632"),
+      (0xb3b0, "skein1024-640"),
+      (0xb3b1, "skein1024-648"),
+      (0xb3b2, "skein1024-656"),
+      (0xb3b3, "skein1024-664"),
+      (0xb3b4, "skein1024-672"),
+      (0xb3b5, "skein1024-680"),
+      (0xb3b6, "skein1024-688"),
+      (0xb3b7, "skein1024-696"),
+      (0xb3b8, "skein1024-704"),
+      (0xb3b9, "skein1024-712"),
+      (0xb3ba, "skein1024-720"),
+      (0xb3bb, "skein1024-728"),
+      (0xb3bc, "skein1024-736"),
+      (0xb3bd, "skein1024-744"),
+      (0xb3be, "skein1024-752"),
+      (0xb3bf, "skein1024-760"),
+      (0xb3c0, "skein1024-768"),
+      (0xb3c1, "skein1024-776"),
+      (0xb3c2, "skein1024-784"),
+      (0xb3c3, "skein1024-792"),
+      (0xb3c4, "skein1024-800"),
+      (0xb3c5, "skein1024-808"),
+      (0xb3c6, "skein1024-816"),
+      (0xb3c7, "skein1024-824"),
+      (0xb3c8, "skein1024-832"),
+      (0xb3c9, "skein1024-840"),
+      (0xb3ca, "skein1024-848"),
+      (0xb3cb, "skein1024-856"),
+      (0xb3cc, "skein1024-864"),
+      (0xb3cd, "skein1024-872"),
+      (0xb3ce, "skein1024-880"),
+      (0xb3cf, "skein1024-888"),
+      (0xb3d0, "skein1024-896"),
+      (0xb3d1, "skein1024-904"),
+      (0xb3d2, "skein1024-912"),
+      (0xb3d3, "skein1024-920"),
+      (0xb3d4, "skein1024-928"),
+      (0xb3d5, "skein1024-936"),
+      (0xb3d6, "skein1024-944"),
+      (0xb3d7, "skein1024-952"),
+      (0xb3d8, "skein1024-960"),
+      (0xb3d9, "skein1024-968"),
+      (0xb3da, "skein1024-976"),
+      (0xb3db, "skein1024-984"),
+      (0xb3dc, "skein1024-992"),
+      (0xb3dd, "skein1024-1000"),
+      (0xb3de, "skein1024-1008"),
+      (0xb3df, "skein1024-1016"),
+      (0xb3e0, "skein1024-1024"),
+      (0xb3e1, "xxh-32"),
+      (0xb3e2, "xxh-64"),
+      (0xb3e3, "xxh3-64"),
+      (0xb3e4, "xxh3-128"),
+      (0xb401, "poseidon-bls12_381-a2-fc1"),
+      (0xb402, "poseidon-bls12_381-a2-fc1-sc"),
+      (0xb403, "rdfc-1"),
+      (0xb501, "ssz"),
+      (0xb502, "ssz-sha2-256-bmt"),
+      (0xb510, "sha2-256-chunked"),
+      (0xb601, "json-jcs"),
+      (0xb702, "bittorrent-pieces-root"),
+      (0xcc01, "iscc"),
+      (0xce11, "zeroxcert-imprint-256"),
+      (0xd00d, "bcrypt-pbkdf"),
+      (0xd0e7, "es256k"),
+      (0xd0ea, "bls12_381-g1-sig"),
+      (0xd0eb, "bls12_381-g2-sig"),
+      (0xd0ed, "eddsa"),
+      (0xd191, "eip-191"),
+      (0xeb51, "jwk_jcs-pub"),
+      (0xed20, "ed2k"),
+      (0xf101, "fil-commitment-unsealed"),
+      (0xf102, "fil-commitment-sealed"),
+      (0x511e00, "shelter-contract-manifest"),
+      (0x511e01, "shelter-contract-text"),
+      (0x511e02, "shelter-contract-data"),
+      (0x511e03, "shelter-file-manifest"),
+      (0x511e04, "shelter-file-chunk"),
+      (0x706c61, "plaintextv2"),
+      (0x807124, "holochain-adr-v0"),
+      (0x817124, "holochain-adr-v1"),
+      (0x947124, "holochain-key-v0"),
+      (0x957124, "holochain-key-v1"),
+      (0xa27124, "holochain-sig-v0"),
+      (0xa37124, "holochain-sig-v1"),
+      (0xb19910, "skynet-ns"),
+      (0xb29910, "arweave-ns"),
+      (0xb39910, "subspace-ns"),
+      (0xb49910, "kumandra-ns"),
+      (0xb59910, "massa"),
+      (0xb59911, "massa-mainnet"),
+      (0xb59912, "massa-buildnet"),
+      (0xb59913, "massa-deweb"),
+      (0xb59914, "massa-gossip"),
+      (0xb59915, "massa-mns"),
+      (0xb59916, "massa-sc"),
+      (0xb59917, "massa-gossip-id"),
+      (0xd01200, "es256"),
+      (0xd01201, "es384"),
+      (0xd01202, "es512"),
+      (0xd01205, "rs256"),
+      (0xd01300, "es256k-msig"),
+      (0xd01301, "bls12_381-g1-msig"),
+      (0xd01302, "bls12_381-g2-msig"),
+      (0xd01303, "eddsa-msig"),
+      (0xd01304, "bls12_381-g1-share-msig"),
+      (0xd01305, "bls12_381-g2-share-msig"),
+      (0xd01306, "lamport-msig"),
+      (0xd01307, "lamport-share-msig"),
+      (0xd01308, "es256-msig"),
+      (0xd01309, "es384-msig"),
+      (0xd0130a, "es521-msig"),
+      (0xd0130b, "rs256-msig"),
+      (0xd02000, "scion")
+    ]
diff --git a/multihash/MultiFormats/MultiHash.hs b/multihash/MultiFormats/MultiHash.hs
new file mode 100644
--- /dev/null
+++ b/multihash/MultiFormats/MultiHash.hs
@@ -0,0 +1,104 @@
+-- | Module      : MultiFormats.MultiHash
+--   Description : Associates multicodec values with their hash functions.
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- Provides a lookup table to verify multicodec values as multihashes and a way
+-- to resolve hash functions from multicodecs or their multicodec name. See:
+-- https://github.com/multiformats/multihash
+module MultiFormats.MultiHash
+  ( MultiHash (MultiHash, multiHashCodec, multiHashFunction),
+    resolveHashCodec,
+    resolveHashName,
+  )
+where
+
+import Control.Monad (join)
+import Crypto.Hash (HashAlgorithm)
+import Crypto.Hash qualified as HF
+import Crypto.Hash.Algorithms qualified as Algo
+import Data.ByteArray qualified as Memory
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import Data.Function (on)
+import Data.Map (Map)
+import Data.Map qualified as LazyMap
+import Data.Maybe (fromMaybe, mapMaybe)
+import MultiFormats.MultiCodec (MultiCodec (..), resolveCodecName, resolveCodecValue)
+import Text.Printf (printf)
+
+-- | Alias for the type of function signture we want from a hash function.
+type HashFunction = ByteString -> ByteString
+
+-- | Forms the MultiHash implementaton.
+data MultiHash = MultiHash
+  { -- | Stores the MultiCodec associated with multiHashCodec. Used for Eq, Ord.
+    multiHashCodec :: MultiCodec,
+    -- | Lazy loads the hash function when called.
+    multiHashFunction :: ~HashFunction
+  }
+
+instance Show MultiHash where
+  show =
+    printf "MultiHash(%s)"
+      . fromMaybe "<invalid codec>"
+      . resolveCodecName
+      . multiHashCodec
+
+instance Eq MultiHash where
+  (==) = (==) `on` multiHashCodec
+
+instance Ord MultiHash where
+  compare = compare `on` multiHashCodec
+
+-- | Resolves a MultiHash from a MultiCodec.
+resolveHashCodec :: MultiCodec -> Maybe MultiHash
+resolveHashCodec codec =
+  MultiHash codec <$> join (LazyMap.lookup codec hashFunctionTable)
+
+-- | Resolves a MultiHash from MultiCodec name.
+resolveHashName :: String -> Maybe MultiHash
+resolveHashName name = resolveHashCodec =<< resolveCodecValue name
+
+-- Provides an implementation for the given HashAlgorithm.
+hashImpl :: (HashAlgorithm a) => a -> Maybe HashFunction
+hashImpl algo =
+  -- This code is really slow. It copies each byte from Memory to
+  -- a new ByteString. I wonder if I can take the pointer from Memory and
+  -- assign it to a ByteString for O(1) conversion. Or if we can convince the
+  -- compiler that that's all that needs done.
+  return $ Bytes.pack . Memory.unpack . HF.hashWith algo
+
+-- | Resolves all the String names from MultiCodec table and assigns an
+-- implementation of the hash function if it exists
+hashFunctionTable :: Map MultiCodec (Maybe HashFunction)
+hashFunctionTable =
+  -- We want a lazy map so we can skip evaluting hash functions that never get
+  -- looked up, but we have to evaluate all the hash codecs that exist.
+  LazyMap.fromList $
+    -- This should leave the hfuncs unevaluted in the Map.
+    mapMaybe
+      (\(name, hfunc) -> (,hfunc) <$> resolveCodecValue name)
+      [ ("identity", Just id),
+        ("sha1", hashImpl Algo.SHA1),
+        ("sha2-256", hashImpl Algo.SHA256),
+        ("sha2-512", hashImpl Algo.SHA512),
+        ("sha3-256", hashImpl Algo.SHA3_256),
+        ("sha3-512", hashImpl Algo.SHA3_512),
+        ("sha3-224", hashImpl Algo.SHA3_224),
+        ("sha3-384", hashImpl Algo.SHA3_384),
+        ("sha3-512", hashImpl Algo.SHA3_512),
+        ("keccak-224", hashImpl Algo.Keccak_224),
+        ("keccak-256", hashImpl Algo.Keccak_256),
+        ("keccak-384", hashImpl Algo.Keccak_384),
+        ("keccak-512", hashImpl Algo.Keccak_512),
+        ("blake3", Nothing),
+        -- Shake has HashAlgorithms in Algo, but idk how to use them
+        ("shake-128", Nothing),
+        ("shake-256", Nothing),
+        ("md5", hashImpl Algo.MD5),
+        -- This can be implemented w/ composition
+        ("dbl-sha2-256", Nothing)
+      ]
diff --git a/varint/MultiFormats/VarInt.hs b/varint/MultiFormats/VarInt.hs
new file mode 100644
--- /dev/null
+++ b/varint/MultiFormats/VarInt.hs
@@ -0,0 +1,123 @@
+-- | Module      : MultiFormats.VarInt
+--   Description : Implements multiformat's varints
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+--
+-- Implements serialization and extraction for multiformat's unsigned binary
+-- varint spec. See: https://github.com/multiformats/unsigned-varint
+module MultiFormats.VarInt
+  ( VarInt,
+    extractVarInt,
+    serializeVarInt,
+    maxVarInt,
+  )
+where
+
+import Data.Bits ((.&.), (.<<.), (.>>.), (.|.))
+import Data.ByteString (ByteString)
+import Data.ByteString qualified as Bytes
+import Data.Word (Word64, Word8)
+import MultiFormats.VarInt.Errors (Error (..), Okay)
+
+-- | VarInt spec uses unsigned 64 bit integers.
+type VarInt = Word64
+
+-- | Byte with MSB=1.
+msb1 :: Word8
+msb1 = 1 .<<. 7
+
+-- | Byte with LSB=1.
+lsb1 :: Word8
+lsb1 = 1
+
+-- | The value w/ MSB=1 and LSB=1.
+msb1lsb1 :: Word8
+msb1lsb1 = msb1 .|. lsb1
+
+-- | The value that extracts all bits but the MSB.
+masklower :: Word8
+masklower = msb1 - 1
+
+-- | The maximum value the spec allows (2^63-1).
+maxVarInt :: VarInt
+maxVarInt = (1 .<<. 63) - 1
+
+-- | The maximum # of bytes a VarInt can occupy when encoded.
+bytesCapacity :: Int
+bytesCapacity = 9
+
+-- | Splits ByteString into it's first occurring VarInt and the remaining
+-- ByteString after.
+spanVarInt :: ByteString -> Maybe (ByteString, ByteString)
+spanVarInt bytes =
+  -- Collect the bytes with MSB=1.
+  case Bytes.span isMSB1 bytes of
+    -- The varint is the leading bytes with the MSB=1 and a final terminating
+    -- byte with MSB=0.
+    (msb1s, msb0s)
+      -- Verify if a final byte exists.
+      | Bytes.null msb0s -> Nothing
+      -- The loop invariant ensures msb + 1 has MSB=0. Add the last byte with
+      -- splitAt since it is (a lot) more efficent than append.
+      | otherwise -> Just (Bytes.splitAt (Bytes.length msb1s + 1) bytes)
+  where
+    isMSB1 byte = (byte .&. msb1) /= 0
+
+-- | Concats the lower 7 bits from bytes into single int value.
+buildVarInt :: ByteString -> VarInt
+buildVarInt = Bytes.foldr (\byte int -> advance int .|. lower byte) 0
+  where
+    advance int = int .<<. 7
+    lower byte = fromIntegral $ byte .&. masklower
+
+-- | Checks edge case where input is invalid from not being a minimal encoding
+-- of varints, (ie, we can fit 2 bytes of 7 bits into 1 byte of 7 bits). The
+-- only case of this is when a final 0x8100 should be a 0x79... I think!
+nonMinimal :: ByteString -> Bool
+nonMinimal bytes = Bytes.unpack (Bytes.takeEnd 2 bytes) == [msb1lsb1, 0]
+
+-- | Checks if a VarInt encoded ByteString overflows a Word64.
+aboveCapacity :: ByteString -> Bool
+aboveCapacity varbytes =
+  let wholelen = Bytes.length varbytes
+   in not (1 <= wholelen && wholelen <= bytesCapacity)
+
+-- | Extracts the first minimally encoded varint from a ByteString.
+extractVarInt :: ByteString -> Okay (VarInt, ByteString)
+extractVarInt bytes
+  | Bytes.null bytes = Left EmptyBytes
+  | otherwise =
+      case spanVarInt bytes of
+        Nothing -> Left MissingTermination
+        Just (varbytes, rest)
+          | aboveCapacity varbytes -> Left BytesOverflow
+          | nonMinimal varbytes -> Left NotMinimal
+          | otherwise -> Right (buildVarInt varbytes, rest)
+
+-- | Puts a parsed VarInt (Word64, without MSB indicators) into a ByteString
+-- with MSB indicators, and a max size of 9 bytes.
+serializeVarInt :: VarInt -> Okay ByteString
+serializeVarInt varint
+  | varint > maxVarInt = Left AboveMaxValue
+  | otherwise =
+      Right
+        . zeroReplaceNull
+        . Bytes.unfoldr setMSBs
+        . Bytes.dropWhileEnd (== 0)
+        $ Bytes.pack [varintGroup i varint | i <- [1 .. bytesCapacity]]
+  where
+    -- Extracts Nth group of 7 bits from VarInt.
+    varintGroup n var = fromIntegral (var .>>. (7 * (n - 1))) .&. masklower
+    -- Sets MSB=1 for leading bytes in unfoldr.
+    setMSBs bytes =
+      Bytes.uncons bytes >>= \(byte, rest) ->
+        if Bytes.null rest
+          then Just (byte, mempty)
+          else Just (byte .|. msb1, rest)
+    -- Replaces a null ByteString with a single zero.
+    zeroReplaceNull bytes =
+      if Bytes.null bytes
+        then Bytes.singleton 0
+        else bytes
diff --git a/varint/MultiFormats/VarInt/Errors.hs b/varint/MultiFormats/VarInt/Errors.hs
new file mode 100644
--- /dev/null
+++ b/varint/MultiFormats/VarInt/Errors.hs
@@ -0,0 +1,28 @@
+-- | Module      : MultiFormats.VarInt.Errors
+--   Description : Implements errors for MultiFormats.VarInt
+--   Copyright   : Zoey McBride (c) 2026
+--   License     : AGPL-3.0-or-later
+--   Maintainer  : zoeymcbride@mailbox.org
+--   Stability   : experimental
+module MultiFormats.VarInt.Errors
+  ( Error (..),
+    Okay,
+  )
+where
+
+-- | Functor for dealing with VarInt Error results.
+type Okay a = Either Error a
+
+-- | Errors for VarInts.
+data Error
+  = -- | If the provided VarInt ByteString is empty.
+    EmptyBytes
+  | -- | If the VarInt's ByteString is missing the MSB=0 terminating byte.
+    MissingTermination
+  | -- | If the ByteString can't fit the VarInt type.
+    BytesOverflow
+  | -- | If the VarInt violates the minimal encoding property.
+    NotMinimal
+  | -- | If the encoded VarInt is larger than allowed maximum.
+    AboveMaxValue
+  deriving (Eq, Show)
