mirror of https://github.com/vacp2p/rfc.git
622 lines
35 KiB
HTML
622 lines
35 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" dir="ltr">
|
|
|
|
<head>
|
|
<meta name="generator" content="Hugo 0.106.0">
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="description" content="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 and Double Ratchet 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.">
|
|
<meta name="theme-color" content="#FFFFFF"><meta property="og:title" content="53/WAKU2-X3DH" />
|
|
<meta property="og:description" content="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 and Double Ratchet 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." />
|
|
<meta property="og:type" content="article" />
|
|
<meta property="og:url" content="https://rfc.vac.dev/spec/53/" /><meta property="article:section" content="docs" />
|
|
|
|
|
|
|
|
<title>53/WAKU2-X3DH | Vac RFC</title>
|
|
<link rel="manifest" href="/manifest.json">
|
|
<link rel="icon" href="/favicon.png" type="image/x-icon">
|
|
<link rel="stylesheet" href="/book.min.e935e20bd0d469378cb482f0958edf258c731a4f895dccd55799c6fbc8043f23.css" integrity="sha256-6TXiC9DUaTeMtILwlY7fJYxzGk+JXczVV5nG+8gEPyM=">
|
|
<script defer src="/en.search.min.07668e91447d4b5e23bc427fda23768cc7456c7564bfc4b25421bc181027a261.js" integrity="sha256-B2aOkUR9S14jvEJ/2iN2jMdFbHVkv8SyVCG8GBAnomE="></script>
|
|
<!--
|
|
Made with Book Theme
|
|
https://github.com/alex-shpak/hugo-book
|
|
-->
|
|
|
|
|
|
</head>
|
|
|
|
<body dir="ltr">
|
|
<input type="checkbox" class="hidden toggle" id="menu-control" />
|
|
<input type="checkbox" class="hidden toggle" id="toc-control" />
|
|
<main class="container flex">
|
|
<aside class="book-menu">
|
|
<div class="book-menu-content">
|
|
|
|
<nav>
|
|
<h2 class="book-brand">
|
|
<a href="/"><span>Vac RFC</span>
|
|
</a>
|
|
</h2>
|
|
|
|
|
|
<div class="book-search">
|
|
<input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
|
|
<div class="book-search-spinner hidden"></div>
|
|
<ul id="book-search-results"></ul>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
<li>Raw
|
|
<ul>
|
|
<li><a href="/spec/20/">20/TOY-ETH-PM</a></li>
|
|
<li><a href="/spec/24/">24/STATUS-CURATION</a></li>
|
|
<li><a href="/spec/28/">28/STATUS-FEATURING</a></li>
|
|
<li><a href="/spec/31/">31/WAKU2-ENR</a></li>
|
|
<li><a href="/spec/32/">32/RLN-V1</a></li>
|
|
<li><a href="/spec/34/">34/WAKU2-PEER-EXCHANGE</a></li>
|
|
<li><a href="/spec/35/">35/WAKU2-NOISE</a></li>
|
|
<li><a href="/spec/37/">37/WAKU2-NOISE-SESSIONS</a></li>
|
|
<li><a href="/spec/38/">38/CONSENSUS-CLARO</a></li>
|
|
<li><a href="/spec/43/">43/WAKU2-NOISE-PAIRING</a></li>
|
|
<li><a href="/spec/44/">44/WAKU2-DANDELION</a></li>
|
|
<li><a href="/spec/45/">45/WAKU2-ADVERSARIAL-MODELS</a></li>
|
|
<li><a href="/spec/46/">46/GOSSIPSUB-TOR-PUSH</a></li>
|
|
<li><a href="/spec/47/">47/WAKU2-TOR-PUSH</a></li>
|
|
<li><a href="/spec/48/">48/RLN-INTEREP-SPEC</a></li>
|
|
<li><a href="/spec/51/">51/WAKU2-RELAY-SHARDING</a></li>
|
|
<li><a href="/spec/52/">52/WAKU2-RELAY-STATIC-SHARD-ALLOC</a></li>
|
|
<li><a href="/spec/57/">57/STATUS-Simple-Scaling</a></li>
|
|
<li><a href="/spec/58/">58/RLN-V2</a></li>
|
|
<li><a href="/spec/61/">61/STATUS-Community-History-Archives</a></li>
|
|
<li><a href="/spec/63/">63/STATUS-Keycard-Usage</a></li>
|
|
<li><a href="/spec/64/">64/WAKU2-NETWORK</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>Draft
|
|
<ul>
|
|
<li><a href="/spec/1/">1/COSS</a></li>
|
|
<li><a href="/spec/3/">3/REMOTE-LOG</a></li>
|
|
<li><a href="/spec/4/">4/MVDS-META</a></li>
|
|
<li><a href="/spec/10/">10/WAKU2</a></li>
|
|
<li><a href="/spec/12/">12/WAKU2-FILTER</a></li>
|
|
<li><a href="/spec/13/">13/WAKU2-STORE</a></li>
|
|
<li><a href="/spec/14/">14/WAKU2-MESSAGE</a></li>
|
|
<li><a href="/spec/15/">15/WAKU2-BRIDGE</a></li>
|
|
<li><a href="/spec/16/">16/WAKU2-RPC</a></li>
|
|
<li><a href="/spec/17/">17/WAKU2-RLN-RELAY</a></li>
|
|
<li><a href="/spec/18/">18/WAKU2-SWAP</a></li>
|
|
<li><a href="/spec/19/">19/WAKU2-LIGHTPUSH</a></li>
|
|
<li><a href="/spec/21/">21/WAKU2-FTSTORE</a></li>
|
|
<li><a href="/spec/22/">22/TOY-CHAT</a></li>
|
|
<li><a href="/spec/23/">23/WAKU2-TOPICS</a></li>
|
|
<li><a href="/spec/26/">26/WAKU2-PAYLOAD</a></li>
|
|
<li><a href="/spec/27/">27/WAKU2-PEERS</a></li>
|
|
<li><a href="/spec/29/">29/WAKU2-CONFIG</a></li>
|
|
<li><a href="/spec/30/">30/ADAPTIVE-NODES</a></li>
|
|
<li><a href="/spec/33/">33/WAKU2-DISCV5</a></li>
|
|
<li><a href="/spec/36/">36/WAKU2-BINDINGS-API</a></li>
|
|
<li><a href="/spec/53/"class=active>53/WAKU2-X3DH</a></li>
|
|
<li><a href="/spec/54/">54/WAKU2-X3DH-SESSIONS</a></li>
|
|
<li><a href="/spec/55/">55/STATUS-1TO1-CHAT</a></li>
|
|
<li><a href="/spec/56/">56/STATUS-COMMUNITIES</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>Stable
|
|
<ul>
|
|
<li><a href="/spec/2/">2/MVDS</a></li>
|
|
<li><a href="/spec/6/">6/WAKU1</a></li>
|
|
<li><a href="/spec/7/">7/WAKU-DATA</a></li>
|
|
<li><a href="/spec/8/">8/WAKU-MAIL</a></li>
|
|
<li><a href="/spec/9/">9/WAKU-RPC</a></li>
|
|
<li><a href="/spec/11/">11/WAKU2-RELAY</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>Deprecated
|
|
<ul>
|
|
<li><a href="/spec/5/">5/WAKU0</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>Retired</li>
|
|
</ul>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
|
|
|
|
<script>(function(){var e=document.querySelector("aside.book-menu nav");addEventListener("beforeunload",function(){localStorage.setItem("menu.scrollTop",e.scrollTop)}),e.scrollTop=localStorage.getItem("menu.scrollTop")})()</script>
|
|
|
|
|
|
|
|
</div>
|
|
</aside>
|
|
|
|
<div class="book-page">
|
|
<header class="book-header">
|
|
|
|
<div class="flex align-center justify-between">
|
|
<label for="menu-control">
|
|
<img src="/svg/menu.svg" class="book-icon" alt="Menu" />
|
|
</label>
|
|
|
|
<strong>53/WAKU2-X3DH</strong>
|
|
|
|
<label for="toc-control">
|
|
|
|
<img src="/svg/toc.svg" class="book-icon" alt="Table of Contents" />
|
|
|
|
</label>
|
|
</div>
|
|
|
|
|
|
|
|
<aside class="hidden clearfix">
|
|
|
|
|
|
<nav id="TableOfContents">
|
|
<ul>
|
|
<li><a href="#abstract">Abstract</a></li>
|
|
<li><a href="#motivation">Motivation</a></li>
|
|
<li><a href="#specification">Specification</a>
|
|
<ul>
|
|
<li><a href="#definitions">Definitions</a></li>
|
|
<li><a href="#design-requirements">Design Requirements</a></li>
|
|
<li><a href="#conventions">Conventions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#specification-1">Specification</a>
|
|
<ul>
|
|
<li><a href="#end-to-end-encryption">End-to-End Encryption</a></li>
|
|
<li><a href="#cryptographic-protocols">Cryptographic Protocols</a></li>
|
|
<li><a href="#pre-keys">Pre-keys</a></li>
|
|
<li><a href="#flow">Flow</a>
|
|
<ul>
|
|
<li><a href="#1-initial-key-exchange-flow-x3dh">1. Initial key exchange flow (X3DH)</a></li>
|
|
<li><a href="#2-double-ratchet">2. Double Ratchet</a></li>
|
|
<li><a href="#3-chain-key-update">3. Chain key update</a></li>
|
|
<li><a href="#4-message-key-derivation">4. Message key derivation</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#security-considerations">Security Considerations</a></li>
|
|
<li><a href="#privacy-considerations">Privacy Considerations</a></li>
|
|
<li><a href="#copyright">Copyright</a></li>
|
|
<li><a href="#references">References</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
|
|
|
|
</aside>
|
|
|
|
|
|
</header>
|
|
|
|
|
|
|
|
<article class="markdown">
|
|
<h1 id="53waku2-x3dh">
|
|
53/WAKU2-X3DH
|
|
<a class="anchor" href="#53waku2-x3dh">#</a>
|
|
</h1>
|
|
|
|
|
|
<h1 id="x3dh-usage-for-waku-payload-encryption">
|
|
X3DH usage for Waku payload encryption
|
|
<a class="anchor" href="#x3dh-usage-for-waku-payload-encryption">#</a>
|
|
</h1>
|
|
|
|
|
|
|
|
|
|
|
|
<img src="https://img.shields.io/badge/status-draft-blue?style=flat-square" />
|
|
|
|
|
|
|
|
|
|
|
|
<ul>
|
|
<li>Status: draft</li>
|
|
<li>Editor: Aaryamann Challani <a href="mailto:aaryamann@status.im">aaryamann@status.im</a></li>
|
|
|
|
<li>Contributors:
|
|
|
|
|
|
Andrea Piana <a href="mailto:andreap@status.im">andreap@status.im</a>
|
|
|
|
,
|
|
Pedro Pombeiro <a href="mailto:pedro@status.im">pedro@status.im</a>
|
|
|
|
,
|
|
Corey Petty <a href="mailto:corey@status.im">corey@status.im</a>
|
|
|
|
,
|
|
Oskar Thorén <a href="mailto:oskar@status.im">oskar@status.im</a>
|
|
|
|
,
|
|
Dean Eigenmann <a href="mailto:dean@status.im">dean@status.im</a>
|
|
|
|
</li>
|
|
|
|
</ul><h1 id="abstract">
|
|
Abstract
|
|
<a class="anchor" href="#abstract">#</a>
|
|
</h1>
|
|
<p>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.</p>
|
|
<p>It builds on the <a href="https://signal.org/docs/specifications/x3dh/">X3DH</a> and <a href="https://signal.org/docs/specifications/doubleratchet/">Double Ratchet</a> specifications, with some adaptations to operate in a decentralized environment.</p>
|
|
<h1 id="motivation">
|
|
Motivation
|
|
<a class="anchor" href="#motivation">#</a>
|
|
</h1>
|
|
<p>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.</p>
|
|
<h1 id="specification">
|
|
Specification
|
|
<a class="anchor" href="#specification">#</a>
|
|
</h1>
|
|
<h2 id="definitions">
|
|
Definitions
|
|
<a class="anchor" href="#definitions">#</a>
|
|
</h2>
|
|
<ul>
|
|
<li>
|
|
<p><strong>Perfect Forward Secrecy</strong> 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.</p>
|
|
</li>
|
|
<li>
|
|
<p><strong>Secret channel</strong> describes a communication channel where a Double Ratchet algorithm is in use.</p>
|
|
</li>
|
|
</ul>
|
|
<h2 id="design-requirements">
|
|
Design Requirements
|
|
<a class="anchor" href="#design-requirements">#</a>
|
|
</h2>
|
|
<ul>
|
|
<li><strong>Confidentiality</strong>: The adversary should not be able to learn what data is being exchanged between two Status clients.</li>
|
|
<li><strong>Authenticity</strong>: 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.</li>
|
|
<li><strong>Forward Secrecy</strong>: 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.</li>
|
|
<li><strong>Integrity</strong>: The adversary should not be able to cause either endpoint to accept data that has been tampered with.</li>
|
|
</ul>
|
|
<p>All of these properties are ensured by the use of <a href="https://signal.org/docs/specifications/doubleratchet/">Signal’s Double Ratchet</a></p>
|
|
<h2 id="conventions">
|
|
Conventions
|
|
<a class="anchor" href="#conventions">#</a>
|
|
</h2>
|
|
<p>Types used in this specification are defined using the <a href="https://developers.google.com/protocol-buffers/">Protobuf</a> wire format.</p>
|
|
<h1 id="specification-1">
|
|
Specification
|
|
<a class="anchor" href="#specification-1">#</a>
|
|
</h1>
|
|
<h2 id="end-to-end-encryption">
|
|
End-to-End Encryption
|
|
<a class="anchor" href="#end-to-end-encryption">#</a>
|
|
</h2>
|
|
<p>End-to-end encryption (E2EE) takes place between two clients.
|
|
The main cryptographic protocol is a Double Ratchet protocol, which is derived from the <a href="https://otr.cypherpunks.ca/Protocol-v3-4.1.1.html">Off-the-Record protocol</a>, using a different ratchet.
|
|
<a href="/spec/10/">The Waku v2 protocol</a> subsequently encrypts the message payload, using symmetric key encryption.
|
|
Furthermore, the concept of prekeys (through the use of <a href="https://signal.org/docs/specifications/x3dh/">X3DH</a>) 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.</p>
|
|
<h2 id="cryptographic-protocols">
|
|
Cryptographic Protocols
|
|
<a class="anchor" href="#cryptographic-protocols">#</a>
|
|
</h2>
|
|
<p>This protocol uses the following cryptographic primitives:</p>
|
|
<ul>
|
|
<li>
|
|
<p>X3DH</p>
|
|
<ul>
|
|
<li>Elliptic curve Diffie-Hellman key exchange (secp256k1)</li>
|
|
<li>KECCAK-256</li>
|
|
<li>ECDSA</li>
|
|
<li>ECIES</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<p>Double Ratchet</p>
|
|
<ul>
|
|
<li>HMAC-SHA-256 as MAC</li>
|
|
<li>Elliptic curve Diffie-Hellman key exchange (Curve25519)</li>
|
|
<li>AES-256-CTR with HMAC-SHA-256 and IV derived alongside an encryption key</li>
|
|
</ul>
|
|
<p>The node achieves key derivation using <a href="https://www.rfc-editor.org/rfc/rfc5869">HKDF</a>.</p>
|
|
</li>
|
|
</ul>
|
|
<h2 id="pre-keys">
|
|
Pre-keys
|
|
<a class="anchor" href="#pre-keys">#</a>
|
|
</h2>
|
|
<p>Every client SHOULD initially generate some key material which is stored locally:</p>
|
|
<ul>
|
|
<li>Identity keypair based on secp256k1 - <code>IK</code></li>
|
|
<li>A signed prekey based on secp256k1 - <code>SPK</code></li>
|
|
<li>A prekey signature - <code>Sig(IK, Encode(SPK))</code></li>
|
|
</ul>
|
|
<p>More details can be found in the <code>X3DH Prekey bundle creation</code> section of <a href="https://specs.status.im/spec/2#x3dh-prekey-bundles">2/ACCOUNT</a>.</p>
|
|
<p>Prekey bundles MAY be extracted from any peer’s messages, or found via searching for their specific topic, <code>{IK}-contact-code</code>.</p>
|
|
<p>The following methods can be used to retrieve prekey bundles from a peer’s messages:</p>
|
|
<ul>
|
|
<li>contact codes;</li>
|
|
<li>public and one-to-one chats;</li>
|
|
<li>QR codes;</li>
|
|
<li>ENS record;</li>
|
|
<li>Decentralized permanent storage (e.g. Swarm, IPFS).</li>
|
|
<li>Waku</li>
|
|
</ul>
|
|
<p>Waku SHOULD be used for retrieving prekey bundles.</p>
|
|
<p>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.</p>
|
|
<h2 id="flow">
|
|
Flow
|
|
<a class="anchor" href="#flow">#</a>
|
|
</h2>
|
|
<p>The key exchange can be summarized as follows:</p>
|
|
<ol>
|
|
<li>
|
|
<p>Initial key exchange: Two parties, Alice and Bob, exchange their prekey bundles, and derive a shared secret.</p>
|
|
</li>
|
|
<li>
|
|
<p>Double Ratchet: The two parties use the shared secret to derive a new encryption key for each message they send.</p>
|
|
</li>
|
|
<li>
|
|
<p>Chain key update: The two parties update their chain keys. The chain key is used to derive new encryption keys for future messages.</p>
|
|
</li>
|
|
<li>
|
|
<p>Message key derivation: The two parties derive a new message key from their chain key, and use it to encrypt a message.</p>
|
|
</li>
|
|
</ol>
|
|
<h3 id="1-initial-key-exchange-flow-x3dh">
|
|
1. Initial key exchange flow (X3DH)
|
|
<a class="anchor" href="#1-initial-key-exchange-flow-x3dh">#</a>
|
|
</h3>
|
|
<p><a href="https://signal.org/docs/specifications/x3dh/#sending-the-initial-message">Section 3 of the X3DH protocol</a> describes the initial key exchange flow, with some additional context:</p>
|
|
<ul>
|
|
<li>The peers’ identity keys <code>IK_A</code> and <code>IK_B</code> correspond to their public keys;</li>
|
|
<li>Since it is not possible to guarantee that a prekey will be used only once in a decentralized world, the one-time prekey <code>OPK_B</code> is not used in this scenario;</li>
|
|
<li>Nodes SHOULD not send Bundles to a centralized server, but instead provide them in a decentralized way as described in the <a href="#pre-keys">Pre-keys section</a>.</li>
|
|
</ul>
|
|
<p>Alice retrieves Bob’s prekey bundle, however it is not specific to Alice. It contains:</p>
|
|
<p>(<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L12">reference wire format</a>)</p>
|
|
<p><strong>Wire format:</strong></p>
|
|
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#75715e">// X3DH prekey bundle
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">Bundle</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Identity key 'IK_B'
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> identity <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Signed prekey 'SPK_B' for each device, indexed by 'installation-id'
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> map<<span style="color:#66d9ef">string</span>,SignedPreKey> signed_pre_keys <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Prekey signature 'Sig(IK_B, Encode(SPK_B))'
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> signature <span style="color:#f92672">=</span> <span style="color:#ae81ff">4</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// When the bundle was created locally
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">int64</span> timestamp <span style="color:#f92672">=</span> <span style="color:#ae81ff">5</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div><p>(<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L5">reference wire format</a>)</p>
|
|
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">SignedPreKey</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#66d9ef">bytes</span> signed_pre_key <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#66d9ef">uint32</span> version <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div><p>The <code>signature</code> is generated by sorting <code>installation-id</code> in lexicographical order, and concatenating the <code>signed-pre-key</code> and <code>version</code>:</p>
|
|
<p><code>installation-id-1signed-pre-key1version1installation-id2signed-pre-key2-version-2</code></p>
|
|
<h3 id="2-double-ratchet">
|
|
2. Double Ratchet
|
|
<a class="anchor" href="#2-double-ratchet">#</a>
|
|
</h3>
|
|
<p>Having established the initial shared secret <code>SK</code> through X3DH, it SHOULD be used to seed a Double Ratchet exchange between Alice and Bob.</p>
|
|
<p>Refer to the <a href="https://signal.org/docs/specifications/doubleratchet/">Double Ratchet spec</a> for more details.</p>
|
|
<p>The initial message sent by Alice to Bob is sent as a top-level <code>ProtocolMessage</code> (<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L65">reference wire format</a>) containing a map of <code>DirectMessageProtocol</code> indexed by <code>installation-id</code> (<a href="https://github.com/status-im/status-go/blob/1ac9dd974415c3f6dee95145b6644aeadf02f02c/services/shhext/chat/encryption.proto#L56">reference wire format</a>):</p>
|
|
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">ProtocolMessage</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// The installation id of the sender
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">string</span> installation_id <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// A sequence of bundles
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">repeated</span> Bundle bundles <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// One to one message, encrypted, indexed by installation_id
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> map<<span style="color:#66d9ef">string</span>,DirectMessageProtocol> direct_message <span style="color:#f92672">=</span> <span style="color:#ae81ff">101</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Public message, not encrypted
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> public_message <span style="color:#f92672">=</span> <span style="color:#ae81ff">102</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">EncryptedMessageProtocol</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> X3DHHeader X3DH_header <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> DRHeader DR_header <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>; <span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> DHHeader DH_header <span style="color:#f92672">=</span> <span style="color:#ae81ff">101</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Encrypted payload
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#75715e">// if a bundle is available, contains payload encrypted with the Double Ratchet algorithm;
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#75715e">// otherwise, payload encrypted with output key of DH exchange (no Perfect Forward Secrecy).
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> payload <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div><p>Where:</p>
|
|
<ul>
|
|
<li>
|
|
<p><code>X3DH_header</code>: the <code>X3DHHeader</code> field in <code>DirectMessageProtocol</code> contains:</p>
|
|
<p>(<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L47">reference wire format</a>)</p>
|
|
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">X3DHHeader</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Alice's ephemeral key `EK_A`
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> key <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Bob's bundle signed prekey
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> id <span style="color:#f92672">=</span> <span style="color:#ae81ff">4</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div></li>
|
|
<li>
|
|
<p><code>DR_header</code>: Double ratchet header (<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L31">reference wire format</a>). Used when Bob’s public bundle is available:</p>
|
|
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">DRHeader</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Alice's current ratchet public key (as mentioned in [DR spec section 2.2](https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet))
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> key <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// number of the message in the sending chain
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">uint32</span> n <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// length of the previous sending chain
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">uint32</span> pn <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Bob's bundle ID
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> id <span style="color:#f92672">=</span> <span style="color:#ae81ff">4</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div></li>
|
|
<li>
|
|
<p><code>DH_header</code>: Diffie-Hellman header (used when Bob’s bundle is not available):
|
|
(<a href="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L42">reference wire format</a>)</p>
|
|
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-protobuf" data-lang="protobuf"><span style="display:flex;"><span><span style="color:#66d9ef">message</span> <span style="color:#a6e22e">DHHeader</span> {<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span> <span style="color:#75715e">// Alice's compressed ephemeral public key.
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#66d9ef">bytes</span> key <span style="color:#f92672">=</span> <span style="color:#ae81ff">1</span>;<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010"></span>}<span style="color:#960050;background-color:#1e0010">
|
|
</span></span></span></code></pre></div></li>
|
|
</ul>
|
|
<h3 id="3-chain-key-update">
|
|
3. Chain key update
|
|
<a class="anchor" href="#3-chain-key-update">#</a>
|
|
</h3>
|
|
<p>The chain key MUST be updated according to the <code>DR_Header</code> received in the <code>EncryptedMessageProtocol</code> message, described in <a href="#2-double-ratchet">2.Double Ratchet</a>.</p>
|
|
<h3 id="4-message-key-derivation">
|
|
4. Message key derivation
|
|
<a class="anchor" href="#4-message-key-derivation">#</a>
|
|
</h3>
|
|
<p>The message key MUST be derived from a single ratchet step in the symmetric-key ratchet as described in <a href="https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet">Symmetric key ratchet</a></p>
|
|
<p>The message key MUST be used to encrypt the next message to be sent.</p>
|
|
<h1 id="security-considerations">
|
|
Security Considerations
|
|
<a class="anchor" href="#security-considerations">#</a>
|
|
</h1>
|
|
<ol>
|
|
<li>
|
|
<p>Inherits the security considerations of <a href="https://signal.org/docs/specifications/x3dh/#security-considerations">X3DH</a> and <a href="https://signal.org/docs/specifications/doubleratchet/#security-considerations">Double Ratchet</a>.</p>
|
|
</li>
|
|
<li>
|
|
<p>Inherits the security considerations of the <a href="/spec/10/">Waku v2 protocol</a>.</p>
|
|
</li>
|
|
<li>
|
|
<p>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.</p>
|
|
</li>
|
|
</ol>
|
|
<h1 id="privacy-considerations">
|
|
Privacy Considerations
|
|
<a class="anchor" href="#privacy-considerations">#</a>
|
|
</h1>
|
|
<ol>
|
|
<li>This protocol does not provide message unlinkability. It is possible to link messages signed by the same keypair.</li>
|
|
</ol>
|
|
<h1 id="copyright">
|
|
Copyright
|
|
<a class="anchor" href="#copyright">#</a>
|
|
</h1>
|
|
<p>Copyright and related rights waived via <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>.</p>
|
|
<h1 id="references">
|
|
References
|
|
<a class="anchor" href="#references">#</a>
|
|
</h1>
|
|
<ol>
|
|
<li><a href="https://specs.status.im/spec/5">5/SECURE-TRANSPORT</a></li>
|
|
<li><a href="/spec/10/">10/WAKU2</a></li>
|
|
<li><a href="https://signal.org/docs/specifications/x3dh/">X3DH</a></li>
|
|
<li><a href="https://www.rfc-editor.org/rfc/rfc5869">HKDF</a></li>
|
|
<li><a href="https://signal.org/docs/specifications/doubleratchet/">Double Ratchet</a></li>
|
|
</ol>
|
|
</article>
|
|
|
|
|
|
|
|
<footer class="book-footer">
|
|
|
|
<div class="flex flex-wrap justify-between">
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
<div class="book-comments">
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<label for="menu-control" class="hidden book-menu-overlay"></label>
|
|
</div>
|
|
|
|
|
|
<aside class="book-toc">
|
|
<div class="book-toc-content">
|
|
|
|
|
|
<nav id="TableOfContents">
|
|
<ul>
|
|
<li><a href="#abstract">Abstract</a></li>
|
|
<li><a href="#motivation">Motivation</a></li>
|
|
<li><a href="#specification">Specification</a>
|
|
<ul>
|
|
<li><a href="#definitions">Definitions</a></li>
|
|
<li><a href="#design-requirements">Design Requirements</a></li>
|
|
<li><a href="#conventions">Conventions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#specification-1">Specification</a>
|
|
<ul>
|
|
<li><a href="#end-to-end-encryption">End-to-End Encryption</a></li>
|
|
<li><a href="#cryptographic-protocols">Cryptographic Protocols</a></li>
|
|
<li><a href="#pre-keys">Pre-keys</a></li>
|
|
<li><a href="#flow">Flow</a>
|
|
<ul>
|
|
<li><a href="#1-initial-key-exchange-flow-x3dh">1. Initial key exchange flow (X3DH)</a></li>
|
|
<li><a href="#2-double-ratchet">2. Double Ratchet</a></li>
|
|
<li><a href="#3-chain-key-update">3. Chain key update</a></li>
|
|
<li><a href="#4-message-key-derivation">4. Message key derivation</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#security-considerations">Security Considerations</a></li>
|
|
<li><a href="#privacy-considerations">Privacy Considerations</a></li>
|
|
<li><a href="#copyright">Copyright</a></li>
|
|
<li><a href="#references">References</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
|
|
|
|
</div>
|
|
</aside>
|
|
|
|
</main>
|
|
|
|
|
|
</body>
|
|
|
|
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|