nymCHAT Winter Season '25 Submission

nymCHAT Winter Season '25 Submission https://forum.nym.com/uploads/default/optimized/1X/26fb88dfa6c94ef3a7025101c1b6bd75fc774323_2_576x1024.gif
none 0.0 0

nymCHAT - Mixnet Messaging App


knockknock


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 attached SURBs.

  • The server receives the message and checks its DB for bob.

  • If it has an entry, it forwards PK_bob to alice via SURB.

  • 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 attaches PK_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 and PK_tmp from it. Bob verifies the signature using PK_Alice. If successful, he uses PK_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! :eyes:

6 Likes

Awesome project I look forward towards stuff like this start of a fix for much of the opsec issues regarding supposedly private communications I.e bad irc setup

Can you add public key only connections?
And a browser based very based chat setup for example dns.chat or nymchat://
Or maybe an electron/sandboxed Firefox equivalent
Then with group messages and a user bookmark system this could be on par or better than simplex chat
And could you add post quantum where possible or at least hybrid like simplex chat
I.e using a kyber and rsa public key then use both for aes encapsulation

And add an option for some sort of nym over nym setup so I can connect to entrance gatway on let’s say a 2 hop from a 5 hop so p2p can be about at least as private as the more centralized connection until client ids can be served at exit gateways

And if not already there or in production (thinking on keyboard sorry if I did not see it as to do or whatnot) file sharing and image loading and media loading essentially but with optional metadata removal when uploading and after download before the actual processing of media and maybe a more aggressive version that removes non media data entirely so junk data in an mp4 that does not contribute to the video or audio is removed and I guess a media sandbox implementation into client is what I’m saying but 2 essentially one as file firewall in and out and one for the viewing itself just in case since that’s where many chats and other private communications end up failing

And possibly add for the centralized part longer delay for handshakes that could be specified by client and or server (I.e) shared random just in case overall though already a really good product though not done but still good thank you for sharing and contributing this free software with free as in freedom nym is paid for good reason but anyways thank you awesome we need developers like you in this community and this might enable coordination between more of them and you (plural) is a better way to iterate that but saying yous seems weird I don’t know

2 Likes