Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
multi-hash
Rust implementation of the Multihash specification for self-describing cryptographic hash digests.
Multihash is a self-describing format. It pairs a hash algorithm identifier (a multicodec tag) with the raw digest bytes. This lets systems switch hash algorithms without a break in compatibility. The crate gives 23 supported hash algorithms, type-safe wrappers, serde integration, and multibase encoding via the multi-util crate stack.
Table of Contents
- Features
- Install
- Supported Algorithms
- Usage
- Testing
- Feature Flags
- Security
- Maintainers
- Contribute
- License
Features
- 23 hash algorithms. SHA1, SHA2 family, SHA3 family, Blake2, Blake3, MD5, RIPEMD.
- Builder pattern. A fluent API to create multihashes from raw data or existing digests.
- Multibase encoding. The
EncodedMultihashsmart pointer gives a base-encoded string representation viaBaseEncodedfrommulti-util. - Serde support. JSON gives the codec name string. Binary gives the varint bytes. The
serdefeature gates it. - Binary round-trip.
Into<Vec<u8>>andTryFrom<&[u8]>for the raw wire format. - Type-safe newtypes.
HashDigestandAlgorithmIdwrappers. - Zero unsafe code.
#![deny(unsafe_code)]is set at the crate root. - Thread-safe. All types are
Send + Sync.
Install
Add this to your Cargo.toml:
[]
= "1.0"
To disable serde support:
[]
= { = "1.0", = false }
MSRV: Rust 1.85 (Edition 2024).
Supported Algorithms
Secure algorithms (recommended for cryptographic use)
| Algorithm | Codec | Digest Size |
|---|---|---|
| Blake2b-256 | Blake2B256 |
32 bytes |
| Blake2b-384 | Blake2B384 |
48 bytes |
| Blake2b-512 | Blake2B512 |
64 bytes |
| Blake2s-256 | Blake2S256 |
32 bytes |
| Blake3 | Blake3 |
32 bytes |
| SHA3-256 | Sha3256 |
32 bytes |
| SHA3-384 | Sha3384 |
48 bytes |
| SHA3-512 | Sha3512 |
64 bytes |
See SAFE_HASH_CODECS for the constant array.
Legacy algorithms (for compatibility)
| Algorithm | Codec | Digest Size |
|---|---|---|
| SHA1 | Sha1 |
20 bytes |
| SHA2-224 | Sha2224 |
28 bytes |
| SHA2-256 | Sha2256 |
32 bytes |
| SHA2-384 | Sha2384 |
48 bytes |
| SHA2-512 | Sha2512 |
64 bytes |
| SHA2-512/224 | Sha2512224 |
28 bytes |
| SHA2-512/256 | Sha2512256 |
32 bytes |
| Blake2b-224 | Blake2B224 |
28 bytes |
| Blake2s-224 | Blake2S224 |
28 bytes |
| MD5 | Md5 |
16 bytes |
| RIPEMD-128 | Ripemd128 |
16 bytes |
| RIPEMD-160 | Ripemd160 |
20 bytes |
| RIPEMD-256 | Ripemd256 |
32 bytes |
| RIPEMD-320 | Ripemd320 |
40 bytes |
| SHA3-224 | Sha3224 |
28 bytes |
See HASH_CODECS for the constant array of all 23 supported codecs.
Usage
Computing a Hash
use Builder;
use Codec;
// Compute a SHA2-256 hash
let multihash = new_from_bytes
.unwrap
.try_build
.unwrap;
assert_eq!;
assert_eq!; // SHA2-256 outputs 32 bytes
Building from an Existing Digest
If you already have a hash digest, for example from an external hashing library:
use Builder;
use Codec;
let digest = vec!; // pre-computed SHA2-256 digest
let multihash = new
.with_hash
.try_build
.unwrap;
Encoding and Decoding
Multihashes encode as codec || length || hash (varint-prefixed):
use ;
use Codec;
let mh1 = new_from_bytes
.unwrap
.try_build
.unwrap;
// Encode to binary (varint wire format)
let bytes: = mh1.clone.into;
// Decode from binary
let mh2 = try_from.unwrap;
assert_eq!;
Base Encoding
Use try_build_encoded() with a specific base. It gives an EncodedMultihash that supports Display and TryFrom<&str>:
use Builder;
use Codec;
use Base;
let encoded = new_from_bytes
.unwrap
.with_base_encoding
.try_build_encoded
.unwrap;
// Display as a base58-encoded multihash string
let base58_string = encoded.to_string;
println!;
// Parse back from string
use EncodedMultihash;
let decoded: EncodedMultihash = try_from.unwrap;
assert_eq!;
Converting to EncodedMultihash
You can convert a Multihash to an EncodedMultihash with .into(). The default base is Base16Lower. You can also use EncodedMultihash::new() with a base of your choice:
use ;
use Base;
use Codec;
let mh = new_from_bytes
.unwrap
.try_build
.unwrap;
// Uses the preferred encoding for multihash objects: Base16Lower
let encoded_mh1: EncodedMultihash = mh.clone.into;
// Or choose a specific base encoding
let encoded_mh2: EncodedMultihash = new;
Serde Integration
With the serde feature on by default, Multihash implements Serialize and Deserialize. Human-readable formats give the codec name and the hex digest. Binary formats give the varint bytes:
use Builder;
use Codec;
use ;
let doc = DocumentHash ;
// Serialize to JSON (human-readable - codec name + hex digest)
let json = to_string.unwrap;
println!;
// Deserialize from JSON
let deserialized: DocumentHash = from_str.unwrap;
assert_eq!;
Error Handling
All conversion and builder errors return Result with a structured Error enum:
use ;
use Codec;
// Handle unsupported algorithms
match new_from_bytes
// Handle missing hash data
match new.try_build
Type-Safe Newtypes
For more type safety, use the newtype wrappers:
use ;
use Codec;
// Type-safe hash digest
let digest = new;
assert_eq!;
assert_eq!;
// Type-safe algorithm identifier
let algo = new;
assert_eq!;
assert_eq!;
assert_eq!;
Testing
The crate has 110 tests across unit, integration, property-based, security, and doc-test suites:
# Run all tests
# Run specific test suites
# Run benchmarks
Linting and formatting:
CI collects coverage with cargo-llvm-cov and uploads the result to Codecov.
Feature Flags
serde(default). Enables serde serialization and deserialization. When on,MultihashimplementsSerializeandDeserialize. Human-readable formats give the codec name and the hex digest. Binary formats give the varint bytes.
Disabling Default Features
[]
= { = "1.0", = false }
Security
#![deny(unsafe_code)]is set at the crate root.- All errors return
Result. No path panics on invalid input. - All types are
Send + Syncwith no shared mutable state. - Hash computation uses vetted cryptographic libraries from the RustCrypto ecosystem.
impl subtle::ConstantTimeEq for Multihashis available for timing-sensitive comparisons.- The
Varbytesdecode path enforces a decoded-size cap (16 MiB) and buffer-length checks. This mitigates CWE-400 and CWE-125.
See SECURITY.md for the full security policy.
Maintainers
This repo: @dgrantham.
Contribute
Contributions are welcome. Please check out the issues.
Development Guidelines
- Run
cargo fmtbefore you commit. - Run
cargo clippy -- -D warningsto check for issues. - Add tests for new features.
- Update documentation for API changes.
- Run the full test suite:
cargo test --all-features.
License
Apache-2.0 (c) Cryptid Technologies