Overview
NTL nodes make routing decisions from learned state. That state is derived from traffic, and traffic comes from strangers. This makes the routing model an attack surface that request-response protocols do not have: an attacker who cannot read your data may still be able to teach your node to send it somewhere useful to them. This document states what NTL defends against at this version, how, and — in §10 — what it does not. The out-of-scope section is normative: an operator who deploys NTL against a threat listed there is unprotected, and needs to know that before deploying rather than after.Adversary Model
The critical assumption is the third. NTL identities are self-generated
keypairs with no registration and no cost. Sybil resistance is not
available, so every defence below is a bound on damage per identity
rather than an attempt to keep attackers out.
1. Weight Poisoning
Attack. The attacker sends traffic designed to move a victim’s synapse weights — inflating their own synapse so they receive traffic they should not, or pushing a competing path down so it is starved. At scale, with many identities, this steers a region of the network toward attacker-controlled nodes, enabling interception, selective dropping, or metering. This is the highest-severity attack specific to NTL. A learned router is being asked to take instruction from its traffic. Defences.- Per-identity influence cap (learning-model
§2.4). Total beneficial weight movement attributable to one identity is
bounded to
Cper windowT_infl. Exceeding the budget clamps further positive updates to zero. - Asymmetric caps. Negative updates are always applied. Without this, an attacker could deliberately burn their budget to become immune to penalties for the remainder of the window.
- Persisted accounting. Influence tallies live in the store, so an attacker who can induce a restart cannot reset their budget.
- Outbound normalisation (§2.3 of the learning model). Total outbound weight is fixed, so strengthening one synapse dilutes it again through rescaling. An attacker cannot grow the pie, only compete for a share.
- Reward requires a verified receipt. Positive reward flows only from a signed, verifiable receipt. Traffic volume alone earns nothing, which is what breaks the naive “spam to strengthen” attack.
- Signal-weight scaling.
Δw ∝ x, the carried signal’s weight, so flooding negligible-weight signals buys negligible influence.
N identities an attacker commands N · C
influence per window. Since identities are free, N is bounded only by the
attacker’s bandwidth and the victim’s max_synapses. The caps convert an
unbounded attack into one that is linear in attacker cost — a
meaningful improvement, not a solution. Operators in adversarial
environments SHOULD lower C, cap synapses per address range, and prefer
configured peers.
2. Forged and Replayed Receipts
Attack. Receipts are the reward signal, so fabricating them is the most direct route to controlling the model — cheaper than generating real traffic. Defences.- Receipts MUST be signed and MUST verify, or be discarded without updating any weight.
- A receipt MUST carry a
correlation_idmatching a decision the node actually journalled, and MUST arrive from the peer that decision was routed to. An unmatched receipt is discarded. - Outcome resolution is idempotent: the first receipt wins (storage-interface §5). Replaying a positive receipt has no cumulative effect.
- Receipts arriving after the aggregation window are discarded — the
decision has already resolved to
timed_out.
3. Eclipse Attacks on Topology
Attack. The attacker floods a victim’s topology knowledge with attacker-controlled peers until legitimate peers are evicted, isolating the victim on an attacker-controlled view of the network. Defences.- Provenance is recorded and enforced. Every peer record carries a
source(storage-interface §2). Adiscoveredorobservedpeer MUST NOT evict aconfiguredorbootstrappeer. - A floor on configured peers. A node MUST retain capacity for its configured and bootstrap peers regardless of discovery pressure. This is why the store must be able to count peers by provenance.
- Bootstrap diversity. A node SHOULD be configured with bootstrap peers under more than one operator. A single bootstrap operator is a single point of eclipse.
- Eviction by evidence, not recency. When at capacity, a node SHOULD evict the peer with the least successful interaction history, not the least recently added. Recency-based eviction is what makes flooding work.
4. Signature-Failure Penalty
Propagation Rule 5 penalises a peer that presents an unverifiable signature. This version makes the penalty and its recovery explicit. On signature verification failure for a signal arriving over synapses:
p defaulting to 0.5 — a single failure halves the
synapse’s weight. The signature-failure outcome additionally carries reward
−1.0, the strongest negative in the model.
Recovery is by ordinary learning, not by amnesty: the synapse regains weight
only through subsequent verified, successfully delivered traffic, at rate
η per success. Halving costs roughly w/(2η·x) successful deliveries to
undo — at η = 0.05, x = 0.8, about a dozen. This asymmetry is
intentional: verification failure is either an attack or a serious
implementation defect, and both warrant slow recovery.
Repeated failures compound multiplicatively. A node MUST prune a synapse
that accumulates signature_failure_prune_threshold failures (default 5)
within one influence window, and SHOULD refuse to re-form it for a cooldown
period (default 1 hour).
A node MUST NOT let signature failures charge against the victim’s
influence budget — the penalty is applied to the synapse that carried the
bad signature, and an attacker must not be able to exhaust a third party’s
budget by forging traffic that appears to come through them.
5. Resource Exhaustion
Attack. Flood a node to exhaust CPU, memory, storage, or its synapse table. Defences.
A node MUST apply the size bound before signature verification, and
before allocating a buffer for the frame.
TTL and deduplication go after verification, which is a deliberate reversal
of 0.2.0-draft — see propagation-rules Rule 5 for
the reasoning. In short: deduplication is a write, so checking it first lets
unauthenticated traffic claim identifiers and suppress genuine signals, and a
TTL refusal owes an acknowledged sender a receipt that must not be emitted on
an unverified signal. The residual CPU cost is one Ed25519 verification per
size-bounded frame from an already-authenticated peer.
Residual risk. Activation backpressure protects the node, not the
network. A flood still consumes upstream bandwidth, and a node that throttles
correctly may still be effectively unreachable.
6. In-Transit Header Mutation
An origin signature covers a signal’s immutable content: identifier, type, origin, timestamp, payload, encoding, scope, correlation id, tags, and delivery class. A relay cannot alter any of these without breaking the signature, which is what prevents payload rewriting and prevents an acknowledged signal being downgraded to best-effort. Four fields cannot be covered, because propagation mutates them by design:
A signature over these could not survive one hop.
Consequence. An on-path node can inflate a signal’s
weight or ttl,
or forge trace entries. Three things bound the abuse rather than preventing
it:
- A receiving node MUST enforce its own limits —
weightin[0, 1],ttlat or belowmax_accepted_ttl— and clamp or reject regardless of what arrived. Clamping is preferred to rejecting. The inflation is the relay’s doing, not the origin’s, so dropping the signal would let any on-path node destroy traffic simply by overwriting a field it is free to overwrite. A node SHOULD report a clamp:weightandttlsit outside the signature, so a clamp is evidence of a peer trying to win traffic or extend a signal’s life beyond what its origin asked for. The exception is a non-finiteweight, which has no sane target to clamp toward and is malformed rather than inflated — that MUST be dropped. - Hop-to-hop authenticity comes from the synapse, not the origin signature. A node knows which peer handed it a signal even when it cannot verify what that peer changed.
- A peer that inflates weight to win traffic still faces the per-identity influence cap, and loses synapse weight when the traffic it attracts fails to deliver.
weight or ttl as trustworthy inputs to
application logic.
A node MUST NOT use a received trace as evidence of a signal’s actual
path. It is a loop-prevention hint, not an audit trail.
7. Traffic Analysis
Signal headers — type, weight, tags, TTL, and the recorded trace — are readable by every node on the path. The trace in particular reveals the signal’s route, and tags reveal application semantics. A node MUST NOT place sensitive data in tags. Payload confidentiality is available through the crypto interface; header confidentiality is not provided. Traffic patterns are visible to any on-path node.8. Handshake Replay and Identifier Prediction
Two requirements that are easy to satisfy in appearance and miss in substance. Both were live defects in the reference implementation, and neither is bounded by the per-identity influence cap, so both defeat §1 and §4 rather than being bounded by them.Authentication must be per connection
A node MUST NOT treat a signed hello as authentication on its own. See synapse-lifecycle for the required challenge-response and the two accompanying rules (refuse your own identity; do not silently replace a live session). The reason it matters here rather than only there: an accepted impostor inherits the identity’s synapse and its accumulated weight, and a signature-failure penalty it incurs lands on the genuine peer’s synapse. That is exactly the third-party penalty exhaustion §4 promises is impossible, so an implementation that authenticates with a bearer token has silently voided that promise.Signal identifiers must be unpredictable
Signal identifiers are the network’s deduplication key (Rule 4), so a node that generates them predictably can have its traffic suppressed before it is sent. Identifiers MUST come from a cryptographically secure generator. A statistical generator is not sufficient even when its seed looks obscure: the common ones are invertible, so a single observed identifier recovers the state and yields every later identifier. Seeding from the node’s own identity is worse than arbitrary, because the identity is in theorigin field of every
signal the node emits.
The attack, given prediction:
- Peer with the nodes the victim routes through — identities are free (§10).
- Emit cheap signals carrying the victim’s next identifiers, signed honestly under the attacker’s own identity, so they verify normally.
- The victim’s real signal now hits
seen_signalsat each relay and is dropped: no handling, no forward, no receipt. - The victim’s decision times out and applies a negative weight update to an honest peer.
9. Origin Key Resolution
Propagation Rule 5 requires a node to verify a signal’s signature before processing or propagating it. Verification needs the origin’s public key, and a node ID isblake3(public_key) — a one-way
function, so the key cannot be recovered from the identifier.
A node therefore knows an origin’s key only if it has met that origin: the
handshake carries the key and binds it to the claimed identity. This has a
consequence that implementations MUST NOT paper over.
A node MUST drop a signal whose origin key it cannot resolve. It MUST NOT
process it, forward it, or act on it as a receipt.
The temptation is to forward it anyway, since a relayed signal from a stranger
looks like ordinary mesh traffic. That would be the cheapest attack in this
document: any connected peer could inject signals under any identity, at no
cost. Every mitigation in §1 through §4 is built on a claimed origin meaning
something. Worse, the incentive gradient would point straight at the hole —
forging as a known origin costs the forger a signature-failure penalty (§4),
while forging as an unknown one would cost nothing at all.
So the honest statement of the current guarantee is:
Verified delivery is one hop in the reference implementation. Multi-hop
propagation works only between nodes that have each met the origin.
Receipts inherit the same bound, for a related reason. A receipt is a
Targeted signal addressed at the acknowledged signal’s origin, and a node
that receives one either matches it to a local pending decision or discards
it — nothing relays it onward. A node with no direct session to the origin
therefore cannot deliver a receipt at all, and MUST NOT hand it to an
arbitrary peer in the hope that it will be forwarded: that looks like delivery
and is not, so the node’s own accounting records a sender as informed when it
was not. Relaying receipts would need the same key distribution as above, plus
a rule for relaying an unmatched receipt without turning every node into a
free amplifier for forged ones (§2).
Closing this needs key distribution, not a code fix. The obvious route is to
carry the origin’s public key in the signal: because the node ID is the key’s
hash, a recipient can check blake3(carried_key) == origin and then verify the
signature, with no third party and no directory. That is self-authenticating,
and it costs 32 bytes per signal. It is a wire-format change and so is deferred
to a signal-format revision rather than smuggled in as a bug fix.
Until then, an implementation MUST report dropped-for-unresolvable-origin
separately from failed-signature. They are different events: the second
identifies a misbehaving peer, the first only says the topology is carrying
traffic this node cannot authenticate.
10. Out of Scope
NTL does not defend against the following, as ofbeta_0.0.0. Each is a
real risk, listed so that operators are not surprised.
An implementation MUST NOT claim protection against anything in this table.
11. Deployment Guidance
The strongest available mitigation is an identity allowlist at synapse
formation. Where deployment permits it, most of this document ceases to
apply, because the adversary can no longer create identities freely.