Security maturity
What has actually been tested, per component, and by what. Generated from the tree rather than maintained by hand: a deleted fuzz target removes its tick here on the next CI run, which is the failure mode a hand-written table has no way to catch.
"The parser is audited" and "the protocol is audited" are very different claims. This page exists so a reader can tell which one they are being offered.
| component | fuzzed | property-tested | independently reviewed | hardware | what an attacker controls |
|---|---|---|---|---|---|
| envelope parser | ✅ armor_and_framing, envelope_decode, node_on_rx |
⬜ | ⬜ | ⬜ | every byte of every frame, from anyone in range, before any check has run |
| armor + KISS framing | ✅ armor_and_framing |
⬜ | ⬜ | ✅ rows 4, 5b | text and serial input, including whatever a user pastes |
| link fragmentation | ✅ linkfrag_reassembly |
⬜ | ⬜ | ⬜ | attacker-chosen set ids, indices and counts, and it allocates to reassemble |
| fountain reassembly | ✅ fragment_reassembly |
⬜ | ⬜ | ⬜ | a stream of chunks whose count and index come straight off the wire |
| node ingest / forwarding | ✅ fragment_reassembly, node_on_rx |
⬜ | ⬜ | ✅ rows 1, 2, 3, 4, 5 | whole envelopes plus the store and interest tables they grow |
| radio codecs | ✅ radio_codecs |
⬜ | ⬜ | ✅ rows 2, 3, 5, 5b | demodulated symbols, which are noise-shaped input by definition |
| seal / open | ✅ seal_open |
⬜ | ⬜ | ⬜ | ciphertext the attacker chose, against a key they did not |
| topic key schedule | ✅ seal_open |
⬜ | ⬜ | ⬜ | group roster and rekey material from anyone already in the group |
| double ratchet | ⬜ | ✅ properties, unauthenticated_input |
⬜ | ⬜ | headers and ciphertext on an established session |
| mix / batching | ⬜ | ✅ properties |
⬜ | ⬜ | timing and volume, which is the whole of what it defends |
| store + eviction | ⬜ | ✅ properties |
⬜ | ⬜ | what to keep under pressure, which is what an attacker attacks by filling it |
| hub / interface table | ⬜ | ✅ properties |
⬜ | ⬜ | concurrent traffic across links, where the failure is a deadlock not a panic |
How to read a ⬜
It means not done, not not needed. Some are deliberate — the mix's defence is statistical, so a fuzzer that cannot crash it proves little — but none of them are covered by something else on this page. Where a gap matters, it is a roadmap row, not a footnote here.
The column that cannot be generated
Independently reviewed is ⬜ for every component, and that is the most important cell in the table. Nobody outside this repository has audited any of it. Every fault listed in the git history was found by the same people who wrote the thing — fuzzing, property tests, and a simulator — which is a real method with a known blind spot: it finds what its authors thought to look for.
A name appears in that column when a person or firm has looked, not when one has been told about it.
What this is counted from
- 7 fuzz targets under
fuzz/fuzz_targets/, each declaring its coverage in a//! fuzz-covers:line. A target naming a component that does not exist fails this script rather than quietly reading as not fuzzed. - Property tests are
mod properties/mod unauthenticated_inputin the component's own source file — 4 components have one. These were written for #278, and the ratchet's and the mix's each turned up a live fault on the way in. - Hardware is the manual verification checklist, 22 rows, worked through with real radios and real devices. CI has none of either.
Every component has at least one form of coverage
That is a floor, not a finish. The two columns it is built from find different things — a fuzzer finds what crashes, a property test finds what is quietly wrong — and several components have only one of the two. The empty column is still the whole of the right-hand side of this table.