Introducing the Mix Protocol: Enhancing Privacy Across libp2p Networks

The Vac team is excited to present a new raw RFC for a libp2p based Mix Protocol. This protocol aims to address a critical gap in the current libp2p framework: the lack of native support for sender anonymity.

What Makes our Mix Protocol Special?

At its core, the Mix Protocol leverages the Sphinx packet format, a proven method for anonymous communication in mix networks. By routing messages through a series of mix nodes, it ensures that neither intermediary nodes nor the final recipient can trace the sender.

Key features include:

  • Sphinx Packet Format: Guarantees anonymity and unlinkability through fixed-size packets and layered encryption.
  • Random Path Selection: Routes messages through a random series of mix nodes, concealing their origin.
  • Protocol Agnostic: Wraps around existing libp2p protocols without requiring changes to their implementation.
  • Pluggable Components: Allows for customizable spam protection, peer discovery, and incentivization mechanisms.
  • Delayed Forwarding: Thwarts timing analysis attacks by introducing random delays in message forwarding.

Anonymity Across All libp2p Protocols

One of the Mix Protocol’s most exciting aspects is its protocol-agnostic nature. It wraps around any existing libp2p protocol – whether it’s for messaging, file sharing, or more – without requiring code changes to existing frameworks. This makes it easier than ever for developers to integrate privacy features into their applications while ensuring sender anonymity.

Why It Matters

The Mix Protocol opens up new possibilities for privacy-preserving applications in the libp2p ecosystem:

  • Enhanced Anonymity: Add a layer of privacy to existing libp2p applications.
  • Censorship Resistance: Build networks that are more resilient to surveillance and censorship.
  • Flexible Integration: Incorporate privacy features without overhauling existing architectures.
  • Decentralized Privacy: Enhance user privacy without relying on centralized components.

Get Involved

We invite everyone to explore the potential of the Mix Protocol by:

  1. Reviewing the full specification: Mix Protocol Spec
  2. Sharing your thoughts on the protocol design and potential optimizations.
  3. Discussing integration strategies for existing libp2p applications.

We’d love to hear your feedback! Your insights are crucial to shaping the future of anonymous communication in the libp2p ecosystem.

7 Likes

Awesome work and great to see the agnostic approach to the topic. Thank you for that.

Doesn’t libp2p-gossipsub provide some sender anonymity, in this case unlinkability between sender ip and specific message, see On the anonymity of Waku-Relay ?

Some reference to support the following statement would be great please:

libp2p protocols do not inherently protect sender identities.

My understanding is that while libp2p-gossipsub protocol does provide some sender anonymity when StrictNoSign is applied, it is not enough enough to protect specific actors in a system where their network have a predictable pattern.

1 Like

Great to see this taking shape!

@fryorcraken the sender anonymity we define for relay/gossipsub is a weak anonymity that does not protect the anonymity of the libp2p endpoints involved in every libp2p transaction (including relay/gossipsub hops). This is of course especially detrimental for req-resp protocols where servers can easily identify and profile the “client” in each exchange. However, knowing the identities of each side of a relay hop also opens up the protocol to a range of fairly trivial deanonymisation attacks (e.g. timing analysis) even if messages are not signed.
TL;DR: existing Relay sender anonymity functions at a higher layer and provides weak anonymity only (see Waku Privacy and Anonymity Analysis Part I: Definitions and Waku Relay | Vac Research). We do not have any anonymity for the sending party on libp2p protocol level.

1 Like

Thank you both for your insights. @fryorcraken StrictNoSign does offer basic sender anonymity by omitting identifiers like from, signature, and key. However, as @haelius rightly points out, this anonymity is relatively weak and has limitations.

While StrictNoSign provides basic unlinkability, K-anonymity within the mesh, and plausible deniability, it doesn’t protect against:

  1. Powerful adversaries capable of traffic analysis
  2. Targeted attacks, even in weaker attacker models
  3. Deanonymization through timing analysis or correlation of network patterns

