Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-1317: Secure Communication with Deniability #591

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions 1317.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
NIP-1317
======

Secure Communication with Deniability
------------------------


## Tag for the lifespan of an event
See [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md).

## Extend NIP-04 to enhance its randomness and forward secrecy
Introduce a new field **`prekey`** in the **`content`**: `"content": "<encrypted_text>?iv=<initialization_vector>&prekey=<public prekey, as a hex string>"`. Its format is the same as the public key of authentication.

If the sender supports this extension, it should randomly generate a secp256k1 key pair as an ephemeral key before sending each message. It should use the ephemeral private key with the recipient's long-term public key to generate a shared secret to encrypt the message. Then, it should fill in the ephemeral public key in the **prekey** field and upload it to the relay server together with the encrypted message body.

If the recipient supports this extension, it should first check whether the **prekey** field exists in the message. If it does, it should use it with its own long-term private key to generate a shared secret for decrypting the message body. Otherwise, it should use the sender's long-term public key and its own long-term private key.

## A deniable temporary identity exchange protocol
Because all event in the NIP-04 messaging protocol are signed by the sender/publisher, the protocol itself is undeniable. In order to implement deniable instant messaging based on Nostr, users can generate a new ephemeral key pair as a "temporary identity" specifically for instant messaging, even each time. The key pair used for posting content is the "permanent identity". However, which permanent identity a temporary identity belongs to should only be known by the communicating parties, and it can be deniable if the other party is treacherous. This requires the communicating parties to authenticate the temporary identities they are about to use with each other's permanent identities, but they cannot provide proof to third parties.

Let **G** represent the generator of the elliptic curve secp256k1, and if **k** is a private key, then **kG** is the corresponding public key.

When Alice, who holds the private key **a**, and has generated **a'**, wants to introduce her temporary identity **a'G** to Bob, who holds the private key **b**, for instant messaging, she first obtains Bob's public key **bG**, and then generates a message `msg(a)` with a content like: **`I am <aG> and I would like to use this temporary identity to communicate with you.`** This can be called a "secret conversation invitation". Using **a** and **bG** for DH to generate a shared secret **abG = a*bG**, Alice generates a message authentication code `mac(abG, msg(a))` for `msg(a)` and combines them into `<msg(a)>?mac=<mac(abG, msg(a))>` format. After encrypted via the aforementioned scheme, the message is sent to `bG` through `a'G`.

When Bob receives and decrypts the message, verifies it using **b** and **aG** for DH to generate a shared secret **abG = b*aG**, and decides to respond to Alice's request, he generates a private key **b'** for the temporary identity and generates a message `msg(b)` with a content like: **`I am <bG> and I will use this temporary identity to communicate with you.`** This can be called a "secret conversation invitation response". Using `abG` for `msg(b)`, Bob generates a message authentication code `mac(abG, msg(b))` and combines them into `<msg(b)>?mac=<mac(abG, msg(b))>` format. After encryption using the aforementioned scheme, the message is sent to **a'G** through **b'G**.

Alice receives and decrypts the message, verifies it using **abG**, and then both parties can use **a'G** and **b'G** for subsequent communication, possibly using more advanced "custom" protocol (see below). Other parties who cannot decrypt the message cannot determine the relationship between **a'G, b'G, aG, and bG**.

The deniability is reflected in the fact that only the communicating parties can calculate the shared secret **abG** through DH, so they can determine that the message is indeed from the other party, but they cannot prove this to a third party. If Bob intends to betray Alice, Alice can deny it by claiming that the mac `mac(abG, msg(a))` contained by the message claiming to be sent by Alice, is actually generated by Bob using his private key **b** and Alice's public key **aG** to generate the shared secret **abG** for "macking" to frame Alice, and vice versa. However, in order to use this protocol, it is necessary to ensure that the public keys of both parties have been published, and the permanent identity public key transmitted to the other party through the protocol cannot be the only source of the other party obtaining one's permanent identity public key, otherwise deniability will be compromised.

Another key point is that only temporary identities publish messages, while permanent identities do not send messages, do not sign, and do not create undeniable evidence.

The secret conversation invitation can have a lifespan of several hours set by [NIP-40](https://github.com/nostr-protocol/nips/blob/master/40.md) and can be explicitly deleted by using [NIP-09](https://github.com/nostr-protocol/nips/blob/master/09.md) before the inviter goes offline. The lifespan of the secret conversation invitation response can be shorter (such as 5 minutes) to avoid its continued effectiveness after the inviter goes offline.

## Extending NIP-04 to support "custom" encryption schemes
In this case, the content format is: **`"content": "<scheme hint>?<base64-encoded body>"`**, such as **`"content": "PGP?AAAABBBBCCCCDDDD..."`** or **`"content": "OTRv3?OTR:AAMDAABBCC..."`**. The scheme hint is used to prompt the client on how (with which protocol) to decrypt this message, and the specific implementation (e.g: [OpenPGP](https://www.openpgp.org/), [OTRv3](https://otr.cypherpunks.ca/Protocol-v3-4.1.1.html), Signal, OTRv4,[Vault1317](https://github.com/hardenedvault/vault1317), etc) depends on the client. If there is no scheme hint, then the message is considered to be in standard format or in the aforementioned extension of NIP-04.

The relay server should not impose any restrictions on forwarding messages to the recipient based on the format of content.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-78: Application-specific data](78.md)
- [NIP-89: Recommended Application Handlers](89.md)
- [NIP-94: File Metadata](94.md)
- [NIP-1317: NIP-1317: Secure Communication with Deniability](1317.md)

## Event Kinds

Expand Down