Features
P2P
Encrypted Network

Introduction

A P2P Encrypted Network is a network of nodes that communicate with each other using a secure, encrypted protocol.
The network is designed to be decentralized, with no central authority or single point of failure.
It is also designed to be lightweight for low end devices, but also resistant to censorship and surveillance, with strong privacy and security guarantees.

Seed nodes are used to help nodes find each other and are connected by default when no peerlist available.

XELIS uses ChaCha20-Poly1305 AEAD cipher for symmetric encryption with key rotation happening for each 1 GB of data transferred.

All transferred data uses a custom serializer / deserializer made by hand to transform a struct representation in raw bytes directly.
This serialization is done using the fixed position of each field and their corresponding bit size.

Before sending a packet to the peer, the local node encrypts it completely to prevent network traffic analysis and to authenticate each transferred data.

All data is transferred using this encrypted protocol which allows for efficient reading, transferring, and serializing of the data.

For a full list of available packets, please see here.

Protocol

The protocol has a simple design with a packet system that allows transferring data between peers.

To create a connection with a potential peer, the party that initiated the connection must send its public key first. This key is required for the Diffie-Hellman key exchange to generate the shared secret for future communication.

The other party will wait on it and will send its own key after receiving the first one.

Once both parties have received the other's key, they can generate a shared secret which will be used as the temporary encryption key until the randomly generated key has been shared with the peer.

Once the key communication has been secured, they can now start the handshake and send / receive data encrypted.

The client that initiated the connection will send a handshake packet to the other party to be upgraded as a Peer, and the other party will respond with a handshake packet to confirm the upgrade.

In the handshake packet, a peer can inform others peers if it accepts that its IP is shared to extend peerlist of others and / or to be returned in RPC API.

To reduce overall bandwidth of network, nodes must NOT:

  • send twice a transaction during propagation time to the same peer.
  • send twice a block during propagation time to the same peer.

For block and transaction propagation, the local node keeps a cache of the last N elements sent or received from a peer to not send the same data twice during propagation.

Encryption

Currently, the ChaCha20-Poly1305 algorithm is used to encrypt / decrypt / authenticate packets.

For each connection with a peer, we maintains 2 distinct symmetric keys:

  • one for outgoing packets (generated by us)
  • one for incoming packets (generated by our peer)

This allows to easily upgrade / upgrade the key to a new one without blocking the other side.

The nonce for each packet encryption/decryption is 12 bytes, but we only changes the first 8 bytes by incrementing the a u64 nonce counter at each packet encryption / decryption.

This can be safely done as in TCP, packets are received in the same order as they were sent.

Also, the current implementation rotate the encryption key every 1 GB of data being sent / encrypted. The key rotation set the nonce counter to 0 and is sent through the Key Exchange packet.

Implementation

As a note, the connection for a new peer (took from the queue or a new incoming connection) is executed through a unique tokio task with the same allocated buffer for handshake. This prevents any DoS attack on creating multiple tasks and verifying connection.

When the peer is verified and valid, two tasks are created for it. One reads incoming packets and the other writes packets to the peer. Separating both directions into two tasks prevents incoming packets from blocking outgoing packets.