From e9783b1a80d3b3716444e0fa4d5a3617ce434f96 Mon Sep 17 00:00:00 2001 From: erik aronesty Date: Sun, 4 Jun 2023 09:45:07 -0400 Subject: [PATCH] . --- 112.md | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 112.md diff --git a/112.md b/112.md new file mode 100644 index 0000000..dff7962 --- /dev/null +++ b/112.md @@ -0,0 +1,240 @@ +NIP-112 +======= + +Encrypted Group Chat +-------------------- + +`draft` `optional` `author:earonesty` + +This NIP defines new event kinds for encrypted group chat with optional forward secrecy guidelines. + +This NIP builds on the encryption from NIP-44, the gift-wrap of NIP-59 and the distributed chat channel management of NIP-28. It is similar to NIP38, with the exception that gift-wrap is used on every message, and issues like metadata leakage and optional forward secrecy are addressed. + +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: change channel metadata +- `403` - wrapped kind: send encrypted message +- `404` - wrapped kind: moved to new channel + + +## Kind 1059: Encrypted Gift Wrap + +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](https://github.com/nostr-protocol/nips/pull/574) 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. + +## Wrapped Kind 400: Create Encrypted channel + +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. + +```json +{ + "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). + +## Wrapped Kind 401: Invitation to Encrypted Channel + +Invitations are sent directly to the participants of the channel. + +```json +{ + "content": "optional personalized invitation message", + "tags": [["e", ], ["privkey": []], +} +``` + +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. + +## Wrapped Kind 402: Change channel metadata + +Update an encrypted channel's public metadata. + +Clients and SHOULD handle wrapped-kind 402 events similar to kind 33 `replaceable` events. Relays cannot distinguish this from other kind 1059 events. + +Clients SHOULD ignore kind wrapped-402 from pubkeys other than the current owner. + +The current owner of a channel is the pubkey that created the given channel using the corresponding wrapped-kind 400 event, or the current owner based on the 405-406 channel ownership delegation flow. + +In other words, only the owner of a channel can *effectively* send kind wrapped-402 events; 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. + +```json +{ + "content": "{\"name\": \"Updated Demo Channel\", \"about\": \"Updating a test channel.\", \"picture\": \"https://placekitten.com/201/201\"}", + "tags": [["e", ]], + ... +} +``` + + +## Kind 403: Send encrypted message to encrypted group channel + +Clients SHOULD use a marked "e" tags to specify if it is is a reply message. + +Clients SHOULD use [NIP-10](10.md) marked "e" tags to recommend a relay and specify whether it is a reply or root message. + +Clients SHOULD append [NIP-10](10.md) "p" tags to replies. + +### Format + +Inner-root message: + +```json +{ + "content": , + "tags": [["e", , , "root"], ] + ... +} +``` + +Inner-reply to another message: + +```json +{ + "content": , + "tags": [ + ["e", , , "root"], + ["e", , , "reply"], + ["p", , ], + ... + ], + ... +} +``` + +### Wrapped-kind 404: Removing Participants + +Send a Wrapped Kind 404 (similar to 401) + +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 issues a new 400 event. + +Then the creator sends out a kind 404 individually to every member of the new group, *excluding the removed participants*. + +```json +{ + "content": "optional friendly invite message", + "tags": [["e", , ], ["e", , ], ["privkey", []] +} +``` +Clients SHOULD ignore wrapped-kind 404 messages from anyone but the current owner of a group. + +Clients SHOULD ignore messages to the previous group that occur after their receive the first kind 404. In addition there is no longer a need to subscribe to the public keys of prior groups. + +Clients use kind 404 to find out which was the precursor channel(s) to this new channel, and should attempt to display all old and new channels in a chain seamlessly to the user as a unified channel history. + +Clients SHOULD consider the new channel metadata as authoritative. + +Clients MAY discard previous channel information, since it will no longer be used. + +### Wrapped-kind 405: Delegate new owner + +To do, this the creator of the group sends out a wrapped-kind 405 to the main group public key. + +```json +{ + "content": "optional friendly invitation to own the group", + "tags": [["e", <400-event-id-of-group>, ], ["p", ]] +} +``` +Clients SHOULD ignore wrapped-kind 405 messages from anyone but the current "owner" of a group. +Clients SHOULD ignore wrapped-kind 405 messages until they receive a 406 CLAIM message from the new "owner" of the group. + +### Wrapped-kind 406: Accept ownership transfer + +To do, this the creator of the group sends out a wrapped-kind 405 to the main group public key. + +```json +{ + "content": "optional friendly hey, i'm in charge", + "tags": [["e", , ]] +} +``` +Clients SHOULD ignore wrapped-kind 406 messages unless they are signed by the delegate in the associated 405 message +Clients SHOULD treat accepted delegates as the new owner of the group for all 404 and 405 messages. + +## NIP-10 relay recommendations + +For [NIP-10](10.md) relay recommendations on replies and on channel creation info, clients generally SHOULD use the relay URL where the event was first seen, if known. + + +Future extensibility +-------------------- + +We reserve wrapped-event kinds 407-419 for other events related to chat, to potentially include new types of media (photo/video), delegation, moderation, mute, hide, etc. + +Motivation +---------- +This is the easiest way to allow the use of group chat with select group of people, while hiding metadata. + +Optional Forward Secrecy +------------------------ + +Claims of "forward" secrecy in mobile applications can be disingenuous. Many mobile applications allow users to purchase a new phone and restore their account with historic messages intact - therefore this is not forward secrecy. + +True forward secrecy relies on servers reliably discarding the intermediate data - in addition to frequent key rotations, or prev-key ratcheting. A trusted server, for example, can be requested to discard old messages, by adding an optional NIP-40 expiration. + +### OPTIONAL forward secrecy extension + +The owner of a channel can add a "expiration" tag to the channel creation message. + +The owner of a channel who adds a "expiration" tag SHOULD issue a 404 message before the expiration. + +All members of a channel SHOULD also adding a NIP-40 "expiration" tag to all messages sent to the channel using the duration (`expiration - created_at`) of the wrapped-400 create. + +Members of a channel MUST NOT send new messages if a 404 message has not been received before expiration. + +Servers SHOULD obey NIP-40 expiration tags. + +Provided that servers obey NIP-40 expiration tags, this will prevent an attacker from reading old group messages before the expiration. + + +Drawbacks +--------- +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 "dox" other members by publishing their wrapped messages. + +Any member of the group can spam the group, or otherwise DOS the group. + +If any single participant of the group chat leaks the shared secret ( whether intentionally or by accident), all the messages can then be decrypted by others until the next 400 and 404 rotation events. + +The use of optional frequent forward secrecy rotation events can mitigate these attacks, provided the server is compliant with the expiration times, +