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 ## Impersonation 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: // TODO # 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 ## ClientIdentify 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 `im.ricochet.chat` 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.