Add NIP-104: E2EE messaging using MLS
Take 2!
This NIP outlines a way to do secure direct and group messaging on Nostr using the MLS protocol.
Is this the code implementing it?
https://github.com/erskingardner/openmls_nostr_crypto
I feel like this is only part of it.
I'm working on implement this NIP for https://github.com/lumehq/coop let see how it go 😄
I feel like this is only part of it.
@rabble yes, this is definitely only part of it. I started that library and intend for it to be complete but then got sucked into updating upstream dependencies to support Schnorr signatures over secp256k1. Ultimately though, it's possible for clients to be built using the other ciphersuites that are already supported by OpenMLS though so I wanted to get the spec out here for review.
The future benefit of that library you liked above will be that nostr clients will have fewer dependencies on underlying crypto primitives, that's basically it.
I'm working on implement this NIP for https://github.com/lumehq/coop let see how it go 😄
🤙 Definitely feel free to DM me if you run into anything or have questions.
Farcaster implemented Signal protocol in DMs. Then they've dropped it because it was too complex to support on different devices (old / new / different libraries).
It would be great to have some kind of demo app first. I suspect it'll be quite complicated.
Nice, how can one extend the Group creation to use FROST (Maybe even have the FROST signers as group admins)?
Nice, how can one extend the Group creation to use FROST (Maybe even have the FROST signers as group admins)?
I've had a bit of a look at FROST but haven't really thought about how it might apply. For now, it's completely out of scope.
It would be great to have some kind of demo app first. I suspect it'll be quite complicated.
@paulmillr working on it :)
Some very initial thoughts on a potential choice of cipher suite: https://njump.me/nevent1qvzqqqqqqypzpp59a0hkv5ecm45nrckvmu7pnk0sukssvly33u3wwzquy4v037hcqyg8wumn8ghj7mn0wd68ytnddakj7qgwwaehxw309ahx7uewd3hkctcqyprq4w327fynj7wa6lha6pktmer8c0979ds0sc89cgsmh5af4pet60p3dcc
@erskingardner looking forward to see your demo app, and what dependencies it pulls in. That might help inform the above.
Nice, how can one extend the Group creation to use FROST (Maybe even have the FROST signers as group admins)?
This makes me wonder how Signal does group admin stuff. They have a nice features to tweak within groups. For these different MLS events, is it expected that all participants are publishing all event types for the group?
Signal groups is just a bunch of 1-to-1 messages. Group settings are stored in the server in enclaves.
This looks super great, I have been thinking about something like this for a while and will maybe try building a client for it. Any update on the more specific example process/app?
This looks super great, I have been thinking about something like this for a while and will maybe try building a client for it. Any update on the more specific example process/app?
I'm working on a reference client right now @github-tijlxyz I'll let everyone know here and on nostr when it's ready. :)
This is ready for review. I've made some updates based on what I'm doing in White Noise and while I don't have fully completed libraries, I would love to start working with anyone that is interested in implementing this to help find more places where we need supporting library code.
Obviously, I'd love to merge this NIP once we get some more eyes on it.
@fiatjaf @staab @vitorpamplona @pablof7z @paulmillr @Sjors @v0l @hzrd149
@erskingardner do you have a fully working MLS over nostr implementation in place?
Yes. https://github.com/erskingardner/whitenoise
I'm still having some platform specific issues (nothing related to MLS) before it's ready for distribution but it works end to end.
- Post compromise security means that leaking key material doesn't allow an attacker to continue to read messages indefinitely into the future.
A brief description of how this is solved would be useful. I know MLS is supposed to solve it, but an ELI5 version would nonetheless be helpful. Like, what exactly happens after user's messaging key is leaked. Or if their private key is leaked.
A brief description of how this is solved would be useful. I know MLS is supposed to solve it, but an ELI5 version would nonetheless be helpful. Like, what exactly happens after user's messaging key is leaked. Or if their private key is leaked.
@paulmillr do you think it's worth having a section in the NIP about the threat model and various compromises possible? Or are you just looking for an explanation here? MLS has a specific section I can link to that goes into lots of detail on this for MLS specifically. There are some nostr specific things I could add though.
MLS spec is hard to read. I think a simple section describing how things improve over the status-quo would be useful, including compromises. Best to keep it concise.
Added a section on Security considerations with some basic details and links to MLS docs on the more in-depth stuff.
is it the idea that we can try Whitenoise? i can't get it to work with the several dependencies
Which dependencies?
I mean if I should try to run whitenoise now, because I think there are some problems like a release tag missing for https://github.com/erskingardner/nostr-openmls which is specified here https://github.com/erskingardner/whitenoise/blob/master/src-tauri/Cargo.toml and some of the dependencies there point to local directories.
Ah yeah, good catch. I've been making changes to those libraries locally. Let me try and get a buildable version done tomorrow. Fair warning. I've been building locally on a mac and things seem to be working well but once I try and run the app on any other platform I get a lot of strange behavior which I'm working on fixing now.
@alexfj0 you should be able to build the app now, I've updated the dependencies to point to GH.
To test out groups and messages, it's easiest to do the following:
- Sign in with an account that is following a few users (hopefully at least one other account that is yours).
- Go to settings, sign in with the second account.
- Publish a key package event from the settings page.
- Switch to the first user.
- Go to the chats screen, click the plus icon at the top right, select your other user and invite them to start a chat.
- Once the group is created, you can try sending a few messages.
- Then switch to the other user. You should see an invite waiting for you.
- Accept that invite and then you can start replying to the other user.
Let me know if you have any troubles.
I’m encountering some issues while implementing NIP-104:
-
I just want to confirm if the content of the kind 443 event is an encodedKeyPackage string? I couldn’t find this in the spec, but the whitenoise implementation seems to do it this way.
-
Does the kind 445 group event need to include the current epoch? Otherwise, do we need to iterate through the local group keys to try decrypting?
The "easy to read" link in the PR description points to an older commit.
A better link, always pointing to the latest version, is
https://github.com/erskingardner/nips/blob/master/104.md
Can you please update it?
In the "Example KeyPackage Event" snippet, the pubkey and sig comments refer to the "main identity key".
However, a few paragraphs above warn that:
KeyPackages include a signing key that is used for signing MLS messages within a group. This signing key MUST not be the same as the user's Nostr identity key.
Is the "main identity key" (from the snippet comments) the same as the user's Nostr identity key? I assume not, but they sound very similar. Could you add a bullet point under that snippet explaining what the "main identity key" is?
I just want to confirm if the content of the kind 443 event is an encodedKeyPackage string? I couldn’t find this in the spec, but the whitenoise implementation seems to do it this way.
The content of the kind 443 is a hex encoded MLS welcome message object (from OpenMLS). You can see everything I'm doing in the create_group command on White Noise. You'll also want to look at the nostr-openmls library for the actual call to the OpenMLS methods.
Does the kind 445 group event need to include the current epoch? Otherwise, do we need to iterate through the local group keys to try decrypting?
No it doesn't need to include the epoch in the actual event or tags. That's included in the MlsMessageOut object you get from the OpenMLS library.
Is the "main identity key" (from the snippet comments) the same as the user's Nostr identity key? I assume not, but they sound very similar. Could you add a bullet point under that snippet explaining what the "main identity key" is?
The "main identity key" is the nostr pubkey (npub in hex format). The "signing key" is the key that you use to generate the KeyPackageBundle. You can see how that is getting done in nostr-openmls.
I can add a bit more context to the spec for that.
No it doesn't need to include the epoch in the actual event or tags. That's included in the MlsMessageOut object you get from the OpenMLS library.
Sorry, maybe I’m wrong, but shouldn’t we decrypt the event first before getting the MlsMessageOut object? Nip44 decrypting requires knowing the epoch to obtain the corresponding group key. I’m not sure if I understand this correctly