Official peer and server implementations.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.


Title: Cwtch Protocol: Facilitating Anonymous Collaboration Author: Sarah Jamie Lewis Doc Class : [11pt, twocolumn]article

Actors & Identity

All parties in a Cwtch System run ricochet nodes.

Cwtch Client

A Cwtch Client identity consists of:

  • A Name
  • An Onion Address (and an associated private key)
  • A Nacl Public Key (and an associated private key)

Cwtch Server

A Cwtch Server identity consists of:

  • A Name
  • An Onion Address (and an associated private key)

Threat Model


One of the key attacks we must defend against in a multiple-party messaging system is the risk of one party attempting to impersonate another.

There are two levels to this kind of the attack, systemic impersonation and superficial impersonation.

Systemic Impersonation would result from the system being unable to distinguish between two parties. Due to the anonymous nature of our approach, we adopt a long lived public key that can be used to link & verify that seperate messages belong to the same party.

Superficial Impersonation is more tricky, it would result from a user being tricked to accepting that two distinct identities are the same. We cannot rely on the user to compare public keys to avoid this. An attacker may try and change their profile name to match a target - it should be noted that restricting profile names to be unique per Cwtch system is not sufficient to prevent this attack (because of homoglyph style attacks), nor is such a restriction desirable.

To prevent superficial style impersonation we take a multi step approach:


Client <-> Server Messages

When a client wishes to join a Cwtch system, they must first identify the address of the Cwtch server.

One a Cwtch server is known, the client connects to the Cwtch server over Ricochet, and performs a standard im.ricochet.auth.hidden-service authentication.

At this point the Cwtch Server initiates an EnableFeatures setup in an attempt to detect that the client is indeed a Cwtch client, or if it is a bare bones Ricochet client.

    message ServerIdentify {
            string name = 1;
            string topic = 2;
            int32  difficulty = 3;

If a Cwtch Client is detected, that the CwtchServer sets up a im.cwtch.event through which all other communication between the client and the server takes place.

            enum EventType {
                    NIL = 0;
                    JOIN = 1;
                    LEAVE = 2;
                    MESSAGE = 3;

            message Event {
                EventType type = 1;
                string client = 2;
                int64 timestamp = 3;
                string detail = 4;
                bytes proof = 5;

Event Types

  • JOIN events are sent when a client connects to the server
  • LEAVE events are sent when a client disconnects from the server
  • MESSAGE events are sent when a client sends a message to the server, these are broadcast to every other connected client.

Sending Messages

    message Message {
            string message = 1;
            bytes signature = 2;
            bytes spamguard = 3;

Message Signatures

Preventing Spam Through SpamGuard

To prevent abusive clients from flooding the server (and therefore other clients) with a large number of message, all messages must include a complet spamguard field.

This field is nonce|sha256(message.signature.nonce). Valid spamguard fields must ensure that the sha256 digest begins with difficulty number of 0x00 as defined by the server profile.

This requires that clients try a number of random nonces prior to sending any messages.

Message packaets with invalid SpamGuard digests will be discarded by the server.

To ensure that a client cannot find a single valid SpamGuard digest, e.g. for the message hi, and use that to spam clients.

Client <-> Client Messages


When 2 clients are online at the same time, they can use the opporunity to exchange ClientIdentify messages over an im.cwtch.client.identify channel:

    message ClientIdentify {
            string name = 1;
            bytes  ed25519_public_key = 2;
            bytes  nacl_public_key = 3;
  • name is a readable name to help identify this client.
  • ed25519_public_key is used to authenticate public messages from this client.
  • nacl_public_key is used to authenticate private messages from this client.

Once a client has the Profile of another client, they can proceed to validate that the messages they have received from the server via the im.cwtch.event that are tagged as originating from the client do in fact validate.

Private Messages

When both clients are online, private messages can be sent to eachother using an channel.

When either client is offline, private messages are sent utilizing the im.cwtch.message channel - instead of a regular message being sent, the message is begins ENC- and contains an encrypted message.

Note that there is no metadata associated with private messages, and as such each client must attempt to decrypt the message with their own keys, and discard messages that fail.