</code></pre></div></div><ul><li><codeclass="language-plaintext highlighter-rouge">identity</code>: Identity key <codeclass="language-plaintext highlighter-rouge">IK_B</code></li><li><codeclass="language-plaintext highlighter-rouge">signed_pre_keys</code>: Signed prekey <codeclass="language-plaintext highlighter-rouge">SPK_B</code> for each device, indexed by <codeclass="language-plaintext highlighter-rouge">installation-id</code></li><li><codeclass="language-plaintext highlighter-rouge">signature</code>: Prekey signature <i>Sig(<codeclass="language-plaintext highlighter-rouge">IK_B</code>, Encode(<codeclass="language-plaintext highlighter-rouge">SPK_B</code>))</i></li><li><codeclass="language-plaintext highlighter-rouge">timestamp</code>: When the bundle was created locally</li></ul><p>(<ahref="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L5">protobuf</a>)</p><divclass="language-protobuf highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kd">message</span><spanclass="nc">SignedPreKey</span><spanclass="p">{</span>
</code></pre></div></div><p>The <codeclass="language-plaintext highlighter-rouge">signature</code> is generated by sorting <codeclass="language-plaintext highlighter-rouge">installation-id</code> in lexicographical order, and concatenating the <codeclass="language-plaintext highlighter-rouge">signed-pre-key</code> and <codeclass="language-plaintext highlighter-rouge">version</code>:</p><p><codeclass="language-plaintext highlighter-rouge">installation-id-1signed-pre-key1version1installation-id2signed-pre-key2-version-2</code></p><h4id="double-ratchet"><ahref="#double-ratchet"class="anchor-heading"aria-labelledby="double-ratchet"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Double Ratchet </h4><p>Having established the initial shared secret <codeclass="language-plaintext highlighter-rouge">SK</code> through X3DH, it can be used to seed a Double Ratchet exchange between Alice and Bob.</p><p>Please refer to the <ahref="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 <codeclass="language-plaintext highlighter-rouge">ProtocolMessage</code> (<ahref="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L65">protobuf</a>) containing a map of <codeclass="language-plaintext highlighter-rouge">DirectMessageProtocol</code> indexed by <codeclass="language-plaintext highlighter-rouge">installation-id</code> (<ahref="https://github.com/status-im/status-go/blob/1ac9dd974415c3f6dee95145b6644aeadf02f02c/services/shhext/chat/encryption.proto#L56">protobuf</a>):</p><divclass="language-protobuf highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kd">message</span><spanclass="nc">ProtocolMessage</span><spanclass="p">{</span>
</code></pre></div></div><ul><li><codeclass="language-plaintext highlighter-rouge">bundles</code>: a sequence of bundles</li><li><codeclass="language-plaintext highlighter-rouge">installation_id</code>: the installation id of the sender</li><li><codeclass="language-plaintext highlighter-rouge">direct_message</code> is a map of <codeclass="language-plaintext highlighter-rouge">DirectMessageProtocol</code> indexed by <codeclass="language-plaintext highlighter-rouge">installation-id</code></li><li><codeclass="language-plaintext highlighter-rouge">public_message</code>: unencrypted public chat message.</li></ul><divclass="language-protobuf highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kd">message</span><spanclass="nc">DirectMessageProtocol</span><spanclass="p">{</span>
</code></pre></div></div><ul><li><p><codeclass="language-plaintext highlighter-rouge">X3DH_header</code>: the <codeclass="language-plaintext highlighter-rouge">X3DHHeader</code> field in <codeclass="language-plaintext highlighter-rouge">DirectMessageProtocol</code> contains:</p><p>(<ahref="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L47">protobuf</a>)</p><divclass="language-protobuf highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kd">message</span><spanclass="nc">X3DHHeader</span><spanclass="p">{</span>
</code></pre></div></div><ul><li><codeclass="language-plaintext highlighter-rouge">key</code>: Alice’s ephemeral key <codeclass="language-plaintext highlighter-rouge">EK_A</code>;</li><li><codeclass="language-plaintext highlighter-rouge">id</code>: Identifier stating which of Bob’s prekeys Alice used, in this case Bob’s bundle signed prekey.</li></ul><p>Alice’s identity key <codeclass="language-plaintext highlighter-rouge">IK_A</code> is sent at the transport layer level (Whisper/Waku);</p></li><li><codeclass="language-plaintext highlighter-rouge">DR_header</code>: Double ratchet header (<ahref="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L31">protobuf</a>). Used when Bob’s public bundle is available: <divclass="language-protobuf highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kd">message</span><spanclass="nc">DRHeader</span><spanclass="p">{</span>
</code></pre></div></div><ul><li><codeclass="language-plaintext highlighter-rouge">key</code>: Alice’s current ratchet public key (as mentioned in <ahref="https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet">DR spec section 2.2</a>);</li><li><codeclass="language-plaintext highlighter-rouge">n</code>: number of the message in the sending chain;</li><li><codeclass="language-plaintext highlighter-rouge">pn</code>: length of the previous sending chain;</li><li><codeclass="language-plaintext highlighter-rouge">id</code>: Bob’s bundle ID.</li></ul></li><li><codeclass="language-plaintext highlighter-rouge">DH_header</code>: Diffie-Helman header (used when Bob’s bundle is not available): (<ahref="https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L42">protobuf</a>) <divclass="language-protobuf highlighter-rouge"><divclass="highlight"><preclass="highlight"><code><spanclass="kd">message</span><spanclass="nc">DHHeader</span><spanclass="p">{</span>
</code></pre></div></div><ul><li><codeclass="language-plaintext highlighter-rouge">key</code>: Alice’s compressed ephemeral public key.</li></ul></li><li><codeclass="language-plaintext highlighter-rouge">payload</code>: <ul><li>if a bundle is available, contains payload encrypted with the Double Ratchet algorithm;</li><li>otherwise, payload encrypted with output key of DH exchange (no Perfect Forward Secrecy).</li></ul></li></ul><!-- TODO: A lot of links to status-go, seems likely these should be updated to status-protocol-go --><h2id="security-considerations"><ahref="#security-considerations"class="anchor-heading"aria-labelledby="security-considerations"><svgviewBox="0 0 16 16"aria-hidden="true"><usexlink:href="#svg-link"></use></svg></a> Security Considerations </h2><p>The same considerations apply as in <ahref="https://signal.org/docs/specifications/x3dh/#security-considerations">section 4 of the X3DH spec</a> and <ahref="https://signal.org/docs/specifications/doubleratchet/#security-considerations">section 6 of the Double Ratchet spec</a>, with some additions detailed below.</p><!-- TODO: Add any additional context here not covered in the X3DH and DR specs --><!-- TODO: description here ### --- Security and Privacy Features #### Confidentiality (YES) > Only the intended recipients are able to read a message. Specifically, the message must not be readable by a server operator that is not a conversation participant - Yes. - There's a layer of encryption at Whisper as well as above with Double Ratchet - Relay nodes and Mailservers can only read a topic of a Whisper message, and nothing within the payload. #### Integrity (YES) > No honest party will accept a message that has been modified in transit. - Yes. - Assuming a user validates (TODO: Check this assumption) every message they are able to decrypt and validate its signature from the sender, then it is not able to be altered in transit. * [igorm] i'm really not sure about it, Whisper provides a signature, but I'm not sure we check it anywhere (simple grepping didn't give anything) * [andrea] Whisper checks the signature and a public key is derived from it, we check the public key is a meaningful public key. The pk itself is not in the content of the message for public chats/1-to-1 so potentially you could send a message from a random account without having access to the private key, but that would not be much of a deal, as you might just as easily create a random account) #### Authentication (YES) > Each participant in the conversation receives proof of possession of a known long-term secret from all other participants that they believe to be participating in the conversation. In addition, each participant is able to verify that a message was sent from the claimed source - 1:1 --- one-to-one messages are encrypted with the recipient's public key, and digitally signed by the sender's. In order to provide Perfect Forward Secrecy, we build on the X3DH and Double Ratchet specifications from Open Whisper Systems, with some adaptations to operate in a decentralized environment. - group --- group chat is pairwise - public --- A user subscribes to a public channel topic and the decryption key is derived from the topic name **TODO:** Need to verify that this is actually the case **TODO:** Fill in explicit details here #### Participant Consistency (YES?) > At any point when a message is accepted by an honest party, all honest parties are guaranteed to have the same view of the participant list - **TODO:** Need details here #### Destination Validation (YES?) > When a message is accepted by an honest party, they can verify that they were included in the set of intended recipients for the message. - Users are aware of the topic that a message was sent to, and that they have the ability to decrypt it. - #### Forward Secrecy (PARTIAL) > Compromising all key material does not enable decryption of previously encrypted data - After first back and forth between two contacts with PFS enabled, yes. #### Backward Secrecy (YES) > Compromising all key material