Our Mix Protocol aims to address these limitations by providing a more robust, protocol-agnostic solution. We’re working towards stronger anonymity guarantees at the libp2p protocol level, complementing and enhancing the existing privacy features in protocols like GossipSub.

This approach will better protect against sophisticated deanonymization attacks and provide stronger anonymity, particularly in scenarios where the current weak anonymity might be insufficient, such as in networks with predictable patterns.

2 Likes

I guess approach used here is similar to Tor?

Our Mix Protocol, while sharing conceptual similarities with Tor (layered encryption and multi-hop routing), is specifically designed for libp2p networks:

  1. libp2p Integration: Seamless integration, providing sender anonymity across libp2p protocols without requiring changes to their implementation.
  2. Decentralized: Operates without reliance on centralized or trusted entities, enhancing resilience and censorship resistance.
  3. Sphinx packet format: Provides stronger protection against certain attacks (e.g., tagging).
  4. Extensibility: Features pluggable components for spam protection, peer discovery, and incentivization, allowing adaptation to various use cases.

While both Tor and our Mix protocol protect sender anonymity, the latter is better suited for decentralized, p2p environments.

Regarding “Decentralized: Operates without reliance on centralized or trusted entities, enhancing resilience and censorship resistance”:

Nodes used for mixing will come from some population and the latter could have a fraction of Byzantine nodes. Presence of these nodes can make the prob. that all mix nodes, selected by the sender, are Byzantine very high.

1 Like

You raise a valid concern about Byzantine nodes in the mix network. Our protocol design acknowledges this challenge and incorporates several mitigations:

  1. Random path selection: Senders choose mix nodes randomly, reducing the probability of selecting an all-Byzantine path.
  2. Configurable path length: Users can adjust the number of mix nodes in their path, balancing anonymity and Byzantine resistance.
  3. Deanonymization probability analysis: We’re conducting analyses on deanonymization probabilities under various attack models, including AS-level adversaries. Our preliminary results suggest that with proper implementation of Sphinx packet format, random delays, and careful path selection (using 3-4 distinct nodes), we can maintain a low deanonymization probability even against strong adversaries controlling a significant fraction of the network.
  4. Reputation system (planned): We’re exploring reputation mechanisms to help identify and avoid potentially malicious nodes.

While these measures significantly reduce risks, they don’t eliminate them entirely. We’re actively researching additional Byzantine-resistant techniques and welcome community input on further improvements.

Ultimately, the protocol aims to provide strong anonymity guarantees while maintaining a balance with practical usability in decentralized networks.

Looking at the RFC

Some comments:

(1) Using ENRs and the v4 identity scheme mean that we know have 2 public keys on ENR records secp256k1 for ENR signature, and usually libp2p authentication at connection, and now ed25519 for Sphinx encryption.

I wonder if there is a way to move to a single encryption scheme by having:

  • ENR signature
  • libp2p auth at connection (libp2p-noise)
  • Sphinx encryption

Done with one key, one scheme.

Note it matters because The maximum encoded size of a node record is 300 bytes.

(2) supported_protocols (long name) provide a plain text version of each protocol. This can be problematic due to size restriction. It also does not specify the full protocol identifier. See (3)

(3) The RFC does not specify how the Sender should encode the protocol to use for dessimination. What is the role of the supported_protocols information onf the ENR? It seems not needed.

(4)

Choose a random exit node that supports the required libp2p protocol for the message.

Related to above, it may make sense to keep this out of the scope of the libp2p-mix protocol definition. Meaning that the sender nodes select an exit node that:

  • support mix protocol
  • fit whatever criteria the consumer requires

(5)

ii. Select remaining L-1 unique mix nodes randomly without replacement from the list of discovered nodes.

What is L-1? Would be good to introduce the variable first.

(6)

i. Decrypts the packet to obtain the next hop multiaddress
ii. Checks if the next hop is in the list of discovered nodes.
iii. If not, performs discovery for that specific node.

