research
research copied to clipboard
Better support for conversational security layer guarantees for Waku base layer
Problem
We want to provide a simple, modern, and secure way for developers building on top of Waku to provider conversational security guarantees for their platforms.
For historical reasons, the way this is currently done is quite complex:
- The Waku Message Payload Encryption (https://rfc.vac.dev/spec/26/) was inherited from Whisper, which is suboptimal in a few ways (complex, non-standard etc)
- On top of this, there's a separate secure transport protocol (https://specs.status.im/spec/5) for forward secrecy that Status usage, which is based on Double Ratchet and X3DH but is currently only implementation in status-go (not Nim nor JS)
This means we don't have a simple and modern way to provide secure messaging with excepted security guarantees for platforms other than Status that works in browsers etc.
With modern frameworks such as Noise (https://noiseprotocol.org) that act as an evolution of things like Double Ratchet (same author), as well as a schelling point for the p2p space (used in libp2p and Ethereum 2 spec, as well as WireGuard and Lightning), there should be room for simplification here. It also has multiple implementations.
This would also complete the story of Waku, where users get conversational security out of the box, without having to re-implement the Status protocol (say) or come up with their own solution.
Proposed solution
We want to introduce a new experimental version 2 spec and implementation for Waku payload encryption https://rfc.vac.dev/spec/14/#payload-encryption
It should provide for basic and excepted security properties such as: confidentiality, authenticity, integrity, as well as some forms of unlinkability and forward secrecy.
Ideally, it'd provide a superset of current capabilities that are provided for with RFC 26 and SPEC 5, i.e.:
- Symmetric (PSK mode?) as well as asymmetric encryption
- Similar or better forward secrecy guarantees to existing solution
Use of more modern primitives, such as ChaChaPoly and similar, would also be interesting. Ditto providing for Zero-RTT and identity hiding (?).
Trade-offs
We acknowledge that this wouldn't have compatibility with the current Status secure chat protocol. There's not currently a strongly identified user for this, but we expect that this will be desired among non Status users.
Since it is unlikely all security and usability properties can be achieved simultaneously, there is likely to be some form of modularity in the spec. I.e. where certain Noise patterns are encouraged and/or required.
Other trade-offs that have to be considered are:
- Use of identity key - does using secp256k1 make sense here given likely Ethereum-heavy usage?
- Complexity of Noise negotiation? There might be a simpler design here, e.g. using different Waku Message versions/separate field for different security goals
- Using more established patterns that are already implementated in multiple implementations (e.g. specific patterns or primitives that can be used from Nim and JS)
- Erring on the side of established patterns, e.g. used in Ethereum, while still keeping in mind differing requirements for Waku (privacy, running in many diverse environments, different domain, etc)
Additional context
Laundry list of some things that be improved in encrypted Waku Payload: https://github.com/vacp2p/rfc/issues/414
Specs:
- 26/WAKU-PAYLOAD: https://rfc.vac.dev/spec/26/
- 14/WAKU2-MESSAGE https://rfc.vac.dev/spec/14/
- Status 5/SECURE-TRANSPORT https://specs.status.im/spec/5
- Ethereum p2p spec https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/p2p-interface.md
- Libp2p noise spec https://github.com/libp2p/specs/tree/master/noise
- (Status example usage: https://specs.status.im/spec/6 and https://specs.status.im/spec/1)
Code:
- https://github.com/status-im/nim-waku/blob/master/waku/v2/node/waku_payload.nim
- Example usage https://github.com/status-im/nim-waku/blob/master/examples/v2/chat2.nim
- nim-libp2p crypto https://github.com/status-im/nim-libp2p/tree/master/libp2p/crypto
- nim-libp2p noise https://github.com/status-im/nim-libp2p/blob/master/libp2p/protocols/secure/noise.nim
Other notes
Long term, we are also interested in things such as:
- Sphinx or similar packet format for better privacy metadata guarantees https://github.com/vacp2p/rfc/issues/182
- Better group chat support (Megolm, decentralized MLS etc)
However, these are out of scope for this issue.
Acceptance criteria
- [ ] Initial rough plan with decisions and trade-offs
- [ ] Issue(s) in vacp2p/rfc repo for spec change
- [ ] Issue(s) in nim-waku for implementation
- [ ] Issue(s) in other Nim libraries needed
Are you thinking group messaging? If so, did you look further into MLS? I'm unsure if Matrix deployed it yet, but they were trying, and ran into some hiccups, but still making progress.
A general comment re
Initial rough plan with decisions and trade-offs
One potential strategy to decide on what Noise protocol patterns fit is to first look at the most dominant use-case(s) of waku2 e.g., maybe as the messaging layer of Ethereum, and then identify the assumptions and security requirements around that use-case e.g., parties have pre-shared keys or not, one-side or two-side authentication is needed or not, what resources are available at parties (might affect the type of encryption or the underlying curve). By having a rough idea bout all these, we can adopt a Noise protocol pattern accordingly and proceed with that.
For a js-waku point of view, the main question is whether there are cryptographic libraries readily available to implement the proposed encryption scheme(s) and whether js-libp2p-crypto is among them. Also, this was mentioned: https://github.com/libp2p/specs/issues/355#issuecomment-905870745 As we are part of the libp2p and Ethereum domain, we need to be aware whether the proposed encryption protocols stray from the de facto protocols used in both domain to ensure we foresee possible issues.
I am guessing this can be updated as noise protocols were delivered (I see some boxes that could be ticked)
^ @s1fr0