hardening: ed25519 verify_strict + mithril-client re-exports#7
Merged
Conversation
Genesis-cert ed25519 path now uses verify_strict, matching upstream ProtocolGenesisVerificationKey::verify. Adds small-order checks on R / A and uses the un-cofactored equation. Measured cost +73,927 host cycles per chain (iai-callgrind, benches/ed25519_strict.rs), one call per chain. Regression pin in src/certificate_verification/mod.rs exercises identity-VK rejection so any revert to non-strict fails fast. Divergence #2 closed and removed from the registry. Stale "non-strict ed25519" commentary trimmed from harness types, report, checks_genesis, and mutation modules. README divergence count updated 5 -> 4. lib.rs re-exports two mithril-client types required by the new ClientBuilder::new(AggregatorDiscoveryType::Url(...)) .set_genesis_verification_key(GenesisVerificationKey::JsonHex(...)) constructor pattern in mithril 2617.0. Lets downstream host consumers avoid taking mithril-client as a direct dep. Harness: equivalence 12/12, divergence pins 6/6.
Replaces the host-side estimate with the actual zkVM number from oaks_cert (--features guest-bench): +49,800 cycles per chain.
Sbcdn
added a commit
that referenced
this pull request
Jun 24, 2026
The per-cert c = ln(1-phi_f) used crypto-ratio from_float, which rounds to a fixed 2^-52 grid; upstream Mithril rationalises the same f64 exactly (num_rational::Ratio::from_float). Switch to from_float_exact (crypto-ratio 0.2.2) so dwarf's c, and thus x = -w*c, is bit-identical to upstream. This resolves intentional divergence #7: the ~2^-52 winning-ev sliver is gone (dwarf_matches_upstream_random reports 0 mismatches). Cycle-neutral on mainnet (-2014 cycles/cert, padded cycles and segments unchanged). The exact c carries a slightly wider denominator, so an ev placed at the exact decision boundary overruns the U2048 wide-fallback cap sooner: a sound abort (never a false accept) and production-unreachable (random ev resolves with zero cache panics). The boundary-sweep probe now counts cap hits as exercising the overflow regime; the soundness assertion unsafe_disagree == 0 is unchanged. Add preview_live_equivalence: a live-data gate asserting dwarf is bit-equivalent to upstream on the corpus real preview certs, including the cert that previously overflowed the U512 series.
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
Two small, independent hardening changes against
main:Genesis ed25519 path now uses
verify_strict. Matches upstreamProtocolGenesisVerificationKey::verifyexactly. Adds the small-order checks onR/Aand the un-cofactored verification equation. Closes the only meaningful flavour of the unjournaled-genesis-VK substitution discussed in the recent security review (low-order public-key shortcut). The broader input-binding obligation remains a consumer-side check onchain_output.genesis_hash, which is information-equivalent to pinning the VK directly.Re-export
AggregatorDiscoveryTypeandGenesisVerificationKeyfrommithril-client. The newClientBuilder::new(...).set_genesis_verification_key(...)constructor pattern in Mithril 2617.0 requires both argument types. Downstream host consumers can now reach them throughmithril-dwarfwithout takingmithril-clienton as a direct dep (which would force a version-pin coordination problem with the transitivemithril@7e787deef).Cycle cost
Measured in
oaks_certwith--features guest-bench: +49,800 RISC0 cycles per chain, genesis-only path (one call per chain). Against the per-cert standard verification cost this is well under 0.02% of a one-cert chain proof. Host-side instruction counts frombenches/ed25519_strict.rs(iai-callgrind) corroborate the ratio.Divergence registry
Divergence #2 (Ed25519 non-strict) closed and removed from
tests/intentional_divergences.rs. Audit-trail entry kept in the closed-divergences block of the module header. README divergence count updated 5 → 4. Stale "non-strict ed25519" commentary trimmed frommithril-dwarf-harness/src/{checks_genesis,mutation,report,types}.rs.Regression detector
New unit pin
ed25519_rejects_small_order_public_keyinsrc/certificate_verification/mod.rsexercises identity-VK rejection through the production entrypoint. Any future revert to non-strictvk.verifyfails this test immediately.Test plan
cargo test -p mithril-dwarf --release --lib(incl. new small-order pin)cargo test -p mithril-dwarf-harness --test equivalence --release— 12/12 passcargo test -p mithril-dwarf-harness --test intentional_divergences --release— 6/6 pass (one less than before, readme and test fixes #2 removed)cargo build --release --features host— re-exports compile cleanlycargo bench --bench ed25519_strict— iai-callgrind delta documentedoaks_cert— +49,800 cycles confirmedFiles
src/certificate_verification/mod.rs—verify→verify_strictat the genesis call site; new small-order pin test.src/lib.rs— two additive re-exports under the existing#[cfg(feature = "host")]block.benches/ed25519_strict.rs(new) — host-side iai-callgrind comparison of the two verify paths; kept as cycle-delta evidence and regression detector for future dalek bumps.Cargo.toml— register the new bench target.mithril-dwarf-harness/tests/intentional_divergences.rs— drop divergence readme and test fixes #2 entry; keep audit-trail note.mithril-dwarf-harness/src/{checks_genesis,mutation,report,types}.rs— trim stale non-strict commentary.README.md— divergence count + example list updated.