if the multiaddress is encoded in the packet. Then why performing discovery and not just proceed with connection?

Also, may be better to have multaddresses to allow for several transport protocols.

(7) If discovery is expected to be used mid-transmission then it may make sense to introduce redundancy in the circuit, meaning a tree-like circuit.

(8)

unique mix nodes randomly without replacement

What does this mean? I could not find reference to the concept of replacement in Sphinx’ paper,

(9)

Custom format with:

IP address (IPv4 or IPv6, 4 or 16 bytes)
TCP/UDP port number (2 bytes)
QUIC/TLS protocol identifier flag (1 byte)
Peer ID (32 bytes for Ed25519 or Secp256k1).

(10)

TCP/UDP port number (2 bytes)

Best to know which one it is. Or left to the context of the consumer?

(11)

Verify the spam protection mechanism applied to the message.

I wonder if the spam protection could be left out of scope of the libp2p-mix protocol, along side the selection of the dissemination layer (ie supported_protocols. Leaving it to be set by the consumer, as the spam protection depends on the dissemination network.

FYI, this basically what you store in an ENR.

(12)

Appendix A. Example Spam Protection using Proof of Work

This seems unnecessary in this RFC, as previously mentioned, I’d leave that out of the scope of the libp2p-mix protocol as this “spam” protection does not protect the libp2p-mix network, it protects the dissemination network.

How does one ensure that no malicious node produce a message with a huge circuit to spam the intermediary nodes? I assume some size restriction on the sphinx packet ensure that the number of nodes in the path is capped.

(13)

May need to reformat the RFC as itemization does not render properly:

2 Likes

I agree with @fryorcraken that aspects like discovery, spam protection should be left out of the spec. Maybe a reference can be made to indicate what is expected out of discovery and spam protection layers in the spec.

Adding some context based on my current understanding of spec and current implementation.
There are some deviations from the rfc which have to be identified during implementation. So, looks like the spec will have to be modified to match the implementation. Had a discussion with @haelius yesterday regarding this. Following are some high level deviations:

  1. mix is no longer implemented as a libp2p protocol but a libp2p transport. Challenges as to why are documented here
  2. Implementation doesn’t have a concept of exit node, rather the destination node is also expected to support mix. There maybe a way to change this, but it may have side-effect wrt anonymity properties.

This is a good point. it would be ideal to look for a single scheme to avoid adding more data to ENR. wdyt? @akshaya
But i am wondering that we are anyways going to hit the ENR limits if we have to include mix transport details in the multiaddr field.
We have faced this problem before as well in case of circuit-relay in status where ENR limits were being hit to due multiple multiaddresses being inlcuded. Wondering if is time to take a look at this problem of limited ENR size and address it.
cc @ksr are you aware if any work been done before on this front i.e to increase size of ENR or find an alternative way to keep publishing only diff in the records during changes(as the 300 bytes limitation seems to have been introduced due to records are relayed frequently and may be included in size-constrained protocols such as DNS as mentioned here?

As state above, since mix is going to be a transport the way a node advertises it supports mix will no longer be via protocol anymore and probably part of a separate field which encapsulates mix transport address or just part of multiaddress field.

This gets addressed by the deviations i had indicated above where-in mix is no longer a protocol but a transport type.

This gets modified as per deviation mentioned above that destination node is required to support mix.

L is supposed to be the path length, but yes…better to introduce the variable in the spec.

true, i guess if different transports are to be supported then it would be not possible to embed complete multiaddress but only peerID in the packet which would then require to do discovery. But this would introduce a latency until all paths are formed in the network and anytime a path is chosen where intermediary peers are not connected to each other.
So i guess each approach (filling complete multiaddress or only peerID) has its own tradeoffs.
@akshaya just including the next peerID should also be enough right.

Are you suggesting introducing multiple paths in the circuit at every intermediary node for redundancy? This may work if we are using mix with a libp2p protocol which is not req-resp based i.e gossipsub. But if we have to use with any other protocols such as lightpush/store(which is what we plan to first POC mix with) I see couple of challenges with introducing multiple paths for req-resp protocols:

  1. mix is used only as a logical tunnel between initiator and destination peer, not sure if we can consider having multiple paths in between.
  2. The reply to a request e.g in case of lightpush is planned to be implemented by the use of Single use reply blocks which from what i understand the node which has initiated the request will include some sort of a header for reply that is used by destination node in order to respond. this would preserve anonymity of initiating node. If we have to use multiple paths at every stage, this would not be feasible as destination node will end up receiving multiple requests to begin with.

To achieve redundancy, the initiator can choose to send same message via multiple paths to achieve redundancy.

not sure, maybe @akshaya can answer.

points 9,10: get addressed with my discussion above wrt whether we have to store complete multiaddress in the packet or only peerID.

@akshaya maybe we can update the spec itself as per current implementation since we can’t go back to a protocol approach.

1 Like

(14) Building on (6) and (7).

Discovery mid-transmission would highly impact latency.

The spec specifies that path selection should be performed as part of sending a message

  1. Perform Path Selection (refer Section 2.4)

This seems highly unreliable, as experienced with the lightning network.

A separate phase selection phase, as done with Tor’s circuit handling, seems more appropriate to provide higher reliability and latency.

LN has a different constraint on the existence of channels, meaning that you MUST do path selection per payment.

In the context of libp2p message sending, such constraint may not exist.

Building a path, and getting feedback that it works, would be better. Then one can use the path for several messages, and create a new one on a regular basis. Meaning less chance of failure when the consumer attempts to send a message.

(15) Using multiaddr to identify nodes in the path restricts to node that are externally reachable. circuit-relay can be used but it is not ideal.
Having a mix of PeerId and multiaddr and having several node per onion layer, may be useful to increase the potential selection of nodes, and includes nodes with existing outbound connections (but no inbound). Think Status Desktop.

Agree that selecting a path while sending a message is not practical as it would add latency. To mitigate this, we can consider that during the mix transport initialization phase and through the life-time of the usage of mix, there can be a separate routine that is identifying and generating a list of paths that can be used while sending messages. It will initiate and maintain connections towards the immediate peers in these paths as well.
This approach kind of sounds similar to tor based approach you had pointed out. This can be implemented outside the mix transport layer or within

I am thinking of coming up with a proposal of how mix can be integrated into Waku and where and how we can use it. Planning to highlight such points in that post.

(16) I would not prescribe the usage of ENRs due to its limitations (previously stated).
I would just state what information is needed per node, and leave it to the consuming protocol to specify how this information is store.

I am not convinced the full codec string for libp2p-mix is needed (if it’s a libp2p protocol). One would probably just need to know it’s a mix node. See (17) for why. In the case of Waku, We would probably just need to add a byte for mix in the waku2 key.

(17) discovered does not mean reachable. From experience with Waku, 80% (@prem to confirm) of nodes found via Waku Peer Exchange are not reachable. And those are filtered out from Discv5.

Discv5 is inadequate due to the lack of Time-To-Live associated to discoverable nodes. This is not a problem in the case of Ethereum, Or Tor, as most nodes are run on VPS or other servers.

This has been shown to be a limitation due to short lived nodes coming from Status Desktop (and tests).

We have done work around it so far because the cost is low (failed attempted connection). Not even sure it’s “low” as we have not measured the cost on battery usage.

In the practical context of Waku/Status app, expecting to find 5 nodes discovered on the layer to form a successful path is… laughable. More PC, it’s the biggest challenge I see here. Fixing the TTL on discv5 (or swapping to another discovery mechanism that better handle short-lived nodes) is likely to become a priority to use libp2p-mix.

Related question: Analysis of Failures in Mix Networks - #2 by fryorcraken

Alternative would be for the sender to have had a recent connection to all nodes in the path, to increase likelihood of success. But this seems to increase risk re de-anonymyzation (just a guess)

Tor Android has a “kindness” mode, to become a “Snowflake” proxy for other Tor users. Would be good to understand how they do discovery for this feature.

As mentioned above, i guess the choice is to decide whether to use full-address in the packet which provides lower latency vs discover peers along the path.
Similarly having several nodes per onion layer has some challenges with req-resp style protocols as explained above.

If mix was implemented as a protocol, this approach would have sufficed where-in it is specified as part of Waku bitfield. But since mix is going to be a transport we may have to include more information in ENR.

Yes, in case of status the network is highly composed of nodes which are not available most of the time i.e probably 10-20 fleet nodes that are online all the time vs 100’s of desktop nodes which come and go during different times of the day. This is probably the primary reason why many nodes are not reachable in combination with nodes behind strict NATs or multi-level NATs which are hard to reach as many run on home internet.

If we have to integrate mix into a network like status, then definitely we need to work on improving discovery either by tuning discv5 or come up with separate protocol. But the idea is to begin with integrating mix into waku relay nodes that are assumed to be mostly available and delay addressing this problem to next phase maybe.

Thanks for the insightful conversation. A couple of thoughts/questions:

we may have to include more information in ENR.

I’m a bit confused as to why ENR and various discovery techniques are part of this specification at all. The ENR is simply a convenient way to encode node information and is compatible with disc protocols like discv5. I think libp2p mix should only be concerned with when discovery should happen. In this regard, I’m with @fryorcraken in that we don’t want per-hop discovery and fully encoded next hop addr(s) would be worth the slightly extra bandwidth (or is there some other limitation here)?

But since mix is going to be a transport

To me this sounds like a new multiaddr format? In other words, we’ll need something like ipv4/0.0.0.0/tcp/2005/mix/l0tsofH3x? However, even after reading the justification for moving away from a protocol to a transport model, I’d be curious to know whether this is a fundamental limitation in libp2p or simply a matter of changing how code is structured? I can well imagine that it’s complex to introduce libp2p protocol layering, but if it ensures greater flexibility in future, it’s perhaps worth doing? E.g. couldn’t a libp2p payload be “shifted down” to a “virtual transport” payload if we properly design such a path?

Implementation doesn’t have a concept of exit node , rather the destination node is also expected to support mix.

To me, this seems to be the most NB limitation to address, as it introduces an unwanted coupling between the mixed path and the mixed protocol. It would be good to understand if this is an artifact of mix now being implemented as a transport or whether this is because of a more fundamental problem.

2 Likes

Agreed, these can be part of the spec of the users of mix e.g in waku mix spec.
The simplest would be to encode next hops address in the packet. A minor limitation would be if mix has to use different underlying transport (TCP or quic), and if the mix node wants to support multiple such transports for mix, then this info will have to be fetched appropriately via other mechanisms. But this is a very minor concern and not to be worried at this point.

yes

I would like @akshaya to pitch in for the rest of your points. But essentially, I kind of agreement with you on them as well.

First off, big thanks to @fryorcraken, @prem, and @haelius for the incredibly detailed and thoughtful feedback on the Mix Protocol RFC.

General Clarification on the Spec

The current spec is somewhat outdated. As @prem mentioned, we have shifted from the initial protocol-based approach to a transport-based approach due to challenges outlined in the README.md here. Even in the protocol-based approach described in the spec, certain aspects could be clarified further.

For example, the spec already states:

The Mix protocol is designed with flexibility in mind, allowing for pluggable components such as spam protection, peer discovery, and incentivization mechanisms. This design choice enables the protocol to evolve and adapt to different network requirements and constraints. This also leaves room for future enhancements such as cover traffic generation.

However, this flexibility is not consistently emphasized throughout the document. Components like discovery mechanisms (e.g., discv5) and spam protection (e.g., PoW) are presented as examples but are not mandatory. These examples were intended for clarity but may have inadvertently complicated the spec. In future updates, we plan to simplify this by removing these examples or explicitly marking them as optional.

The reason for including discv5 as an example was to ensure that mix nodes are chosen randomly. Any discovery mechanism that provides a random sample of nodes from the entire network (without skew) can be used.

Why Not a Tor-like Approach

Initially, we explored a Tor-like approach (Tor Push). However, it is known to be vulnerable to traffic correlation attacks in two main ways:

  1. Traffic volume analysis: An attacker observing both ends of a Tor circuit can correlate the volume and timing of data to deanonymize users.
  2. Probing attacks: Active adversaries can inject traffic patterns and observe their propagation through the network.

By switching to Sphinx cryptographic format and implementing a mix network approach, we aim to achieve better anonymity protection against these types of attacks, albeit at some cost to performance. Our design decisions prioritize stronger metadata protection. It’s important to note that both systems have their strengths and are designed for different purposes.

One thing to keep in mind is that for complex use cases (e.g., GossipSub), only the first hop may need to be anonymized rather than all the hops. This would reduce overall latency. Additionally, we can send messages over 3-4 redundant paths to improve reliability without significantly increasing the deanonymization probability.

Responses to Specific Comments

(1) Multiple Keys in ENRs

This is a valid concern. Currently, ENRs include both secp256k1 (for ENR signatures and libp2p authentication) and ed25519 (for Sphinx encryption). While having separate keys for signing and encryption is generally a good practice for security separation, ENR size constraints are indeed a challenge. As this is a bottleneck, we should explore ways to consolidate or optimize key usage without compromising security.

(2), (3), and (4) Supported Protocols in ENRs

Mix transport does not use multistream negotiation like traditional libp2p transports. Therefore, the sender must know beforehand whether the destination supports a specific protocol. This can be advertised in a space-efficient manner within ENRs or another metadata mechanism. We agree that the current approach could be optimized further.

(5) Path Length Variable

As @prem mentioned, L refers to the path length. This omission in the earlier part of the spec is an oversight.

6) Mid-Transmission Discovery

In our current PoC implementation, we encode the full multiaddress including peerID (or the mixID) in the Sphinx packet. This eliminates the need for mid-transmission discovery. The format used is:
/ip4/<ip4>/tcp/<port>/mix/<id>
as @haelius mentioned.

(7) Redundancy in Circuits

Since discovery is not required mid-transmission in our current implementation, redundancy at intermediary nodes is unnecessary.

(8) Random Node Selection Without Replacement

To mitigate traffic correlation attacks, nodes in a path must be chosen randomly without repetition. This ensures stronger anonymity properties by preventing any single node from observing multiple points in a path.

(9) and (10) Transport Protocol Flexibility

The choice of transport protocol (TCP, QUIC, etc.) is left to the consumer for flexibility. In our PoC implementation, we use TCP but aim to support both TCP and QUIC in future iterations.

(11) Spam Protection

Spam protection is intentionally designed as a pluggable component and has been moved to an appendix in the current spec for clarity. To avoid confusion, we may completely omit it from future versions of the spec or explicitly note that it is optional.

(12) Preventing Abuse of Mixnets

Spam protection mechanisms like PoW are included to prevent abuse of mixnets by malicious users opening excessive connections to destinations. While this does not directly protect intermediary nodes from DoS attacks, it helps mitigate abuse when anonymizing connections to, for example, a light push peer.

(13) RFC Formatting Issues

We will review and address formatting issues in future updates to ensure better readability.

For further clarity on any unaddressed points, 'll follow up with detailed discussions in subsequent communications.

1 Like

When you form a circuit. Whether it’s every t time or for every message, you need some information for each node in the circuit.

The latest information can come from 2 sources:

  1. From a discovery mechanism (e.g. discv5)
  2. From being actually directly connected to the nodes

In the case of (1), you need to assume that the majority of discovered nodes are not reachable. Which means that if you attempt to form a circuit with no-redundancy, it is highly likely to fail.

(2) is a practical manner to ensure that your circuit formation work. However, I am not sure of the anonymity implications.