mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-11-13 23:39:08 -05:00
100 lines
3.6 KiB
Markdown
100 lines
3.6 KiB
Markdown
|
NIP-92
|
||
|
==========================
|
||
|
|
||
|
Rendezvous Beacons
|
||
|
------------------
|
||
|
`draft` `optional` `author:shafemtol`
|
||
|
|
||
|
A rendezvous beacon is used to anonymously deliver a secret event to a recipient
|
||
|
without prior communication between sender and recipient. Apart from its
|
||
|
timestamp, a rendezvous beacon is indistinguishable from any other rendezvous
|
||
|
beacon of the same kind on the same relay.
|
||
|
|
||
|
A stored rendezvous beacon has kind `9992`, while an ephemeral rendezvous beacon
|
||
|
has kind `29992`.
|
||
|
|
||
|
`pubkey` MUST be a unique public key with no publicly known relation to any
|
||
|
other event.
|
||
|
|
||
|
`content` MUST be the 8-character base64 encoded string of a 6-byte combined
|
||
|
hash/nonce, generated as described below.
|
||
|
|
||
|
For stored beacons, `tags` SHOULD contain a `NIP-40` `expiration` tag with a
|
||
|
value of `created_at` plus exactly `10000000` (ten million) seconds and no other
|
||
|
tags. It is not recommended to use stored rendezvous beacons on relays that do
|
||
|
not support `NIP-40`.
|
||
|
|
||
|
For ephemeral beacons, `tags` SHOULD be an empty list.
|
||
|
|
||
|
`created_at` SHOULD be approximately the time the event is submitted to the
|
||
|
relay.
|
||
|
|
||
|
|
||
|
Public User Metadata
|
||
|
--------------------
|
||
|
|
||
|
In order for the sender to know how to reach the recipient, the recipient needs
|
||
|
to publish some parameters in their `set_metadata` event, with the following
|
||
|
attribute:
|
||
|
|
||
|
`"bip92": [<subprefix>,<recipient_pubkey>,<relays>...]`
|
||
|
|
||
|
`<subprefix>` MUST be either an empty string or a single hexadecimal character.
|
||
|
In order to match the recipient's subscription filter, the `id` of the beacon
|
||
|
MUST have a prefix that matches `"0000" + <subprefix>`.
|
||
|
|
||
|
`<recipient_pubkey>` is the pubkey to use together with the key for the secret
|
||
|
beacon to derive a shared secret as described below.
|
||
|
|
||
|
`<relays>` are the remaining items in the list, specifying the relays where the
|
||
|
recipient expects to receive a beacon.
|
||
|
|
||
|
|
||
|
Beacon Generation
|
||
|
-----------------
|
||
|
|
||
|
- Generate a random keypair `a, A`.
|
||
|
- Derive the shared secret `S` as described below.
|
||
|
- Let `k = bytes(tagged_hash("NIP0092/beacon", bytes(x(S))))`.
|
||
|
- Let `i` be the 0-indexed position in `<relays>` where the secret event is to
|
||
|
be found.
|
||
|
- Let `d` be a random odd positive integer below `2³²`.
|
||
|
- For `j` in `0, 1, ...`:
|
||
|
- Let `p` be the 2-byte encoding of `i` followed by the 4-byte encoding of
|
||
|
`(j * d) mod 2³²`, each with the most significant byte first.
|
||
|
- Let `c` be the byte-wise `xor` of `p` and `k[0:6]`.
|
||
|
- Construct the beacon event, with `A` as the `pubkey` and `c` as the
|
||
|
`content`.
|
||
|
- If the resulting `id` matches the required prefix, break out of the loop.
|
||
|
- Sign the beacon event using `a` and deliver it to one of the relays listed in
|
||
|
`<relays>`.
|
||
|
|
||
|
|
||
|
Shared Secret Derivation
|
||
|
------------------------
|
||
|
|
||
|
Given the keypair `a, A` of the beacon (`A` being its `pubkey`) and the keypair
|
||
|
`b, B` of the recipient (`B` being their `recipient_pubkey`), the shared
|
||
|
secret is simply the point `S` resulting from ECDH operation, that is, `S =
|
||
|
a⋅B`, or equivalently, `S = b⋅A`. The shared secret is used in subsequent
|
||
|
derivations as `tagged_hash(tag, bytes(x(S)))`, with the functions as defined in
|
||
|
[BIP-340](https://bips.xyz/340).
|
||
|
|
||
|
|
||
|
Secret Event Delivery
|
||
|
---------------------
|
||
|
|
||
|
The secret event to be delivered to the recipient is given the rendezvous
|
||
|
keypair `r, R` (`R` being the `pubkey`), calculated as follows:
|
||
|
|
||
|
- `t = bytes(tagged_hash("NIP0092/tweak", bytes(x(S))))`
|
||
|
- `r = (a + t) mod n`
|
||
|
- `R = A + t⋅G`
|
||
|
|
||
|
The sender is able to derive `r` and uses this to construct and sign the secret
|
||
|
event.
|
||
|
|
||
|
From the beacon, the recipient derives the shared secret and is thus able to
|
||
|
learn `R`. The recipient uses `R` to find the secret event on the relay
|
||
|
indicated in the beacon.
|