mirror of
https://github.com/nostr-protocol/nips.git
synced 2024-12-23 00:45:53 -05:00
read permissions
This commit is contained in:
parent
37a02e817b
commit
a784792bb4
81
76.md
Normal file
81
76.md
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
NIP-76
|
||||||
|
======
|
||||||
|
|
||||||
|
Relay Read Permissions
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
`draft` `optional`
|
||||||
|
|
||||||
|
Tag names `rp` (read permission) and `prp` (probabilistic read permission) define which keys are authorized to download an event from the relay.
|
||||||
|
|
||||||
|
Events that include an `rp` or `prp` require AUTH to be downloaded.
|
||||||
|
|
||||||
|
## Read Permission
|
||||||
|
|
||||||
|
The `rp` tag accepts a list of pubkeys
|
||||||
|
|
||||||
|
```json
|
||||||
|
["rp", "<pubkey1>", "<pubkey2>", "<pubkey3>"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Relays MUST check if the authed user is one of the keys in the `rp` if present.
|
||||||
|
|
||||||
|
## Probabilistic Read Permissions
|
||||||
|
|
||||||
|
Bloom filters are bit arrays that encode keys `n` times. They are represented by a base64 encoded tag value with the `n` as the third element.
|
||||||
|
|
||||||
|
```json
|
||||||
|
["prp", "<bit size>:<rounds>:<base64>"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Bloom filters MUST use `SHA-256` functions of the key + iterating index as the psedocode below:
|
||||||
|
|
||||||
|
```js
|
||||||
|
class BloomFilter(size: Int, n: Int, buffer: ByteArray) {
|
||||||
|
val bits = BitArray(buffer)
|
||||||
|
|
||||||
|
fun bitIndex(value: ByteArray, index: Byte) {
|
||||||
|
return BigInt(sha256(value || index)) % size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun add(pubkey: HexKey) {
|
||||||
|
val value = pubkey.hexToByteArray()
|
||||||
|
|
||||||
|
for (index in 0..n) {
|
||||||
|
bits[bitIndex(value, index)] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mightContains(pubkey: HexKey): Boolean {
|
||||||
|
val value = pubkey.hexToByteArray()
|
||||||
|
|
||||||
|
for (index in 0..n) {
|
||||||
|
if (!bits[bitIndex(value, index)]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun encode() = size + ":" + rounds + ":" + base64Enc(bits.toByteArray()) // base64 might include extra 0 bits to fill the last byte
|
||||||
|
|
||||||
|
fun decode(str: String): BloomFilter {
|
||||||
|
val parts = str.split(":")
|
||||||
|
return BloomFilter(parts[0].toInt(), parts[1].toInt(), base64Decode(bits.toByteArray()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Relays MUST check if the authed user is in the filter before returning the event.
|
||||||
|
|
||||||
|
### Test cases
|
||||||
|
|
||||||
|
The filter below has 100 bits, with 10 rounds or hashes that should be able to match 10,000,000 keys without a single false positive.
|
||||||
|
|
||||||
|
```json
|
||||||
|
["prp", "100:10:QGKCgBEBAAhIAApO"]
|
||||||
|
```
|
||||||
|
|
||||||
|
It includes keys `ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b` and `460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c`
|
||||||
|
|
Loading…
Reference in New Issue
Block a user