nostrability
nostrability copied to clipboard
Direct Messaging (DMs)
Summary in quote form from a nostr DM User
I gave up. Either it works, but is not encrypted - or it doesn't work for me, in which case I just give up and fall back to "tools of the old world". -dissatisfied nostr DM user
| app | nip-04 | nip-17 one-to-one | nip-17+group | double ratchet | MLS | comment |
|---|---|---|---|---|---|---|
| bitchat | ✅ | PR | ||||
| 0xchat | ✅ | ✅ | ||||
| 0xchat Lite | ✅ | aiming for compatibility with white noise NIP-104 | ||||
| amethyst | ✅ | ✅ | If the receiver doesn't have a DM relay, it sends to all relays of the sender in the hopes that the receiver shares some of those relays. | |||
| Chachi | ✅ | nip-17 note | ||||
| n17.chat | ✅ | |||||
| damus | ✅ | planned | POC | |||
| Flotilla | ✅ | ✅ | ||||
| gossip | ✅ | ✅ | NIP-17 if signaled with 10050 event | |||
| Iris | ❌ | yes* | *interoperability not confirmed | |||
| keychat | ✅ | yes* | yes* | *interoperability not confirmed | ||
| white noise | yes* | *interoperability not confirmed. NIP-EE spec | ||||
| rust-nostr | ✅ | ✅ | ✅ | https://github.com/rust-nostr/nostr/tree/master/crates/nostr-mls | ||
| Flash | ✅ | https://njump.me/nevent1qqsylfnj542yrze3h9t9vgucxm4l764vmr3pyn9y4uaq9y06hrlrdagf0aw04 | ||||
| Yakihonne | secure DMs toggle is confusing] | |||||
| nostrphp | PR submitted | |||||
| marketplaces | ✅ | working spec | ||||
| Coracle | ❌ | ✅ | ✅ | ❌ | ❌ | NIP 04 is evil, MLS is hard (planning to add it when the typescript library is ready) |
| nostrudel | ✅ | ✅ | https://njump.me/nevent1qqs84nnyc2jx796hrm3vsec9zaf6vwp2v8qaustrdq9raxkv3rp5xjsdysxan | |||
| Coop | ✅ | |||||
| Flightless | ✅ | https://njump.me/nevent1qqsgm9tjgwpp7z5q5e2aqj6x3km5a79zpr8sx8647k8ssnrawpe4a5qpr9mhxue69uhhqun0ve5kcetn9ehx7um5wgcjucm0d5q3wamnwvaz7tmswf5k6atn9ehx7um5wgcjucm0d578y9g6 |
problem statement
Today there are at least four (4) direct messages standards implemented on nostr.
NIP-04 (used by iOS damus) NIP-17 (amethyst) double rachet signal (@mmalmi Iris) MLS (used by white noise @erskingardner)
Example incompatibility betwee Amethyst and Damus: https://github.com/nostrability/nostrability/issues/152
When sending DMs to another profile on nostr, it is not always immediately clear which app(s), and which standard(s) the DM counterparty/receiver is able to receive and read.
Ideally, there is some under the hood communication that takes place, so that DM senders don't have to think about DM standards, and which apps implement which standard(s).
How might we solve this multi-DM standard problem?
cc @mmalmi @erskingardner @vitorpamplona @jb55
cryptography
NIP-17 is encrypted by NIP-44. NIP-44 has been audited. See https://github.com/paulmillr/nip44/blob/ce63c2eaf345e9f7f93b48f829e6bdeb7e7d7964/audit-2023.12.pdf and https://cure53.de/audit-report_nip44-implementations.pdf.
see couple more DMs issues: https://github.com/nostrability/nostrability/issues/152 Amethyst DM cannot be seen by damus NIP-17 https://github.com/nostrability/nostrability/issues/98 Mastodon / activitypub / fediverse DM to nostr warning #98
Keychat has its own NIP-04 implementation, its own Signal implementation and its own MLS implementation to be best of my understanding.
Keychat has its own NIP-04 implementation, its own Signal implementation and its own MLS implementation to be best of my understanding.
That's my understanding too. They've rolled their own everything.
Iris doesn't have NIP-04 anymore
Let's create another standard!
Coracle, Gossip, Shopstr, Yakihonne, Snort support nip-4, and nip17
Nip-17-only clients:
- Chachi, Coop, Flotilla
Is the following left curve solution considered bad form:
-encourage that all apps add a client tag (e.g. nevent published by nostrudel, coracle etc.) -refer to a DM compatibilty matrix for any and all nostr apps -nostr app X is then responsible for handling UI (or not) that suggests e.g. "your counterparty utilizes an app with a compatible/incompatible DM standard" -if incompatible: "proceed to magicnostrapplist dot com to find a compatible DM app"
Is the following left curve solution considered bad form:
-encourage that all apps add a client tag (e.g. nevent published by nostrudel, coracle etc.) -refer to a DM compatibilty matrix for any and all nostr apps -nostr app X is then responsible for handling UI (or not) that suggests e.g. "your counterparty utilizes an app with a compatible/incompatible DM standard" -if incompatible: "proceed to magicnostrapplist dot com to find a compatible DM app"
Bad form or not, this would take much more work than you imagine, work that is better employed by people just doing NIP-17 and deleting NIP-04.
Bad form or not, this would take much more work than you imagine, work that is better employed by people just doing NIP-17 and deleting NIP-04.
Noted. Say NIP-04 is retired.
Now there remain:
- NIP-17
- double ratchet
- MLS
The multi-standard problem statement remains.
I am biased, but here's my take.
NIP-04 is gone.
NIP-17 is the basis that everyone should code. Just because it is easier than other protocols.
Double Ratchet and MLS require offline state storage that is not connected and cannot be recovered from your keys alone. So, when people switch clients, unless they also export/import the chat seed or full state/db from the source client, they are not going to see their messages, even if both clients implement these protocols. To me, that is a real trade-off. Some conversations need that type of privacy, others don't. And for those specific conversations, it's fine to use NIP-17 to start and then transfer to a more private means of communication.
Keychat input:
We believe that the key is to differentiate between the DM functionality of microblogging apps and standalone chat apps. Microblogging apps should use nip17 and gradually phase out nip4. Chat apps should use the Signal protocol and MLS protocol. When users send DMs on microblogging apps, nip17 should be used.
https://njump.me/nevent1qqsdcx6w4j2jx93hs77rks0y30yxtxwnt7c2y6wly6pplulddy0lx7galuwg6
I've refrained from commenting because I'm not an expert on signal's protocol or MLS, but my understanding is that MLS provides a superset of the functionality with equivalent or better performance and privacy. Any work on signal-style double ratchet protocols is redundant, and fragments interoperability. I welcome any corrections but I really don't know why we would not be going all in on MLS at this point.
On nip 17 vs MLS, I think for now 17 should be the standard, and MLS articulated as a "secure upgrade" based on feature detection. MLS clients should always read and display NIP 17 messages, but refrain from sending them. This is how I managed the NIP 04 deprecation in Coracle. Long term though, it's probably worth upgrading all the way to MLS for best case privacy and interop.
A couple of inputs today. From JeffG on privacy (worst, good, best) & complexity of implementation (t-shirt size)
Nip04 worst XS Nip17 ok S (this is gift wrap) @Martti Malmi signal stuff good M/L MLS best L/XL
From Martti:
It's better to use MLS if it works reliably and is not overly complicated to use as a library. Double ratchet's advantage is simplicity: it's fairly easy to implement on all platforms. I think it makes sense to try both and see how it goes. Maybe both have different use cases.
What do you envision as the use case(s) where these encryption methods two find product-market for?
For example, double ratchet is easy and lightweight to add to a chat widget on a web page. Less than 100KB bundle, including dependencies from nostr-tools. Actually, it could perhaps be included as a nip library in nostr-tools.
I've refrained from commenting because I'm not an expert on signal's protocol or MLS, but my understanding is that MLS provides a superset of the functionality with equivalent or better performance and privacy. Any work on signal-style double ratchet protocols is redundant, and fragments interoperability. I welcome any corrections but I really don't know why we would not be going all in on MLS at this point.
Your understanding is correct. I agree that the signal double ratchet, while lighter weight - especially when you think about dependencies, isn't so much easier to implement that we should continue to fragment messaging. My plan with MLS is to build libraries to make the implementation as easy as possible over time (with lots of language bindings to everything). If dependency size is an issue, I'm sure we can address that. I'll see about getting some benchmarks on size of dependencies (OpenMLS is the big one) soon.
EDIT: I took a quick cursory look at the dependency graph of White Noise and the total of all dependencies required for MLS are ~1MB in total. This is fully unoptimized - I'm very sure we can get this down further.
Language bindings can only go so far. The goal should be for each language to have its own native implementation.
Language bindings can only go so far. The goal should be for each language to have its own native implementation.
Agree, in time. 😅
Language bindings can only go so far. The goal should be for each language to have its own native implementation.
@vitorpamplona what is the benefit? Code execution performance?
renamned NIP-17 to NIP-17 one-to-one, and added a NIP-17+group column (i.e. supports one-to-one and group chats) per Joe Ruelle feedback
https://njump.me/nevent1qqs9xyaxc7r4xtznwpad59mjtj0rtrx5x34gn4eex4tepnxvy3lvw6cpz3mhxue69uhhyetvv9ujuerpd46hxtnfduqs6amnwvaz7tmwdaejumr0dsq3vamnwvaz7tmjv4kxz7fwwpexjmtpdshxuet5usyl6x
Language bindings can only go so far. The goal should be for each language to have its own native implementation. @vitorpamplona what is the benefit? Code execution performance?
Mostly call performance and memory management. Beyond the additional cost of the bridge between languages in each call, most compiler optimizations (which today are the driving force of performance in general) have to be disabled when calling binaries directly. This is especially true when garbage-collected languages (java, go, etc) have to interface with native memory. On top of that, most host languages open their memory safety up to the native library. The library can break all the security constraints made by the host language. In Java, for instance, the native lib (or any of its dependencies) can completely take over the JVM.
added a NIP-17+group column
It's impossible to support nip 17 without supporting group messages without purposely breaking things.
added a NIP-17+group column
It's impossible to support nip 17 without supporting group messages without purposely breaking things.
Yeah, it feels like it's more work to remove groups than to support them. Do we even have a case where NIP-17 is coded but not the group part of it?
0xChat, Amethyst, Coop, Gossip, Flotilla, Coracle and Yakihonne support one-on-one and groups.
Robosats, Minibits, Safebox, Wherostr, Nutstash, Cashu.me, Keychat seems to all support at least one-on-one NIP-17.
Keychat directly uses the open-source libsignal (X3DH + double ratchet), while Iris uses secp256k1 to re-implement the idea of the double ratchet.
https://github.com/signalapp/libsignal
https://damus.io/nevent1qqsgjvrlud57y0l4meen8gcrjjcqlnhh98fv5y380u6fcazg3le287qyl684g
https://njump.me/nevent1qqsxrmv82ggyjzdxl3jmuflc85vn5djxetx4ypm4wwnalrzwcs28uqsdwyy70
Keychat 0xchat proposing MLS group chat compatibility
@vitorpamplona on NIP-17
https://njump.me/nevent1qqswrqethwqlh6d79crtcfmcvvc92w7gpkw4hdvyk8g05aqeevmntvcpzfmhxue69uhk7enxvd5xz6tw9ec82cspr9mhxue69uhhq7tjv9kkjepwve5kzar2v9nzucm0d5qs6amnwvaz7tmwdaejumr0dsq3vamnwvaz7tmjv4kxz7fwwpexjmtpdshxuet5g8kr9u
In white
@keychat-io update:
We're currently revising our MLS group implementation. We've studied the codebases of NIP-104 and White Noise in depth and learned some useful design ideas—such as encrypting MLS messages using NIP-44 and hiding the
group_ID. We’ve also been posting comments and discussing better mechanisms, like more efficient ways to update the MLS group’s receiving addresses. Ultimately, we hope different MLS clients will be able to interoperate.
https://njump.me/nevent1qqs24h2tgeqn0acs4xfe5r540aqz6x05eafeddn7w6ykpgchd55rhhqrkmdun
@keychat-io on various DM implementation and spec differences:
NIP-4 vs NIP-17 vs Signal Protocol vs MLS Protocol
Microblog DMs and standalone chat apps represent different scenarios and application types.
Microblog DMs prioritize multi-device synchronization over enhanced security, while standalone chat apps favor better security over multi-device synchronization.
NIP-4 and NIP-17 are suited for microblog DMs, while the Signal and MLS protocols are ideal for standalone chat app.
NIP-4 and NIP-17:
These protocols are suited for microblog DMs due to their efficient multi-device synchronization, as the encryption key and receiving address remain unchanged. Importing an nsec key allows users to receive and decrypt DM messages, which is ideal for microblog DMs.
However, this same feature becomes a disadvantage for standalone chat apps because it compromises forward secrecy and backward secrecy, and exposes the recipient's identity.
Signal Protocol and MLS Protocol:
These protocols update the encryption key with each message, and the receiving address can also be updated. This feature is best suited for standalone chat apps due to its robust security features.
However, this advantage turns into a disadvantage for microblog DMs due to poor multi-device synchronization capabilities. Simply importing an nsec key is not sufficient to receive and decrypt messages in such scenarios.
NIP-4 vs NIP-17:
Both NIP-4 and NIP-17 do not conceal the recipient’s identity. However, NIP-17 conceals the sender's identity, unlike NIP-4.
Signal Protocol vs MLS Protocol:
The Signal Protocol is best suited for one-on-one chats and small group chats.
The MLS Protocol is ideally suited for large-scale group chats.
https://njump.me/nevent1qqsfz7djthay0z462m3ttshqp2a3eqnvms7hs5h3nj896jgackugxdczyzaljga2jfrqvhugcsx8mxlkrnxvplelelcxt2xt9l6vlwmzpz83u8qveyn
added link to MLS NIP-EE spec used by White Noise
@erskingardner which other app(s) today are compatible with White Noise via MLS spec?