- internal/chain: end-to-end chain verification. Walks head → genesis,
verifies every cert (Ed25519 or STM as appropriate), and checks
continuity at every boundary:
epoch: same or +1 from previous
hash: current.previous_hash == previous.hash
AVK: same epoch → equal aggregate_verification_key
new epoch → matches previous.protocol_message.next_aggregate_verification_key
- cmd: 'verify chain' subcommand + 'verify manifest <dir>' for SHA-checking
downloaded immutable files
- internal/manifest: per-file SHA-256 verification against the digests.json
shipped in the snapshot's digests archive
- MCP: 8th tool 'mithril_verify_chain' for agent-driven full-chain verify
- README: complete rewrite — status table, architecture, gotchas, MCP
tool surface, exit code contract, build instructions
- LICENSE: Apache-2.0 (matches upstream Mithril)
Verified end to end against live networks:
preprod chain 90 certs (89 STM + 1 genesis) 1124 wins ✓
mainnet chain 89 certs (88 STM + 1 genesis) 210921 wins ✓
That's the wrap. Pure-Go consensus-correct Mithril client, single 10 MB
static binary, MCP-native, no CGo, no upstream Rust runtime.
|
||
|---|---|---|
| cmd/mithril-go | ||
| internal | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| LICENSE | ||
| README.md | ||
| STM-SPRINT.md | ||
mithril-go
Pure-Go client for the Cardano Mithril protocol.
Mithril is Cardano's stake-based certified-snapshot system — it lets a new node bootstrap the chain from a cryptographically-verified snapshot instead of replaying every block from genesis.
The official mithril-client
is Rust. mithril-go is a pure-Go reimplementation that produces a single
static binary with no CGo, no upstream Rust runtime, and an MCP-native
tool surface for AI agents — useful for:
- Embedding Mithril bootstrap into Go-based Cardano tooling (alongside
gouroboros,dingo, etc.) - Constrained ARM/embedded targets where shipping the Rust binary + its deps is overkill
- Operators who prefer a single
go install-able helper - AI agents (Claude Code, Cursor, Zed, ...) that want to verify Mithril certs as a callable tool
Status
Working consensus-correct verification against live mainnet and preprod.
| Capability | Status |
|---|---|
| Aggregator REST client | ✅ list, show, cert, walk-chain |
| Resumable HTTP download (SHA hook + progress) | ✅ |
| Streamed zstd+tar extract (tar-slip defended) | ✅ |
| Genesis Ed25519 verification | ✅ live mainnet + preprod |
| STM BLS12-381 aggregate verification | ✅ live mainnet + preprod |
| Lottery-win threshold (Taylor series, big.Rat) | ✅ |
| Merkle batch-proof verification (Blake2b-256) | ✅ |
| AVK chaining + epoch + hash continuity | ✅ |
| Full chain verification (genesis → head) | ✅ live mainnet + preprod |
| Per-immutable SHA manifest verification | ✅ |
| MCP stdio server (8 tools) | ✅ |
| Full immutables-download loop (8000+ files) | ⏳ |
Quick start
go build ./cmd/mithril-go # produces a 9.5 MB single static binary
mithril-go info -network mainnet
mithril-go list -network mainnet
mithril-go show -network mainnet latest
mithril-go cert -network mainnet head
mithril-go cert -network mainnet -chain head # walk to genesis
mithril-go download -network preprod -out ./snap latest
mithril-go verify -network preprod manifest ./snap # SHA-check downloaded files
mithril-go verify -network mainnet genesis # Ed25519
mithril-go verify -network mainnet head # STM BLS aggregate
mithril-go verify -network mainnet chain # full walk + every cert
Every query command supports -json for structured output.
Architecture
cmd/mithril-go/
main.go CLI entrypoint, subcommand dispatch
mcp.go MCP tool registration
json.go Structured-output helpers
internal/
aggregator/ REST client (list, get, cert, walk-chain)
artifact/ Resumable HTTP download + streamed zstd-tar extract
chain/ End-to-end chain verify (genesis → head, AVK chaining)
manifest/ Per-immutable SHA-256 verification against digests.json
mcp/ Minimal JSON-RPC 2.0 stdio MCP server (no deps)
networks/ Per-network aggregator URLs + genesis verify keys
stm/ STM BLS12-381 verification: types, BLS, aggregation,
lottery, Merkle, top-level Verify
verify/ Genesis Ed25519 verification
What was non-obvious (so future-you doesn't have to dig)
Three things in the upstream Rust that aren't documented anywhere prominent:
- DST is empty. Mithril's BLS hash-to-G1 uses an empty domain
separation tag, not the IETF standard
BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_. The Rust callsblst.verify(sig, msg, &[], &[], pk, ...)— the&[]is the empty DST. - The signed message is
signed_message_bytes || mt_root_bytes, notsigned_messagealone. The Merkle commitment root is appended before BLS verify. - Aggregation is MuSig-style scalar-weighted, not plain.
t_i = Blake2b-128(Blake2b-128(σ_0‖…‖σ_{n-1}) ‖ be_u64(i)), thenaggr_sig = Σ t_i·sig_iandaggr_vk = Σ t_i·vk_i. Plain summation does not interop with blst.
Plus the protocol_message hash is SHA-256 over key-then-value, with
keys ordered by Rust enum declaration order, not alphabetical.
Machine / LLM usage
Every query command accepts -json:
mithril-go verify -network mainnet -json chain | jq '.steps[] | select(.kind=="genesis")'
Stable exit codes:
| Code | Meaning |
|---|---|
| 0 | success |
| 1 | generic error |
| 2 | usage error |
| 3 | network / aggregator error |
| 4 | integrity failure (SHA, tar-slip, truncated archive) |
| 5 | signature verification failure (genesis or STM) |
| 130 | canceled (SIGINT) |
These are the contract — existing codes won't renumber.
MCP server
mithril-go mcp brings up a Model Context Protocol stdio server.
Compatible with any MCP client (Claude Code, Cursor, Zed, custom agents).
Tools exposed:
| Tool | Purpose |
|---|---|
mithril_info |
Network + aggregator + genesis verify key |
mithril_list_snapshots |
Newest-first list of cardano-database snapshots |
mithril_show_snapshot |
Detail for a snapshot (or latest) |
mithril_get_certificate |
Cert by hash (or head) |
mithril_walk_cert_chain |
Walk previous_hash from head to genesis |
mithril_verify_certificate |
Ed25519 OR STM BLS verify, dispatched by cert kind |
mithril_verify_chain |
Full chain verify with per-step report |
mithril_verify_genesis |
Walk to genesis + Ed25519 verify (legacy single-purpose tool) |
Example agent flow:
agent: tools/call mithril_verify_chain {network: mainnet}
→ {verified: true, length: 89, genesis_hash: "...", steps: [...]}
Dependencies
github.com/consensys/gnark-crypto— pure Go BLS12-381 (audited)golang.org/x/crypto/blake2b— stdlib-adjacent Blake2bgithub.com/klauspost/compress/zstd— pure Go zstd
No CGo. No blst. go build ./cmd/mithril-go produces a single static
binary. Cross-compile with GOOS=linux GOARCH=arm64 go build.
Building
go build -o mithril-go ./cmd/mithril-go
go test ./...
go test -tags live ./... # hits live preprod aggregator
Verified against live networks (latest run)
mainnet chain 89 STM + 1 genesis ✓
mainnet head 59 signers, 1972 wins ✓
mainnet genesis Ed25519 ✓
preprod chain 89 STM + 1 genesis ✓
preprod head 2 signers, 11 wins ✓
preprod genesis Ed25519 ✓
License
Apache-2.0. See LICENSE. Matches the upstream Mithril project.