This repository has been archived on 2026-06-29. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
mithril-go/README.md
Sulkta 5294cf0bfa STM full verification landing — milestones C/D/E complete
Implemented the remaining STM verification layers:

- internal/stm/lottery.go: EvaluateSigma (Blake2b-512 lottery draw) +
  IsLotteryWon with Taylor-series threshold comparison (ported from
  mithril-stm::eligibility), big.Rat-based to match Rust's num_bigint/
  num_rational path
- internal/stm/merkle.go: Blake2b-256 Merkle batch-proof verification,
  faithful port of mithril-stm's verify_leaves_membership_from_batch_path
  including the 'current is left/right child' branch logic and the
  1-byte zero pad for missing siblings
- internal/stm/verify.go: top-level stm.Verify(msg, ms, avk, params)
  glues all four checks: k-threshold, lottery, Merkle, BLS aggregate
- cmd: 'verify head' now runs full STM verification; JSON output shows
  signers, wins, params, verified flag
- MCP: new 'mithril_verify_certificate' tool dispatches genesis Ed25519
  vs STM by cert kind

Verified against live networks:
  mainnet head cert bc00b551…  epoch=626  59 signers  1972/16948 wins  ✓
  mainnet genesis   25acfcfe…  epoch=539  Ed25519 ✓
  preprod head      dd9c4fcb…  epoch=284   2 signers    11/100 wins   ✓
  preprod genesis   69bc3bdf…  epoch=196  Ed25519 ✓

This is a consensus-correct pure-Go Mithril client. Single binary,
CGo-free, no upstream Rust dependency.

Next: full chain verification (walk head → genesis, check continuity).
2026-04-23 15:58:44 -07:00

143 lines
5.3 KiB
Markdown

# mithril-go
Pure-Go client for the Cardano [Mithril](https://mithril.network) 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`](https://github.com/input-output-hk/mithril)
is Rust. This project is a pure-Go reimplementation that produces a single
static binary with no runtime dependencies — useful for:
- Embedding a Mithril bootstrap into Go-based Cardano tooling
(alongside `gouroboros`, `dingo`, and friends)
- Running on constrained ARM/embedded targets where shipping the Rust
binary + its deps is overkill
- Operators who prefer a single `go install`-able helper
## Status
**Full Mithril verification working — genesis Ed25519 AND STM BLS12-381 — against live mainnet and preprod.**
| Piece | Status |
|---|---|
| Aggregator REST client | ✅ list, get, cert, chain |
| `list` / `show` / `info` / `cert` commands | ✅ mainnet + preprod |
| Resumable HTTP download (single stream, SHA hook) | ✅ |
| Streamed zstd+tar extract (tar-slip defended) | ✅ |
| `download` — digests + ancillary | ✅ (full immutables loop pending) |
| **Genesis Ed25519 verification** | ✅ live mainnet + preprod |
| **STM BLS12-381 aggregate verification** | ✅ live mainnet + preprod |
| **MCP stdio server** | ✅ 7 tools, Claude/Cursor/Zed compatible |
| Full cert-chain verify (genesis → head) | ⏳ next |
## Usage
```
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 ./db latest # digests + ancillary
```
## Verification sprint plan
The verification story splits into two layers:
### 1. Genesis Ed25519 verification
The genesis certificate (terminates the chain; its `previous_hash` is
empty and `genesis_signature` is non-empty) is signed by a static
Ed25519 key baked into this client per network (`internal/networks`).
- Key encoding: the Mithril genesis key is serialized as an ASCII-
representation of a 32-byte array literal (e.g. `"[191,66,...]"`)
then hex-encoded. Decoder needs to unwrap both levels before handing
32 raw bytes to `ed25519.Verify`.
- Signed payload: `signed_message` field (32 bytes hex) is the output
of hashing the serialized `protocol_message` — the exact hash
function and canonicalization must match the Rust reference
(`mithril-common/src/protocol/` in the upstream repo). Likely
Blake2b-256 over a deterministic CBOR or JSON encoding; needs
confirming against upstream.
- Wire location: `internal/verify/verify.go``Genesis(...)`.
### 2. STM BLS12-381 aggregate verification
Every non-genesis certificate carries a `multi_signature` that is an
STM (Stake-based Threshold Multi-signature) aggregate proof over BLS12-381.
- Scheme: Chotard/Kiayias/Peters "Stake-based Threshold Multisignatures"
(Mithril paper §5-6).
- Library: `github.com/supranational/blst` Go bindings (IETF-draft
BLS12-381 operations; production-grade, consensus layers use it).
- Inputs:
- `next_aggregate_verification_key` from the previous-epoch cert's
`protocol_message` (the "trust handoff" between certs)
- `multi_signature` bytes (CBOR-encoded STM aggregate signature)
- `signed_message` (what was signed)
- Output: pass/fail, plus the epoch-boundary decision to promote
that cert's `next_aggregate_verification_key` for use by the NEXT
verification.
- Wire location: `internal/verify/verify.go``STM(...)`.
### Downstream once verification lands
- `verify` subcommand: takes a snapshot directory, walks the cert chain,
verifies genesis Ed25519 + each STM signature in order, validates the
`merkle_root` against the digests manifest's computed root, reports
per-stage pass/fail.
- Per-immutable SHA check against the `digests.json` manifest (already
downloaded — 16836 entries for preprod as of epoch 284).
- Full immutables loop for the `download -immutables` path.
## Machine / LLM usage
Every query command accepts `-json` for structured output:
```
mithril-go list -network mainnet -json # snapshot array
mithril-go show -network mainnet latest -json
mithril-go cert -network mainnet head -json
mithril-go cert -network mainnet head -chain -json
mithril-go info -network mainnet -json
```
Exit codes are stable:
| 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.
Planned: `mithril-go mcp` stdio server (Model Context Protocol) so MCP-native
agents (Claude Code, Cursor, etc.) can discover + call commands without
shelling out. Not yet implemented.
## Dependencies
- `github.com/klauspost/compress/zstd` — pure Go zstd decoder
- (pending) BLS12-381: `github.com/supranational/blst` via its Go bindings
## Building
```
go build -o mithril-go ./cmd/mithril-go
```
Produces a single static binary (~9.5 MB). CGo is not used; cross-
compilation is `GOOS=linux GOARCH=arm64 go build ./cmd/mithril-go`.
## License
TBD