Lesson 11
Who Sees What
A threat model is a list of actors you are defending against, what powers they have, and what each defense actually buys you. FIPS calls out four such actor classes in its intro spec. Every layer of the protocol exists to answer one of them.
The four adversary classes
Transport observer
Passive capture on the underlying medium: tcpdump on WiFi, a tap on Ethernet, a radio receiver. Reads bytes, times them, counts them.
Active attacker
Same vantage as the observer, plus can inject, modify, drop, or replay transport packets at will.
Other FIPS node
A real peer in the mesh. It decrypts the link frames it is party to, forwards sessions, and might be run by someone curious or hostile.
Disruptive node
An FIPS node trying to break routing: forged TreeAnnounces, poisoned bloom filters, Sybil clusters, eclipse attempts.
Which defense answers which adversary
Each layer in the stack is pointed at a specific class of attacker. That is why FIPS has two separate encryption contexts rather than one:
- FMP Noise IK handles the two transport-level adversaries. Every byte that leaves the NIC is encrypted under a per-link session, with AEAD integrity and replay protection. A tcpdump yields ciphertext.
- FSP Noise XK handles the transit router. The mesh can forward a packet through an arbitrary number of untrusted hops and still keep the payload and the source npub out of their reach. Each hop decrypts FMP, forwards, re-encrypts FMP to the next hop, and never touches the FSP AEAD.
- Signed announces and discretionary peering handle disruptive nodes. TreeAnnounce messages carry a Schnorr signature over the ancestry chain, so a liar cannot forge a better tree position. Handshake rate limits throttle Sybil creation. You control who becomes a direct peer.
The visibility matrix
Pick an adversary. The control below shows which protocol artifacts they can actually observe, which are opaque to them, and what keeps the opaque ones opaque.
A mesh node that forwards your FSP session but is not its endpoint. Sees routing envelope only.
| Artifact | Visibility |
|---|---|
Packet timing and sizes Wire-level volume and inter-arrival gaps. | visible |
Transport endpoints Underlying WiFi BSSID, IP:port pair, Bluetooth MAC, serial tty. | metadata |
FMP payload (routing gossip, session datagrams) TreeAnnounce, BloomGossip, LookupRequest, MMP reports, forwarded SessionDatagrams. | visible |
node_addr of the endpoints The 128-bit SHA-256 of the public key carried in the session routing envelope. | visible |
npub of the endpoints The bech32 Nostr public key; the application-layer identity. | opaque |
FSP payload (application data) The encapsulated IPv6 packet, stream chunk, or control message. | opaque |
What stops them
- FSP session AEAD hides the payload even as each hop decrypts and re-encrypts FMP.
- The routing envelope carries node_addr only; a transit router cannot derive npub from it.
- Multi-path candidate selection spreads sessions across peers, limiting any one router's view.
Two rows are worth sitting with. The transit router row has
node_addr marked visible but
npub marked opaque. That is the whole point of hashing the key into
a separate routing address: you can forward traffic without learning which Nostr identities are
on either end. Someone who already knows a candidate npub can of course test whether it matches
a given node_addr, but the router itself cannot enumerate identities from routed traffic.
The destination row looks scary (npub, payload, timing all visible) but that is the working definition of an endpoint. The defense is social, not cryptographic: if you do not want someone to know you are talking to them, do not open a session to them. FSP's job is only to make sure no one else can read that session.
What FIPS does not claim
The intro spec is explicit about two non-goals, and it is worth being equally explicit here:
- No anonymity. Direct peers learn each other's npub through the FMP Noise IK handshake. There is no mixing layer, no cover traffic, no tunnel rotation. Tor and I2P solve a different problem.
- No traffic analysis resistance. A global observer with vantage points on multiple transports can correlate flow timing and size patterns across the mesh to infer who is talking to whom. FIPS does not pad, mix, or batch to defeat this. Confidentiality is protected; the fact that a conversation is happening is not.
Those limits are load-bearing. They are why FIPS can run on low-power devices with lossy radio links, which a mix network generally cannot. A future anonymizing overlay could sit on top of FIPS the same way Tor sits on top of TCP, but it is not in scope for the base protocol.
Eclipse resistance in practice
Eclipse is the subtle one. An attacker who controls every direct peer of a target controls what the target knows. The mesh-layer crypto cannot save you here: all the forged TreeAnnounces are signed by the attacker's own valid identities. The only real defense is topological.
Curated deployments should peer across different operators and different transport types: one peer over the apartment WiFi, one over a friend's UDP overlay, one over LoRa. An attacker has to compromise operators and transports at once. Automatic peer discovery weakens this, which is why the spec notes that open deployments lean on handshake rate limits rather than strong Sybil guarantees.
Lesson quiz
1. Which layer defends against a passive observer on the underlying WiFi or Ethernet?
2. A transit router forwards an FSP session between two other nodes. What can it read?
3. Why does the routing envelope carry node_addr instead of npub?
4. Which of these is NOT a claim FIPS makes?
5. In an open network with automatic peer discovery, what primarily resists Sybil attacks?
6. Why is topological diversity the main defense against eclipse attacks?