This document describes a protocol that defines packet exchange between nodes using underlying datagram protocol (e.g. UDP). Nodes participating in exchange are:


Packet consists of packet metadata (header) and EllipticCP message. EllipticCP messages are encrypted and authenticated with AEAD algorithm instantiated with ChaCha20 and Poly1305 (RFC 8439). AEAD algorithm uses shared secret obtained from Curve25519 Diffie-Hellman function.

Both server and client have long-term key pairs. Server generates its short-term key pair on startup and changes it periodically (every hour or so). Client must obtain server's long term public key separately. Before opening connection, client generates key pair which is client's short-term key for this connection. During life time of a connection, both client and server can change short-term key at any time. After short-term key is changed, previous key remains valid until next change of short-term key. Client can not change its short-term key more than once per hour.

Short-term keys have "parity" property. Initial key (server's first key upon startup or client's key generated before opening a connection) is defined to be of even parity. After each key change, its "parity" is also changed (e.g. if old one was 'even', new one is 'odd').

Packet format

Client -> server Server -> client
Init request packet:
(I,C',0,N,Box[INIT_REQ message](C'->S))
Init reply packet:
(I,N,Box[INIT_REP message](S->C'))
Open request packet:
(I,C',K,N,Box[OPEN_REQ message](C'->S'))
Open reply packet:
(I,C',N,Box[OPEN_REP message](S'->C'))
Message packet:
Message packet:
... ...
Key exchange packet:
(I,C',N,Box[KEYX_REQ message](C'->S'))
Key exchange packet:
(I,C',N,Box[KEYX_REP message](S'->C'))
... ...


Key identifier (KEYID) contains information about keys used to encrypt and authenticate cryptographic box:

Client and server initialize nonce for new connection to randomly generated 64-bit number before sending init request/open reply packet. Nonces are increased by precisely 1 for each subsequent packet. Nonce for init reply packet is initialized to randomly generated 64-bit number on startup and is increased by precisely 1 for every subsequent init reply packet. 96-bit AEAD nonce is constructed in the following way:

Upon opening connection, both client and server can send any number of message packets.

Client periodically sends key exchange packet to check if server has changed its short-term key and to keep connection alive. If client generates new short-term key, it must send key exchange packet to inform server about new key. Server will encrypt subsequent packets to client with new key only after it receives packet from client which was encrypted with that new key. Client can use new key immediately after receiving key exchange response. If client does not receive response to key exchange after some number of tries, it should consider connection broken.

Server can purge connections after some time of inactivity.

Messages defined by EllipticCP

Message format is (MT,MD[,MT,MD,...]) where:

Init request message

Init reply message

Open request message

K — cookie (present in packet header) is constructed by concatenating nonce and authentication tag from previously received init reply packet/message. Server may reject cookies with nonces that are too distant from current init reply nonce counter, thus preventing replay attack using captured open request packets. Purpose of vouch subpacket is to authenticate client towards the server (optional).

Open reply message

Key exchange request message

Key exchange reply message