Passphrase-based peer rendezvous for iroh-gossip swarms over the public Mainline DHT. Two nodes that share a passphrase + application salt find each other and join the same gossip topic — no bootstrap server, no prior knowledge of peer addresses. The algorithm is a clock-free variant of HyParView-style partition healing on BEP 44 mutable items, with K-sharded slots, logical aging with random-tie eviction, vouching of up to V neighbors at age 1, and a two-layer AEAD record envelope. Full spec in PROTOCOL.md. Ships with: * 119 tests (unit / property / integration / doctest) all green * 100% mutation-testing catch rate (cargo-mutants) * cargo-fuzz harnesses for the parse surface * Kani proofs of no-UB / no-panic on crypto::epoch_of and wire::decode_entries across their full symbolic input spaces * Stateright distributed-system model: safety invariants S1 + S2 proved exhaustively for N ≤ 6, K ≤ 3; liveness witness under weak fairness * Miri green on the synchronous modules * cargo-deny + cargo-audit clean * criterion benches * Full-matrix CI (Linux + macOS + Windows × stable + MSRV 1.93.0) * Dedicated nightly lane for Miri / mutation / fuzz / Kani / Stateright Pinned iroh 0.98.x. License MIT. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3.9 KiB
3.9 KiB
Changelog
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
0.1.0 — 2026-04-22
First public release. Passphrase-based peer rendezvous for iroh-gossip swarms over the public Mainline DHT, keyed from a shared passphrase + an application salt — no central bootstrap server and no prior knowledge of peer addresses required.
Algorithm
- K-sharded BEP 44 mutable-item slots (default
K = 3), each with its own HKDF-derived Ed25519 signing keypair and per-slot AEAD wrapper key. - Logical aging with random-tie eviction; vouching of up to
Vneighbors at age 1; two-layer ChaCha20-Poly1305 AEAD envelope over fixed-width entries. - Seq-ratcheted per-epoch wrapper keys; one-shot body key per record.
- Clock-free: no dependence on wall-time across nodes.
- Full specification lives at
PROTOCOL.md.
Public API
Rendezvous::join(passphrase, app_salt)— one-call entry point.Rendezvous::builder()— fullBuilderfor endpoint/secret_key/ parameter overrides.Rendezvous::{sender, subscribe, state, endpoint, node_id, topic_id, broadcast, shutdown}— handle surface.iroh_gossiptypes re-exported where useful; otherwise thin wrappers.
Feature flags
sim— discrete-event simulator + test-support exports.kani— Kani proof harnesses (off by default).miri-compat— skip Miri-incompatible tests.mainline-live— integration tests against the real public Mainline DHT.test-support—Builder::dht_backendfor injecting customDhtSlots.
Correctness evidence shipping with the crate
- 119 tests across unit, property, integration, and doctest layers; all green.
- Property tests (
proptest) on wire format roundtrip, merge invariants (|R'| ≤ B, age bound, self at age 0), crypto roundtrip across epoch boundaries. - Integration tests over real iroh endpoints with an injected in-memory DHT: two-node bootstrap, multiple-subscriber fan-out, drop cancels background tasks.
- Mutation testing (
cargo-mutants) — 100% catch rate on testable mutations (119 caught, 27 unviable, 0 missed). See.cargo/mutants.tomlfor the exclusions and their rationale. - Fuzz harnesses (
cargo-fuzz) fordecode_entries. - Bounded model checking (Kani) of undefined-behavior / panic
absence on
crypto::epoch_of(fulli64×u64 ≥ 1space) andwire::decode_entries(arbitrary byte input). Structural invariants are covered by the stronger proptest + Stateright combo. - Distributed-system model checking (Stateright): safety invariants
S1 (record size ≤ B) and S2 (age < A_max) proved exhaustively for
N ≤ 6, K ≤ 3; liveness witnesses under weak fairness; randomized
large-N exploration available via
just model-random. - Miri — UB-free on the synchronous modules (
keys,wire,crypto,merge). - Simulator baseline (
examples/simulator.rs) — cold-start (8 nodes) and symmetric partition (5/5) scenarios both heal in 1 round at 100%. Asymmetric 1:100 with defaultK = 3is a documented limitation inPROTOCOL.md §8.
Supply chain
- MIT-licensed; MSRV 1.93.0; all crypto dependencies from the audited RustCrypto stack.
cargo-deny+cargo-auditgreen on every push (transitiveunmaintainedadvisory frompasteviairoh → portmapper → netwatchdocumented indeny.toml).[package.metadata.docs.rs]configured for all-feature docs builds.