Appendix B. P2P Signal protocol deltas
Normative for auditors reviewing Signal usage in Enkrypted Chat. Upstream definitions: Signal Protocol documentation. Tutorial background: P2P Signal Protocol.
B.1 Scope
This appendix lists only deltas from the standard Signal deployment model. Where this document is silent, implementations SHOULD follow the Signal specification for primitive choice (Curve25519, AES-256, HMAC-SHA256, etc.) unless noted here.
B.2 No central pre-key server
| Standard Signal | Enkrypted Chat P2P |
|---|---|
| Bob uploads pre-key bundle to server before Alice messages | Peers exchange material live over WebRTC data channel after ICE |
| Alice fetches bundle asynchronously | Synchronous handshake PDUs: signal-key-exchange-request, signal-key-exchange-response, signal-session-complete (P3) |
| One-time prekeys consumed from server pool | No one-time prekeys — 3-DH X3DH variant instead of 4-DH |
Implication: No offline initial message to a peer who has never been online in the same session establishment window.
B.3 X3DH variant (3-DH)
The P2P handshake performs three DH contributions (identity, signed prekey, ephemeral) without a one-time prekey DH4 term. Forward secrecy for the first application message relies on ephemeral keys plus WebRTC DTLS and subsequent Double Ratchet steps.
B.4 WASM implementation bridge
- Browser builds use WebAssembly compiled from the
signal-protocolRust core. - JavaScript in
p2pmarshals keys and ciphertext across the WASM boundary; wire PDUs remain JSON (P4). - Formal verification (overview) applies to the Rust core, not the JS/WASM glue or cascade wrapper.
B.5 Local storage
| Asset | Typical location |
|---|---|
| Identity and session state | Browser storage (IndexedDB / OPFS per product build) |
| Ratchet state | Persisted per peer session in MLSProvider / Signal store |
Storage encryption at rest is product-dependent and not guaranteed by EnkryptedChat-Profile-v0 (P1.5).
B.6 Identity key vs Peer ID
| Identifier | Role |
|---|---|
| Peer ID | Broker routing address; opaque string; not a Signal identity key |
| Signal identity key | Long-term key inside WASM store; used in X3DH and ratchet |
Verifying that a Peer ID maps to an expected identity key is out of band (TOFU or future safety-number UX).
B.7 Session lifecycle
| Event | Behavior |
|---|---|
| First connect | Full Signal exchange via P3 handshake |
| Reconnect, state retained | MAY resume ratchet if peer IDs unchanged (P3.6) |
| Lost state / peer ID change | MUST repeat Signal handshake |
| Teardown | Local session state SHOULD be cleared on explicit disconnect or unrecoverable decrypt failure |
B.8 Out-of-order and skipped messages
Double Ratchet MUST accept out-of-order ciphertext within a session per Signal semantics. Maximum skip windows follow the WASM library configuration; auditors SHOULD inspect signal-protocol tests for bounds.
B.9 Composition with cascade
Signal encrypts the output of the MLS layer (or plaintext entry) inside the cascade (P5). Signal security properties apply to that layer’s input/output; they do not extend to broker metadata, MLS group administration plaintext in handshake, or fast-file DTLS-only paths.
B.10 Security properties (Signal layer only)
| Property | P2P Signal layer |
|---|---|
| Forward secrecy (messages) | Provides (after handshake complete) |
| Break-in recovery | Provides (Double Ratchet) |
| Asynchronous delivery | Does not provide (no relay server) |
| Server-assisted key directory | Does not provide |