mithril-dwarf v0.1.0: cycle-optimized verifier + equivalence harness#5
Merged
Conversation
A purpose-built, allocation-free Cardano Mithril certificate verifier
in Rust, sized for zkVM guests (primary target: RISC Zero). Verdicts
are bit-equivalent to upstream `mithril-common`'s
`MithrilCertificateVerifier` at pinned rev
`36fd7f8818f0ff14b10336fa7f855d52698e40a8`, gated by an equivalence
harness in the new `mithril-dwarf-harness/` sub-crate.
## Verifier (`src/`)
- Custom binary wire format with a hand-rolled `FastByteParser`; the
output `CertificateZeroCopy<'a>` borrows every field from the source
buffer (VK arrays, signature bytes, Merkle leaves, index lists).
- Tiered cheapest-first verification in
`verify_standard_certificate`:
- Phase 1: basic comparisons (self-chain, epoch parity, epoch
chaining, previous-hash link).
- Phase 2: SHA-256 over canonical bytes; cert-hash preimage and
signed-message check share a single `pm_digest` / `pp_digest`.
- Phase 3: AVK and protocol-parameters chaining (same-epoch direct
compare; cross-epoch hex compare).
- Phase 4: aggregate BLS via `blst`, Merkle batch proof via Blake2b,
lottery via Taylor-series `ln(1 - φ_f)` over rational arithmetic
(`crypto-ratio`).
- 4-byte `Copy` `VerifyError` enum; failure paths allocate nothing.
- Streaming SHA-256 sink (`HashSink` trait + `Sha256Sink`,
`JsonHexWriter`); no `String` materialised on the hot path.
- Hot-path hoists in `preliminary_verify`: per-cert `c = ln(1 - φ_f)`
computed once, per-signer `x = -w*c` hoisted out of the index loop,
Blake2b `"map" || msgp` prefix pre-absorbed and cloned per index,
uniqueness via a `(m+1)`-bit u32 bitset.
- `#[inline(always)]` on `aggregate_signatures_and_keys` to keep the
fused scalar-gen and pk/sig parsing loops below LLVM's cost
threshold; `__udivdi3` avoided via a u64/u32 split in
`write_u64_dec`.
## Equivalence harness (`mithril-dwarf-harness/`)
A separate sub-crate that runs every upstream Mithril check and the
matching dwarf check on every certificate in a multi-network corpus,
bitwise-compares the canonical byte streams per check, and
bitwise-compares the top-level verdicts. Hard failure on:
- false positive (dwarf accepts what upstream rejects),
- soundness regression (dwarf rejects what upstream accepts),
- structurally insufficient mutation (both impls accept).
A ~25-axis mutation suite covers hashes, AVK/signature envelopes,
epochs, protocol parameters, signer stake, `NextAvk` /
`NextProtocolParameters` JSON, BLS-algebraic mutations, and
length-axis perturbations. A separate byte-fuzz test models the
in-guest threat shape: raw wire bytes flipped, dwarf is the only
defence. A cross-impl chain test walks the full corpus chain
(genesis-terminated) and asserts verdict equivalence with a
middle-link tamper to exercise mid-iteration orchestrator paths.
## Intentional divergences
Five places where dwarf's observable behaviour intentionally differs
from upstream are documented and pin-tested in
`tests/intentional_divergences.rs`:
1. BLS identity-point rejection layer (parse-time vs verify-time).
2. ed25519 non-strict `verify` vs upstream's `verify_strict`.
3. `verify_epoch_chaining` direction asymmetry.
4. Check ordering inside `verify_standard_certificate`.
5. `usize` width on the BLS aggregation index on RISC0.
A corpus-wide gate (`divergence_registry_verdict_equivalence_holds_on_corpus`)
asserts these don't change top-level verdicts on real certs.
## Drift CI
`.github/workflows/upstream-drift-check.yml` rebuilds the harness
weekly against `Sbcdn/mithril.git#main` instead of the pinned rev;
any behaviour or type-signature divergence fails the job. A local
helper at `scripts/check-upstream-drift.sh` runs the same check with
automatic restore.
## Test corpus
`mithril-dwarf-harness/tests/test_data/certificates/` carries a
diverse mainnet + preprod corpus covering all five
`SignedEntityType` variants; `fetch_diverse_corpus.sh` is the
reproducible fetcher. `corpus_diversity_report` hard-asserts variant
and network floors so a silent corpus shrink fails the gate.
## Benches
`benches/` carries iai-callgrind benchmarks for per-check cycle cost
and side-by-side comparison against the upstream reference path.
## Status
Pre-1.0 (`v0.1.0`).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Initial public release of
mithril-dwarf, a cycle-optimized, allocation-free Mithril certificate verifier sized for zkVM guests (primary target: RISC Zero). Verdicts are bit-equivalent to upstreammithril-common'sMithrilCertificateVerifierat pinned rev36fd7f8818f0ff14b10336fa7f855d52698e40a8and gated by an equivalence harness.src/(zero-allocation hot path, BLS viablst, Merkle via Blake2b, lottery via Taylor series over rational arithmetic).mithril-dwarf-harness/) carrying 12 equivalence tests + 6 intentional-divergence pin tests.SignedEntityTypevariants.See the commit message for the full per-area breakdown.
Test plan
cargo test -p mithril-dwarf --release— 8/8 unit testscargo test -p mithril-dwarf-harness --test equivalence --release— 12/12 testscargo test -p mithril-dwarf-harness --test intentional_divergences --release— 6/6 testscargo build --release --all-features— clean