Skip to content

mithril-dwarf v0.1.0: cycle-optimized verifier + equivalence harness#5

Merged
Sbcdn merged 1 commit into
mainfrom
release/v0.1.0
Jun 1, 2026
Merged

mithril-dwarf v0.1.0: cycle-optimized verifier + equivalence harness#5
Sbcdn merged 1 commit into
mainfrom
release/v0.1.0

Conversation

@Sbcdn

@Sbcdn Sbcdn commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

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 upstream mithril-common's MithrilCertificateVerifier at pinned rev 36fd7f8818f0ff14b10336fa7f855d52698e40a8 and gated by an equivalence harness.

  • New verifier in src/ (zero-allocation hot path, BLS via blst, Merkle via Blake2b, lottery via Taylor series over rational arithmetic).
  • New equivalence harness sub-crate (mithril-dwarf-harness/) carrying 12 equivalence tests + 6 intentional-divergence pin tests.
  • Intentional-divergence registry documenting five places dwarf's observable behaviour intentionally differs from upstream, each verdict-equivalent and pin-tested.
  • Upstream drift CI workflow rebuilding the harness weekly against upstream main.
  • Multi-network test corpus (109 entries, mainnet + preprod) covering all five SignedEntityType variants.
  • Custom zero-copy wire format; host-side converter for chain ingestion.

See the commit message for the full per-area breakdown.

Test plan

  • cargo test -p mithril-dwarf --release — 8/8 unit tests
  • cargo test -p mithril-dwarf-harness --test equivalence --release — 12/12 tests
  • cargo test -p mithril-dwarf-harness --test intentional_divergences --release — 6/6 tests
  • cargo build --release --all-features — clean
  • Manual review of comment + doc style (public-readiness pass)
  • Optional: oaks_cert cycle bench delta vs prior baseline

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`).
@Sbcdn Sbcdn force-pushed the release/v0.1.0 branch from 6984585 to 93cd9c0 Compare June 1, 2026 21:29
@Sbcdn Sbcdn merged commit 566469b into main Jun 1, 2026
1 check failed
@Sbcdn Sbcdn deleted the release/v0.1.0 branch June 2, 2026 08:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant