Mix Decoy Stats Propagation
Abstract
In the context of continuous time mixing stategies such as the memoryless mix used by Katzenpost, n-1 attacks may use strategic packetloss. Nodes can also fail for benign reasons. Determining whether or not it’s an n-1 attack is outside the scope of this work.
This document describes how we will communicate statistics from mix nodes to mix network directory authorities which tells them about the packetloss they are observing.
1. Design Overview
Nodes (mixes, gateways, and providers) need upload packet-loss statistics to the directory authorities, so that authorities can label malfunctioning nodes as such in the consensus in the next epoch.
Nodes currently sign and upload a Descriptor in each epoch.
In the future, they would instead upload a “UploadDescStats” containing: * Descriptor * Stats * Signature
Stats contains: * a map from pairs-of-mixes to the ratio of count-of-loops-sent vs count-of-loops-received
refer to our non-existent document on Provider orignated deocy loop traffic design discussion
1.3 Terminology
wire protocol
- refers to our PQ Noise based protocol which currently uses TCP but in the near future will optionally use QUIC. This protocol has messages known as wire protocolcommands
, which are used for various mixnet functions such as sending or retrieving a message, dirauth voting etc. For more information, please see our design doc: wire protocol specificationProviders
- refers to a set of node on the edge of the network which have two roles, handle incoming client connections and run mixnet services. Soon we should get rid ofProviders
and replace it with two different sets,gateway nodes
andservice nodes
.Epoch
- The Katzenpost epoch is currently set to a 20 minute duration. Each new epoch there is a new PKI document published containing public key material that will only be valid for that epoch.
2. Tracking Packet Loss and Detecting Faulty Mixes
Katzenpost lets different elements in the network track whether other elements are functioning correctly. A node A will do this by sending packets in randomly generated loops through the network, and tracking whether the loop comes back or not. When it comes back, it will mark that as evidence, that the nodes on the path of that loop are functioning correctly.
Experimental setup, node A:
- Data: each network node
A
collects a record of emitted test loops in a certain epoch, their paths and whether they returned or not. Importantly, each loop is the same length and includes l steps. - A segment is defined as a possible connection from a device in the
network to another, for example from a node in the layer
k
to a node in the layerk+1
. Each loop is a sequence of such segments. - Each node
A
will create 3 hashmaps,sent_loops_A
,completed_loops_A
andratios_A
. Each of these will use a pair of concatenated mixnode ID’s as the key. The ordering of the ID’s will be from lesser topology layer to greater, e.g. the two-tuple (n, n+1) which is represented here as a 64 byte array:
var sent_loops_A map[[64]byte]int
var completed_loops_A map[[64]byte]int
var ratios_A map[[64]byte]float64
- Every time the node A sends out a test loop, for each segment in the
loop path, it will increment the value in
sent_loops_A
. - When a test loop returns, for each step in the loop path, it will
increment the value in
completed_loops_A
. - Generate a new map entry in
ratios_A
for each mix-node-pairp
, ifsent_loops_A[p]==0
setratios_A[p]=1
. Elseratios_A[p] = completed_loops_A[p]/sent_loops_A[p]
- Plot the resulting distribution, and calculate the standard deviation to detect anomalies. Have the node report significant anomalies after a sufficient time period as to not leak information on the route of individual loops.
- Anomalies may have to be discarded if the corresponding
sent_loops_A[p]
is small.
You would expect the distribution of values in
completed_loops
to approximate a binomial distribution. In
an absence of faulty nodes, ratios
should be 1, and when
there are some faulty nodes values at faulty nodes should approach 0 (if
the node doesn’t work at all), and be binomially distributed at nodes
that can share a loop with faulty nodes.
Therefore each mix node generates a statistics report to upload to the dirauth nodes, of the struct type:
type LoopStats struct {
Epoch uint64
MixIdentityHash *[32]byte
Ratios map[[64]byte]float64
}
The report is subsequently uploaded to the directory authorities, which combine the reports of individual nodes into a health status of the network and arrive at a consensus decision about the topology of the network.
3. Uploading Stats to Dirauths
Stats reports are uploaded along with the mix descriptor every Epoch. A cryptographic signature covers both of these fields:
type UploadDescStats struct {
Descriptor []byte
StatsReport []byte
Signature []byte
}
Statistics reports collected during the XXX period of time, that is, the time between descriptor N+1 upload and descriptor N+2 upload, are what will affect the topology choices in epoch N+2 if the dirauths collectively decide to act on the very latest statistics reports in order to determine for example if a mix node should be removed from the network:
| ---------------- epoch N ---------------- | ---------------- epoch N+1 ---------------- | ---------------- epoch N+2 ---------------- |
| ----------- UD_N+1 ---------------------- | ------------ UD N+2 ----------------------- | ----------- UD N+3 ------------------------ |
| ------------------ XXX ---------------- |