-
Notifications
You must be signed in to change notification settings - Fork 16
NIP 112: Encrypted Group Chat
draft
optional
author:earonesty
This NIP defines new event kinds for encrypted group chat.
This NIP builds on then encryption from NIP-44, the gift-wrap of NIP-59 and the distributed chat channel management of NIP-28.
It works by creating a shared secret that is used to encrypt the group or channel messages. Only the participants know that secret, so only such members can read/write to this group chat. This effectively hides metadata from external users. See drawbacks below.
It reserves 4 event kinds (104) for immediate use.
[1059](https://github.com/nostr-protocol/nips/pull/468) - encrypted gift-wrap, can be used by many protocols
400 - wrapped kind: create encrypted channel
401 - wrapped kind: invite to encrypted channel
402 - wrapped kind: send encrypted message
403 - wrapped kind: change channel metadata
404 - wrapped kind: moved to new channel
For all encrypted group chat messages, the client first generates a kind 4XX message, as below.
Then they generate a new public/private keypair, and uses this to sign and encrypt the message.
The content
is NIP-44 encrypted JSON string with the temporary key, this is the inner event.
All events called "wrapped-kind XX" refer to these kind 1059 gift wrapped events.
Create a Encrypted chat channel.
In the channel creation content
field, Client SHOULD include basic channel metadata (name
, about
and picture
).
This is akin to NIP-28, kind 40 but using gift-wrap encryption.
On creating a channel, the creator MUST also generate a unique/new private-public key pair which will serve as the shared-secret
for a given channel.
This is the "destination pubkey" for the channel creation.
{
"content": "{\"name\": \"Demo Channel\", \"about\": \"A test channel.\", \"picture\": \"https://placekitten.com/200/200\"}",
}
The wrapped INNER event id for the channel creation should be saved. This is the event id that will be used in all future INNER references to the channel creation.
Channel creation events MUST be sent to the "destination pubkey" of the channel itself, not to any specific user.
As a rule, this "destination pubkey" of the channel MUST used as the sole identifier and external filter that clients use to retrieve events for the channel.
There are no other public tags or metadata, all other kinds and tags are "inner" (inside the wrapped message).
Invitations are sent directly to the participants of the channel.
{
"content": "optional personalized invitation message",
"tags": [["e", <channel-create-event-id> <relay-urls>], ["privkey": [<channel-private-key>]],
}
When wrapping invitation messages, the destination pubkey is the user being invited, the relay used should be one of that user's well-known relays.
More than one relay can be recommended in the "e" tag.
Update an encrypted channel's public metadata.
Clients and SHOULD handle wrapped-kind 402 events similar to kind 0 metadata
events. Relays cannot distinguish this from other kind 1059 events.
Clients SHOULD ignore kind wrapped-402 from pubkeys other than the pubkey that created the given channel using the corresponding wrapped-kind 400 event. In other words, only the creator of channel can send kind wrapped-402 events for a given channel; kind 402 for any channel sent by other people, even participants of that channel, are ignored.
Clients SHOULD support basic metadata fields:
-
name
- string - Channel name -
about
- string - Channel description -
picture
- string - URL of channel picture
Clients MAY add additional metadata fields.
Clients MUST specify an "e" tag to identify the channel id. Clients SHOULD mark the "e" tag to recommend a relay.
{
"content": "{\"name\": \"Updated Demo Channel\", \"about\": \"Updating a test channel.\", \"picture\": \"https://placekitten.com/201/201\"}",
"tags": [["e", <channel-wrapped-400-event-id> <relay-url>]],
...
}
Clients SHOULD use a marked "e" tags to specify if it is is a reply message.
Clients SHOULD use NIP-10 marked "e" tags to recommend a relay and specify whether it is a reply or root message.
Clients SHOULD append NIP-10 "p" tags to replies.
Inner-root message:
{
"content": <string>,
"tags": [["e", <kind_400_event_id>, <relay-url-where-it-was-seen>, "root"],
...
}
Inner-reply to another message:
{
"content": <string>,
"tags": [
["e", <kind_400_event_id>, <relay-url>, "root"],
["e", <kind_403_reply_to_event_id>, <relay-url>, "reply"],
["p", <pubkey>, <relay-url>],
...
],
...
}
Send a Wrapped Kind 403
Once a group is created, all participants know the shared-secret, so to remove a participant, we need to create a new group.
To do, this the creator of the group sends out a kind 403 to every member of the new group, excluding the removed participants.
{
"content": "{\"name\": \"Demo Channel\", \"about\": \"A test channel.\", \"picture\": \"https://placekitten.com/200/200\", \"privkey\": \"<private key of new channel>\", \"oldkey\": \"<private key of previous channel>\",}",
"tags": [["p", <channel-public-key>, <relay-url>]],
}
Clients SHOULD ignore wrapped-kind 403 messages from anyone but the creator of a group.
Clients SHOULD ignore messages to the old group that occur after their receive the first kind 403
Clients use kind 403 to find out which was the precursor channel to this new channel, and can optionally display both the old and new channel seamlessly to the user, with messages from the old channel and the new channel merged as a unified channel history.
For NIP-10 relay recommendations on replies and on channel creation info, clients generally SHOULD use the relay URL where the event was first seen, if known.
We reserve wrapped-event kinds 404-409 for other events related to chat, to potentially include new types of media (photo/video), delegation, moderation, mute, hide, etc.
This is the easiest way to allow the use of group chat with select group of people, while hiding metadata.
Any member of the group can, implicitly, invite new members to the group, since they have the private key. Any member of a group can "doxx" other members by publishing their wrapped messages.
Further, if any single participant of the group chat leaks the shared secret ( whether intentionally or by accident), all the messages (past or future) can then be decrypted by others.
Frequent 403 events can help mitigate these attacks.