diff --git a/content/docs/rfcs/53/README.md b/content/docs/rfcs/53/README.md new file mode 100644 index 00000000..73b70ade --- /dev/null +++ b/content/docs/rfcs/53/README.md @@ -0,0 +1,251 @@ +--- +slug: 53 +title: 53/WAKU2-X3DH +name: X3DH usage for Waku payload encryption +status: draft +category: Standards Track +tags: waku-application +editor: Aaryamann Challani +contributors: +- Andrea Piana +- Pedro Pombeiro +- Corey Petty +- Oskar Thorén +- Dean Eigenmann +--- + +# Abstract + +This document describes a method that can be used to provide a secure channel between two peers, and thus provide confidentiality, integrity, authenticity and forward secrecy. +It is transport-agnostic and works over asynchronous networks. + +It builds on the [X3DH](https://signal.org/docs/specifications/x3dh/) and [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/) specifications, with some adaptations to operate in a decentralized environment. + +# Motivation + +Nodes on a network may want to communicate with each other in a secure manner, without other nodes network being able to read their messages. + +# Specification + +## Definitions + +- **Perfect Forward Secrecy** is a feature of specific key-agreement protocols which provide assurances that session keys will not be compromised even if the private keys of the participants are compromised. +Specifically, past messages cannot be decrypted by a third-party who manages to get a hold of a private key. + +- **Secret channel** describes a communication channel where a Double Ratchet algorithm is in use. + + +## Design Requirements + +- **Confidentiality**: The adversary should not be able to learn what data is being exchanged between two Status clients. +- **Authenticity**: The adversary should not be able to cause either endpoint to accept data from any third party as though it came from the other endpoint. +- **Forward Secrecy**: The adversary should not be able to learn what data was exchanged between two clients if, at some later time, the adversary compromises one or both of the endpoints. +- **Integrity**: The adversary should not be able to cause either endpoint to accept data that has been tampered with. + +All of these properties are ensured by the use of [Signal's Double Ratchet](https://signal.org/docs/specifications/doubleratchet/) + +## Conventions + +Types used in this specification are defined using the [Protobuf](https://developers.google.com/protocol-buffers/) wire format. + +# Specification + +## End-to-End Encryption + +End-to-end encryption (E2EE) takes place between two clients. +The main cryptographic protocol is a Double Ratchet protocol, which is derived from the [Off-the-Record protocol](https://otr.cypherpunks.ca/Protocol-v3-4.1.1.html), using a different ratchet. +[The Waku v2 protocol](/spec/10/) subsequently encrypts the message payload, using symmetric key encryption. +Furthermore, the concept of prekeys (through the use of [X3DH](https://signal.org/docs/specifications/x3dh/)) is used to allow the protocol to operate in an asynchronous environment. +It is not necessary for two parties to be online at the same time to initiate an encrypted conversation. + +## Cryptographic Protocols + +This protocol uses the following cryptographic primitives: +- X3DH + - Elliptic curve Diffie-Hellman key exchange (secp256k1) + - KECCAK-256 + - ECDSA + - ECIES +- Double Ratchet + - HMAC-SHA-256 as MAC + - Elliptic curve Diffie-Hellman key exchange (Curve25519) + - AES-256-CTR with HMAC-SHA-256 and IV derived alongside an encryption key + + The node achieves key derivation using [HKDF](https://www.rfc-editor.org/rfc/rfc5869). + +## Pre-keys + +Every client SHOULD initially generate some key material which is stored locally: +- Identity keypair based on secp256k1 - `IK` +- A signed prekey based on secp256k1 - `SPK` +- A prekey signature - `Sig(IK, Encode(SPK))` + +More details can be found in the `X3DH Prekey bundle creation` section of [2/ACCOUNT](https://specs.status.im/spec/2#x3dh-prekey-bundles). + +Prekey bundles MAY be extracted from any peer's messages, or found via searching for their specific topic, `{IK}-contact-code`. + +The following methods can be used to retrieve prekey bundles from a peer's messages: +- contact codes; +- public and one-to-one chats; +- QR codes; +- ENS record; +- Decentralized permanent storage (e.g. Swarm, IPFS). +- Waku + +Waku SHOULD be used for retrieving prekey bundles. + +Since bundles stored in QR codes or ENS records cannot be updated to delete already used keys, the bundle MAY be rotated every 24 hours, and distributed via Waku. + +## Flow + +The key exchange can be summarized as follows: + +1. Initial key exchange: Two parties, Alice and Bob, exchange their prekey bundles, and derive a shared secret. + +2. Double Ratchet: The two parties use the shared secret to derive a new encryption key for each message they send. + +3. Chain key update: The two parties update their chain keys. The chain key is used to derive new encryption keys for future messages. + +4. Message key derivation: The two parties derive a new message key from their chain key, and use it to encrypt a message. + +### 1. Initial key exchange flow (X3DH) + +[Section 3 of the X3DH protocol](https://signal.org/docs/specifications/x3dh/#sending-the-initial-message) describes the initial key exchange flow, with some additional context: +- The peers' identity keys `IK_A` and `IK_B` correspond to their public keys; +- Since it is not possible to guarantee that a prekey will be used only once in a decentralized world, the one-time prekey `OPK_B` is not used in this scenario; +- Nodes SHOULD not send Bundles to a centralized server, but instead provide them in a decentralized way as described in the [Pre-keys section](#pre-keys). + +Alice retrieves Bob's prekey bundle, however it is not specific to Alice. It contains: + +([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L12)) + +**Wire format:** + +``` protobuf +// X3DH prekey bundle +message Bundle { + // Identity key 'IK_B' + bytes identity = 1; + // Signed prekey 'SPK_B' for each device, indexed by 'installation-id' + map signed_pre_keys = 2; + // Prekey signature 'Sig(IK_B, Encode(SPK_B))' + bytes signature = 4; + // When the bundle was created locally + int64 timestamp = 5; +} +``` + +([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L5)) + +``` protobuf +message SignedPreKey { + bytes signed_pre_key = 1; + uint32 version = 2; +} +``` + +The `signature` is generated by sorting `installation-id` in lexicographical order, and concatenating the `signed-pre-key` and `version`: + +`installation-id-1signed-pre-key1version1installation-id2signed-pre-key2-version-2` + +### 2. Double Ratchet + +Having established the initial shared secret `SK` through X3DH, it SHOULD be used to seed a Double Ratchet exchange between Alice and Bob. + +Refer to the [Double Ratchet spec](https://signal.org/docs/specifications/doubleratchet/) for more details. + +The initial message sent by Alice to Bob is sent as a top-level `ProtocolMessage` ([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L65)) containing a map of `DirectMessageProtocol` indexed by `installation-id` ([reference wire format](https://github.com/status-im/status-go/blob/1ac9dd974415c3f6dee95145b6644aeadf02f02c/services/shhext/chat/encryption.proto#L56)): + +``` protobuf +message ProtocolMessage { + // The installation id of the sender + string installation_id = 2; + // A sequence of bundles + repeated Bundle bundles = 3; + // One to one message, encrypted, indexed by installation_id + map direct_message = 101; + // Public message, not encrypted + bytes public_message = 102; +} +``` + +``` protobuf +message EncryptedMessageProtocol { + X3DHHeader X3DH_header = 1; + DRHeader DR_header = 2; + DHHeader DH_header = 101; + // Encrypted payload + // if a bundle is available, contains payload encrypted with the Double Ratchet algorithm; + // otherwise, payload encrypted with output key of DH exchange (no Perfect Forward Secrecy). + bytes payload = 3; +} +``` +Where: +- `X3DH_header`: the `X3DHHeader` field in `DirectMessageProtocol` contains: + + ([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L47)) + ``` protobuf + message X3DHHeader { + // Alice's ephemeral key `EK_A` + bytes key = 1; + // Bob's bundle signed prekey + bytes id = 4; + } + ``` + +- `DR_header`: Double ratchet header ([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L31)). Used when Bob's public bundle is available: + ``` protobuf + message DRHeader { + // Alice's current ratchet public key (as mentioned in [DR spec section 2.2](https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet)) + bytes key = 1; + // number of the message in the sending chain + uint32 n = 2; + // length of the previous sending chain + uint32 pn = 3; + // Bob's bundle ID + bytes id = 4; + } + ``` + +- `DH_header`: Diffie-Hellman header (used when Bob's bundle is not available): + ([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L42)) + ``` protobuf + message DHHeader { + // Alice's compressed ephemeral public key. + bytes key = 1; + } + ``` + +### 3. Chain key update + +The chain key MUST be updated according to the `DR_Header` received in the `EncryptedMessageProtocol` message, described in [2.Double Ratchet](#2-double-ratchet). + +### 4. Message key derivation + +The message key MUST be derived from a single ratchet step in the symmetric-key ratchet as described in [Symmetric key ratchet](https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet) + +The message key MUST be used to encrypt the next message to be sent. + +# Security Considerations + +1. Inherits the security considerations of [X3DH](https://signal.org/docs/specifications/x3dh/#security-considerations) and [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/#security-considerations). + +2. Inherits the security considerations of the [Waku v2 protocol](/spec/10/). + +3. The protocol is designed to be used in a decentralized manner, however, it is possible to use a centralized server to serve prekey bundles. In this case, the server is trusted. + +# Privacy Considerations + +1. This protocol does not provide message unlinkability. It is possible to link messages signed by the same keypair. + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +# References + +1. [5/SECURE-TRANSPORT](https://specs.status.im/spec/5) +2. [10/WAKU2](/spec/10/) +3. [X3DH](https://signal.org/docs/specifications/x3dh/) +4. [HKDF](https://www.rfc-editor.org/rfc/rfc5869) +4. [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/) \ No newline at end of file diff --git a/content/docs/rfcs/54/README.md b/content/docs/rfcs/54/README.md new file mode 100644 index 00000000..09faf727 --- /dev/null +++ b/content/docs/rfcs/54/README.md @@ -0,0 +1,103 @@ +--- +slug: 54 +title: 54/WAKU2-X3DH-SESSIONS +name: Session management for Waku X3DH +status: draft +category: Standards Track +tags: waku-application +editor: Aaryamann Challani +contributors: +- Andrea Piana +- Pedro Pombeiro +- Corey Petty +- Oskar Thorén +- Dean Eigenmann +--- + +# Abstract + +This document specifies how to manage sessions based on an X3DH key exchange. +This includes how to establish new sessions, how to re-establish them, how to maintain them, and how to close them. + +[53/WAKU2-X3DH](/spec/53) specifies the Waku `X3DH` protocol for end-to-end encryption. +Once two peers complete an X3DH handshake, they SHOULD establish an X3DH session. + +# Session Establishment + +A node identifies a peer by their `installation-id` which MAY be interpreted as a device identifier. + +## Discovery of pre-key bundles + +The node's pre-key bundle SHOULD be broadcasted on a content topic derived from the node's public key. + +The derivation is further described in [10/WAKU-USAGE](https://specs.status.im/spec/10#contact-code-topic) + +## Initialization +A node initializes a new session once a successful X3DH exchange has taken place. +Subsequent messages will use the established session until re-keying is necessary. + +## Concurrent sessions + +If a node creates two sessions concurrently between two peers, the one with the symmetric key first in byte order SHOULD be used, this marks that the other has expired. + +## Re-keying + +On receiving a bundle from a given peer with a higher version, the old bundle SHOULD be marked as expired and a new session SHOULD be established on the next message sent. + +## Multi-device support + +Multi-device support is quite challenging as there is not a central place where information on which and how many devices (identified by their respective `installation-id`) a peer has, is stored. + +Furthermore, account recovery always needs to be taken into consideration, where a user wipes clean the whole device and the node loses all the information about any previous sessions. +Taking these considerations into account, the way the network propagates multi-device information using X3DH bundles, which will contain information about paired devices as well as information about the sending device. +This means that every time a new device is paired, the bundle needs to be updated and propagated with the new information, the user has the responsibility to make sure the pairing is successful. + +The method is loosely based on [Signal's Sesame Algorithm](https://signal.org/docs/specifications/sesame/). + +## Pairing + +A new `installation-id` MUST be generated on a per-device basis. +The device should be paired as soon as possible if other devices are present. + +If a bundle is received, which has the same `IK` as the keypair present on the device, the devices MAY be paired. +Once a user enables a new device, a new bundle MUST be generated which includes pairing information. + +The bundle MUST be propagated to contacts through the usual channels. + +Removal of paired devices is a manual step that needs to be applied on each device, and consist simply in disabling the device, at which point pairing information will not be propagated anymore. + +### Sending messages to a paired group + +When sending a message, the peer SHOULD send a message to other `installation-id` that they have seen. +The node caps the number of devices to `n`, ordered by last activity. +The node sends messages using pairwise encryption, including their own devices. + +Where `n` is the maximum number of devices that can be paired. + +## Account recovery + +Account recovery is the same as adding a new device, and it MUST be handled the same way. + +## Partitioned devices + +In some cases (i.e. account recovery when no other pairing device is available, device not paired), it is possible that a device will receive a message that is not targeted to its own `installation-id`. +In this case an empty message containing bundle information MUST be sent back, which will notify the receiving end not to include the device in any further communication. + +# Security Considerations + +1. Inherits all security considerations from [53/WAKU2-X3DH](/spec/53). + +# Recommendations + +1. The value of `n` SHOULD be configured by the app-protocol. + - The default value SHOULD be 3, since a larger number of devices will result in a larger bundle size, which may not be desirable in a peer-to-peer network. + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +# References + +1. [53/WAKU2-X3DH](/spec/53) +2. [Signal's Sesame Algorithm](https://signal.org/docs/specifications/sesame/) +3. [5/SECURE-TRANSPORT](https://specs.status.im/spec/5) \ No newline at end of file diff --git a/content/docs/rfcs/55/README.md b/content/docs/rfcs/55/README.md new file mode 100644 index 00000000..add824e9 --- /dev/null +++ b/content/docs/rfcs/55/README.md @@ -0,0 +1,75 @@ +--- +slug: 55 +title: 55/STATUS-1TO1-CHAT +name: Status 1-to-1 Chat +status: draft +category: Standards Track +tags: waku-application +editor: Aaryamann Challani +contributors: +- Andrea Piana +- Pedro Pombeiro +- Corey Petty +- Oskar Thorén +- Dean Eigenmann +--- + +# Abstract + +This specification describes how the Status 1-to-1 chat protocol is implemented on top of the Waku v2 protocol. +This protocol can be used to send messages to a single recipient. + +# Background + +This document describes how 2 peers communicate with each other to send messages in a 1-to-1 chat, with privacy and authenticity guarantees. + +# Specification + +## Overview + +This protocol MAY use any key-exchange mechanism previously discussed - + +1. [53/WAKU2-X3DH](/spec/53/) +2. [35/WAKU2-NOISE](/spec/35/) + +This protocol can provide end-to-end encryption to give peers a strong degree of privacy and security. +Public chat messages are publicly readable by anyone since there's no permission model for who is participating in a public chat. + +## Flow + +### Negotiation of a 1:1 chat + +There are two phases in the initial negotiation of a 1:1 chat: +1. **Identity verification** (e.g., face-to-face contact exchange through QR code, Identicon matching). +A QR code serves two purposes simultaneously - identity verification and initial key material retrieval; +1. **Asynchronous initial key exchange** + +For more information on account generation and trust establishment, see [2/ACCOUNT](https://specs.status.im/spec/2) + +### Post Negotiation + +After the peers have shared their public key material, a 1:1 chat can be established using the methods described in the key-exchange protocols mentioned above. + +### Session management + +The 1:1 chat is made robust by having sessions between peers. +It is handled by the key-exchange protocol used. For example, + +1. [53/WAKU2-X3DH](/spec/53/), the session management is described in [54/WAKU2-X3DH-SESSIONS](/spec/54/) + +2. [35/WAKU2-NOISE](/spec/35/), the session management is described in [37/WAKU2-NOISE-SESSIONS](/spec/37/) + +# Security Considerations + +1. Inherits the security considerations of the key-exchange mechanism used, e.g., [53/WAKU2-X3DH](/spec/53/) or [35/WAKU2-NOISE](/spec/35/) + +# Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +# References + +1. [2/ACCOUNT](https://specs.status.im/spec/2) +2. [53/WAKU2-X3DH](/spec/53/) +3. [35/WAKU2-NOISE](/spec/35/) +4. [10/WAKU2](/spec/10/) \ No newline at end of file diff --git a/content/menu/index.md b/content/menu/index.md index 6db60d71..b3822f3d 100644 --- a/content/menu/index.md +++ b/content/menu/index.md @@ -43,6 +43,9 @@ bookMenuLevels: 1 - [30/ADAPTIVE-NODES]({{< relref "/docs/rfcs/30/README.md" >}}) - [33/WAKU2-DISCV5]({{< relref "/docs/rfcs/33/README.md" >}}) - [36/WAKU2-BINDINGS-API]({{< relref "/docs/rfcs/36/README.md" >}}) + - [53/WAKU2-X3DH]({{< relref "/docs/rfcs/53/README.md" >}}) + - [54/WAKU2-X3DH-SESSIONS]({{< relref "/docs/rfcs/54/README.md" >}}) + - [55/STATUS-1TO1-CHAT]({{< relref "/docs/rfcs/55/README.md" >}}) - Stable - [2/MVDS]({{< relref "/docs/rfcs/2/README.md" >}}) - [6/WAKU1]({{< relref "/docs/rfcs/6/README.md" >}})