nymCHAT - Mixnet Messaging App
Project Overview
nymCHAT clients communicate with a discovery node through the mixnet, which is a user discovery / message relay service. The discovery node stores username -> (pubkey, senderTag)
in a local db.
A senderTag
is a random alphanumeric string that corresponds with single use reply blocks (SURB), which are received from incoming messages. Clients attach SURBs to all messages, allowing the discovery node to reply to messages without ever learning the origin or destination of the message.
The discovery node enables fully pseudonymous user discovery and message forwarding. All messages are end to end encrypted by the clients to ensure the node cannot read any message content.
Users also have the ability to route their messages directly to one another, skipping the discovery node entirely. To enable this, clients exchange handshake
messages which reveal their current nym addresses. All further messages can be sent directly from client -> client
, instead of client -> discovery node -> client
. The handshake is encrypted and formatted exactly like a normal message to prevent the server from a) knowing you are sending a handshake and b) learning your address.
Security Properties
I. Transport Privacy
All traffic routed through Nym mixnet via sphinx packets
II. Message Privacy
End-to-end encryption using ECDH with ephemeral keys + AES-GCM for forward secrecy.
III. Authentication
Signature verification using long-term EC keys (SECP256R1)
IV. Pseudonymity
Username registration with no linkage to real identity
V. Direct Communication
Optional p2p mode bypasses discovery node after initial contact
Deployment & Build Process
The application is built for ease of deployment using Docker:
Client Setup
Server Setup
To run both client and server in docker compose, or build from source, see:
Build
System Components
Discovery Node
- Stores
(username → (public_key, senderTag))
mappings. - Facilitates lookups and message forwarding.
- Runs a nym-client binary for Mixnet connectivity.
Client Application
- Simple NiceGUI web UI
- Implements message encryption, decryption, verification, and storage locally.
- Uses Rust-Python FFI bindings for spawning ephemeral nym-clients and other Nym SDK utilities.
Protocol
alice
wants to send a message to her friend bob
.
Client Registration
-
Alice sends a registration request containing
(alice, pk_alice, SURBs)
to a server. -
The server responds with a nonce.
-
Alice signs the nonce and sends it back to the server.
-
The server verifies the signature, if successful adds
alice -> pk_alice, senderTag
to the DB and responds with a success message.
User Lookup
-
Alice sends a query to the server, containing target
bob
and attachedSURBs
. -
The server receives the message and checks its DB for
bob
. -
If it has an entry, it forwards
PK_bob
to alice viaSURB
. -
Alice stores
bob -> PK_bob
in her local contacts table.
Message Sending:
-
Alice uses
PK_bob
and an ephemeral keypair(SK_tmp, PK_tmp)
to derive a shared secret, then encrypts the message and encapsulates it into a payload. -
She attaches
PK_tmp
for bob to derive the same shared secret. Since this is her first message to Bob, she also attachesPK_alice
. Alice signs the payload for Bob to verify. -
Alice then encapsulated this payload into the proper format, and signs the entire outer payload for the server to verify.
-
This message is sent to the server, addressed to Bob.
-
The server verifies Alice’s outer signature for routing; it cannot read or verify the message payload, which remains end-to-end encrypted. If successful, the server queries it’s local db for Bob and retrieves the associated
senderTag
. -
The server forwards the encrypted message to Bob via
SURB
. -
Bob receives the encrypted message and parses
PK_alice
andPK_tmp
from it. Bob verifies the signature usingPK_Alice
. If successful, he usesPK_tmp
to derive the same shared secret and decrypts the message.
Future Work
Security Considerations
- Key vault
- Confirmation mechanisms for first-contact key trust.
- Replay protection and server message authentication.
Teaming up with dial0ut
Working with Hans Bricks @hans1337 to enhance the overall ecosystem.
Full Rust Implementation
The client and server components will be rewritten in Rust to improve performance, security, and maintainability.
Self-Hosted Groups
Integration of Messaging Layer Security for E2E encrypted self-hosted groups.
Federated Discovery Nodes
Implement a P2P network of discovery nodes for decentralization.
Tauri Front End
Taking inspiration from the Nym team and building a proper GUI using Rust & React.
Conclusion
nymCHAT successfully demonstrates a secure chat app MVP that preserves user privacy via the Mixnet. Use of the discovery node, SURB-based routing, and end to end encryption ensure that users can discover and communicate with one another securely without leaving the mixnet.
This submission marks the completion of the MVP phase, with a solid groundwork laid out for future development.
Massive thanks to the Nym team for this opportunity, I am forever grateful!
Continuation proposal coming soon!