nymChat - Python Messenger

Hello everyone! I’m excited to share nymChat, a python based messaging client that uses Nym’s mixnet via WebSocket. It’s a small start, but the goal is to create the most secure messaging platform on the planet.

You can find the code and README here: GitHub - code-zm/nymChat: Python Messaging Client for secure, asynchronous communication over the Nym Mixnet.

Ensure the nym-client is configured & running before you run the python script.

To send a message, simply run nymChat.py and enter the recipient Nym Client Address.

Some goals I have for this project:

  • client side encryption/decryption
  • usernames + user search
  • groupchats
  • clean front end
  • ios / android apps

Feel free to fork the repo and make any changes you’d like. Also any critiques on what I have so far are much appreciated!

Thanks,
code-zm

4 Likes

hey @code-zm, this is excellent work, thank you for the contribution. Let’s turn your future goals into a roadmap and get you a grant for this project!

How long do you think you’d need to build apps on different platforms with the features you listed above?

  • client side encryption/decryption
  • usernames + user search
  • groupchats
  • clean front end
  • ios / android apps

Keep up the good work :slight_smile:

3 Likes

Hello! I’ve devised a 12 week road map to guide me to release.

Link to roadmap: Blocks And Arrows

2 Likes

Here is the technical diagram, let me know if I am missing anything important!

Link to diagram: Blocks And Arrows

2 Likes

Hey there, cool work! :slight_smile:

As per my post to you in the element chat I think you could do something easy with the address book by parsing something like the incoming SURB sender tag and/or a random nickname assignment pretty easy.

I’d like to hear more re: the key management, since this would be an extra layer of encryption at the app level above the encryption that’s happening at the network level with the client themselves.

Its really cool to see someone writing in Python as well, I’m wondering whether this might be a good opportunity to look into some Rust-Python FFI as we have already done with c++ & Go so you don’t have to rely on having 2 processes running with the standalone binary, but it could all be bundled together. Might this be interesting to you? No worries if not, just thought I’d bring it up.

I’m wondering what your plan is regarding group chats, which I saw you mention in the element chat but I don’t see here.

1 Like

SURBs, User Search, and Key Management

My initial idea was to utilize SURB’s as a “secret chat” feature that replies directly using the SURB instead of a recipient nym address. From my understanding, the initial request must still be sent directly to a nym address. From that point on message routing can be done strictly through SURB’s. This essentially means you have to be doxxed (nym-client address) in order to to communicate through SURBs, which is not good.

A solution could be a centralized server that acts as a registry. Each client will publish a batch of SURBs, an ephemeral public key, and a session ID (sender tag)

For example:
Client A creates and publishes a batch of SURBs to a registry with an associated ephemeral public key + session ID.

Client B could then query this registry using Client A’s session ID and return associated SURBs. This way Client B can initiate conversation with Client A without ever knowing their nym-client address.

As for key management, I am thinking of using ephemeral public keys tied to each batch of SURBs. Each time a batch of SURBs is exhausted, the associated subkey is revoked. The client will then automatically generate new SURBs + subkey and publish them to the registry. The private key will be generated and stored securely on the local machine.

This setup prioritizes anonymity and usability but also introduces the inherent risks of any centralized service.

I am not sure how to implement groupchats yet, I want to focus on the messaging itself first. If anyone has any insights I am all ears.

Thanks,
code-zm

So I really like where this is going, this sort of ‘SURB broadcast / deaddrop’ service! I want to throw a bunch of points in here as its bringing up a few concurrent trains of thought… Let me know if any of these bring up ideas/questions :slight_smile:

What is revealed by a Nym address

This essentially means you have to be doxxed (nym-client address) in order to to communicate through SURBs, which is not good.

Yes the SURB model sort of relies on a client - server model in which you have a client talking to a backend service of some kind you don’t want to doxx yourself too, not necessarily in a situation where your comms/addressing is more peer to peer. It sort of relies on one party (the client) always initiating the connection/request to the other (the server).

Remember that ‘doxxing’ a Nym address only shows which Gateway your client is using as an entry gateway, so overall not a whole lot is being revealed. That said, it is still showing which gateway a client is using, so depending on your threat model could still be undesirable.

Sending SURBs around

Client B could then query this registry using Client A’s session ID and return associated SURBs. This way Client B can initiate conversation with Client A without ever knowing their nym-client address.

You would probably not need to send the SURBs from the server to B to then package and send to A, just have B send their messages to A through the mixnet to the server already encrypted for A, and then the server can just package them and A can decrypt them on the ‘app’ level after they’ve done the Nym Client encryption → Mixnet → NC decryption dance.

MVD

This has the potential to grow into quite a big thing alongside the chat, so I think working out some sort of minimum viable version might be good to contain it a little :slight_smile: That said, I think this is also starting to hone in on an interesting problem that we don’t immediately have a solution for right now, which is how to communicate in a p2p-ish context without having to reveal your Nym address. I also think this might deserve a grant on its own, using the chat as a ‘proof of concept’ that it works. Really interesting stuff.

SURB requests

We might have to expose some method on the client which would allow for SURBs to be ‘manually’ requested, which wouldn’t necessarily be an issue, but this is not something you can do right now.

A high level example: for the moment, assuming that B has had 100 SURBs sent to it from A (B does not know A’s address), but the reply it wants to send requires 120 SURBs, it will use SURB 100 to request more SURBs from A before sending the full 120SURB reply.

What you would maybe want to do in this instance is something more like have the server / intermediary service keep track of how many SURBs remain per ‘bucket’ (the random alphanumeric string used to differentiate SURBs for a session) and then keep sending requests to keep this ‘topped up’ on its own. This might be jumping the gun a bit though in relation to my next point…

SURB lifetimes

For the moment the SURB is valid indefinitely, but the client will purge its local DB of SURBs that are older than a day on restart. We still have a few features to add to the Mixnet to add some extra security which will lower the validity of the actual SURB though: once we implement proper key rotation and replay protection, then SURBs will only be valid for the length of the key epoch. This length is still to be decided.

This means that you shouldn’t assume a situation in which Client A sends a bunch of SURBs to the server which can be used over the next e.g. day, but instead it will be more of a back-and-forth flow of SURB requests and topups.

As such, you’re possibly adding a few back and forth trips through the Mixnet for a message, if we assume that Client B wants to send a message to Client A but requires more SURBs than A current has stored on the server. Not a problem per se, just something to be aware of.

Potential attack

One thing to bear in mind is that there is the possibility of an (active) attack that the server, assuming it is untrusted, could try and perform against the clients. This would involve consistently requesting more and more SURBs from the clients, then sending all of these through the network at once, in order to try and create a ‘burst’ effect in the traffic and monitor which Gateways exhibit this behaviour, in order to work out which Gateways the clients of the SURBs were connected to. This is not necessarily a problem with this design, more a general active attack which it is good to be aware of here.

1 Like

Nym combined with GNUnet architecture development is a good choice

2 Likes