read permissions

This commit is contained in:
Vitor Pamplona 2024-09-13 12:56:50 -04:00
parent 37a02e817b
commit a784792bb4

81
76.md Normal file
View 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`