Skip to content

Latest commit

 

History

History
123 lines (86 loc) · 8.43 KB

spec.md

File metadata and controls

123 lines (86 loc) · 8.43 KB

Detox Chat protocol specification

Specification version: 0.2.0

Author: Nazar Mokrynskyi

License: Detox Chat specification (this document) is hereby placed in the public domain

Introduction

This document is a textual specification of Detox Chat protocol. The goal of this document is to give enough guidance to permit a complete and correct implementation.

Refer to the design document if you need a high level overview.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in IETF RFC 2119.

Glossary

  • Contact: node in Detox network that implements Detox Chat application protocol
  • Contact request: Initial connection of new contact

Foundation

Detox Chat works on top of Detox network, make yourself familiar with Detox network first as this document will not cover it.

Detox Chat is only one possible protocol that works on top of Detox network. In order to identify that remote contact wants to communicate using this particular protocol, its application parameter during connection should start with detox-chat-v0 (this may change in future incompatible versions of the specification). After detox-chat-v0 there might be some extensions, that are beyond core Detox protocol and are not required for implementation, but may be supported by some implementations.

Supported commands

Following commands MUST be supported by all implementations:

Command name Numeric value
SECRET 1
SECRET_RECEIVED 2
NICKNAME 3
TEXT_MESSAGE 4
TEXT_MESSAGE_RECEIVED 5
  • SECRET - used for sending secret
  • SECRET_RECEIVED - used to confirm that secret was received
  • NICKNAME - used to send own nickname
  • TEXT_MESSAGE - used to send text messages
  • TEXT_MESSAGE_RECEIVED - used to confirm that text message was received
  • Command with numeric value 0 is reserved for future use.
  • Commands with numeric values 6..63 are reserved for future use.
  • Commands with numeric values 64...255 are translated into additional commands from range 0..191 and can be used for custom extensions

ID and its encoding

In order to add someone to contacts and possibly to make a contact request, it is necessary to know contact's ID.

There are 2 types of ID: plain ID and ID with secret. Plain ID is just Ed25519 long term public key of a node. ID with secret is the plain ID with some secret appended to it.

Secrets are used as anti-spam system, user can create any number of such secrets for different purposes, so that during contact request it will be clear which secret was used. Such secrets are only used during contacts requests, all future connections use secrets from last successful secrets exchange.

For convenience of distribution of such IDs in text form, following encoding procedure is used:

  • take 32-byte Ed25519 long term public key of a node
  • optionally append a secret up to 32-bytes long
  • compute Blake2b-256 hash of above, take first 2 bytes from that hash and append to above
  • base58-encode all of the above using dictionary 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz (as used in Bitcoin and some other projects)

Upon decoding, hash is recomputed and last 2 bytes are compared in order to make sure, ID was not misprinted.

Connections and contact requests

Contact request is an initial connection to a contact, meaning no previous secrets exchange took place.

Contact request is only possible when secret is used. If no secret was specified, node MUST reject contact request. If contact was previously added using plain ID, first connection without secret MUST be accepted, since contact is already added and no contact request needs to be sent.

After first successful connection happened, any subsequent connections use secrets from last secrets exchange. Connections with secrets that use incorrect secrets MUST be rejected and in specific cases SHOULD notify user that they or their contact was compromised (see "Partial post-compromise security and compromise detection" section below).

Secrets exchange

Once user is connection to other contact, the first thing that happens is secrets exchange, commands other than SECRET and SECRET_RECEIVED MUST be rejected.

There are 2 secrets with each contact: local and remote. Local secret is generated by local node, remote secret is generated by remote contact.

During secrets exchange each contact generates a new, previously unused local secret and sends it to the other contact using command SECRET and contents as follows:

  • 32 bytes - newly generated local secret

Once SECRET with new remote secret is received, node MUST replace previous remote secret with new one immediately and send SECRET_RECEIVED command in response with no contents to confirm that secret was indeed received. Node MUST NOT accept known previously used remote secret (it is up to implementation how many previously used secrets are stored for this purpose).

After both SECRET and SECRET_RECEIVED commands were received, secrets exchange is considered finished and other commands are allowed to be used.

When new local secret is sent using SECRET command, both this newly generated and previous local secrets should be kept until SECRET_RECEIVED is received, and only then old secret should be removed. If SECRET was sent, but no SECRET_RECEIVED was received, both previous valid secret and unconfirmed should be allowed for next connection.

Partial post-compromise security and compromise detection

The fact that new secrets are exchanged during each connection enables following useful features:

  • if contact tries to contact us using outdated secret, it means that contact was likely compromised and someone have stolen its keys; by knowing when outdated secret and next after it were generated, user will know approximate time frame in which contact compromise happened
  • if after compromise at least one secure conversation took place, compromise detection will be possible AND future conversations with such contact will still be secure
  • if an attacker managed to initiate connection faster than contact, then one next valid connection it will still be clear that compromise happened and approximately when
  • if incoming connection from contact uses unknown secret, it means that this node was likely compromised AND conversation between an attacker and your contact already happened

These features require implementations to keep track of old secrets (both local and remote) and when they were generated, however, how much secrets are kept and for how long is up to implementation.

Nickname

Nickname is sent using command NICKNAME and contents as follows:

  • up to 65535 bytes nickname string (though, large nicknames are highly discouraged, as they will take a lot of time to send)

Nickname is typically sent after secrets exchange and after nickname change to currently connected contacts.

Text messages

Text messages are sent using TEXT_MESSAGE command and contents as follows:

  • 8 bytes - signed 64-bit float (double) in bid-endian format, date as Unix timestamp (in milliseconds) when message was sent
  • 8 bytes - signed 64-bit float (double) in bid-endian format, date as Unix timestamp (in milliseconds) when message was written
  • up to 65519 bytes - text message itself

Once text message is received, COMMAND_TEXT_MESSAGE_RECEIVED command is sent in response with contents as follows:

  • 8 bytes - signed 64-bit float (double) in bid-endian format, date as Unix timestamp (in milliseconds) when message was sent

NOTE: COMMAND_TEXT_MESSAGE_RECEIVED means that message was received, there is no indication that it was ever read.

Text messages SHOULD be treated as Markdown markup (GFM flavor), but:

  • with images being rendered as links (because otherwise they are loaded unconditionally and may lead to de-anonymization)
  • without raw HTML support, all raw HTML will be rendered as text

Since Markdown is a human-readable format, lighter clients may render it as simple text.

Incoming message MUST NOT be shown to user if its sent date is older than of last received message or if its written date is not newer than of last received message.

Acknowledgements

Detox Chat protocol is inspired by Tox.