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

First Draft of Proposed NIP-76: Trace Resistant Private Posts #260

Closed
wants to merge 1 commit into from
Closed
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
85 changes: 85 additions & 0 deletions 76.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
NIP-76
======

Trace Resistant Private Posts
-------------------------------

`draft` `optional` `author:d-krause`

Given the privacy concerns detailed in [A Cypherpunk's Manifesto](https://nakamotoinstitute.org/cypherpunk-manifesto/), additional measures can be taken in the NOSTR protocol to further maintain the privacy of NOSTR users when they desire it. This NIP defines a protocol that can be implemented by conforming relays and clients to maximize the privacy of a user's posts.

## Goal
The goal of NIP-76 is to provide a way for users to share private data while also making it very difficult for governments or other third parties to scan content to identify posters and subscribers of the content. The third party "needing" this information must start with identifying the targeted entity **first**, *and only then* can they begin to work on obtaining access to their NOSTR private contents.

## Two BIP-32 Extended Private Keys Required
Given a user's private key and 32 byte chain code, the user can generate an infinite supply of keys (see [BIP-32](https://bips.xyz/32])). In addition to the user's private profile key (`nsec`), NIP-76 requires two additional private extended keys, which we will call `addressesPrivateExtended`(a-prvx) and `secretsPrivateExtended`(s-prvx).

[NIP-06](06.md) defines one manner in which the user's profile private key can be generated. Using this method, the client application could derive apx and spx as descendents of the profile key (`m/44'/1237'/0'/0/0`). For users that were not created with NIP-06, a random 32 byte chain code can be generated and stored by the client, and apx and spx can be derived from the resulting master private key.

## Post Event

The TRPP post is different from the Text Note event (`kind: 1`) in the following ways:
1. The is event `kind` is `17761`.
1. The `pubkey` is the derived pubkey from the `a-pubx/${index}` where index starts with 1 for the first post and increments + 1 for each successive post. (`a-pubx/0` is reserved for profile feed metadata.)
1. The event `content` is encrypted with `sha256(s-pubx/${index})` and is stored as a base64 string
1. The `sig` is computed the same, only the `a-prvx/${index}` for signing.

## Event Storage Examples
Consider 3 users: Alice, Bob, and Charlie with the following key information, with only the pubkey stored in a relay:
| User | Pub Key | Address Extended Key | Secrets Extended Key
| --- | ----------- | ----------- | ----------- |
| Alice | A100...10A5 |**private:** aprvkd9fy7...98wfuwhec9h **public:** apub1r378f...7dsf38defs92|**private:** aprvks8jf7...9sh3lfu37d1 **public:** apuby2hd3p...mc73hf68s86s
| Bob | B200...F35C |**private:** aprvk4h8s7...6dsy3tab2yh **public:** apub2pc8t3...xv43m8d66dj|**private:** aprvbz75ak...pmn723n829 **public:** apubdsg5a76...88dutet577s
| Charlie | C300...19E4 |**private:** aprv987h7us...paw2pswee55e **public:** apubk22j8d6...pqww2ee4r56|**private:** aprvdg66d4...dfsg6ayyt5ts **public:** apubncs63ge5...re4s5d6s62f

If Bob and Charlie wish to follow Alice's Private Posts, they would exchange address and secrets extended **public** keys.

If Alice made 3 private posts in her timeline, all with the same content of "Hello World!", they would appear in the relay something like below (*`created_at` and `sig` ommitted from the samples for brevity*):
```json
{
"kind": 17761
"id": "01128889c6b6214981aa3c8cf812c82ecab4e64ab4b5e80f3bf78f59702710a5",
"pubkey": "3f22b2c92609f66d998d0f58907cf035f9fb9b9111e86c3fba4b11650424d1a8",
"content":"m0CPGvN59oWddLn4vYSne/kzt1oV0al8wJKj3bxIbqr6H0++VIFomqCC"
}
```

```json
{
"kind": 17761
"id": "cd142288be41c69f42c963248c7cb33ee2c5a9fdec590d714f3a200869c2d9d1",
"pubkey": "1d4be0bc944196f6f2b4a552e2b3e2c18f62fa5dfc429511bb6a07a8638a587a",
"content":"Im15XqMUqQvnpgRqGGskUtAlhuwQrZom2x7WO1JtkNzJ/BpJrhWZ3jFF"
}
```
```json
{
"kind": 17761
"id": "1a8e8398580a2501b1cf4fdc0ba8bd70e93aeab49b41aa6a404e5c13b0884850",
"pubkey": "42ef3b0d118bef0b261b9e2ca8a77e997e91e160e951ced05eeee74853f3c500",
"content":"qP6oks7xkXSsYAUi+Y8JF3gXTejxkjxwXW0sWtARdRoBVZfM6nUumeLA"
}
```
Thus, all of the content for Alice's post appear with a different pubkey, and encrypted with a different secret key, making it computationally unfeasible to identify what is in the posts or who created them without first having access to Alice's extended public addressing and secret keys.

This prevents, or at least severely hinders, the ability for governments, corporations, and other third parties from scanning content, then identifying the users based on the content. One must know the user first, get permission to see the content, either from the user directly or via a legal action that compels the disclosure of the user's keys.



## Communication between clients and relays

Relays expose a websocket endpoint to which clients can connect. The relay communication of NIP-76 is the same as [NIP-01](01.md), with the addition of a new field `addresses` add to the subscription filters parameter.

```json
{
"kinds": [17761],
"addresses": <a list of address extended public keys (a-pubx) used to derive the pubkey tag>,
}
```
Upon receiving a `REQ` message, the relay SHOULD query its internal database and return events that match the filter by searching for children address starting at index 0 that have events with a pubkey equal to the `a-pubx/0..n`, until n reaches a point where no more events are returned.


Additional info
---------------

- [Proof of Concept (without NOSTR)](https://animiq.com)
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ NIPs stand for **Nostr Implementation Possibilities**. They exist to document wh
- [NIP-56: Reporting](56.md)
- [NIP-57: Lightning Zaps](57.md)
- [NIP-65: Relay List Metadata](65.md)
- [NIP-76: Trace Resistant Private Posts](76.md)

## Event Kinds
| kind | description | NIP |
Expand Down