mirror of
https://github.com/nostr-protocol/nips.git
synced 2025-02-22 05:09:00 +00:00
bloom filter specs.
This commit is contained in:
parent
e146de7bbd
commit
4a980e0284
53
17.md
53
17.md
@ -104,14 +104,61 @@ Clients SHOULD publish kind `14` events to the `10050`-listed relays. If that is
|
||||
|
||||
A client MAY publish a kind `30010` which means saw messages with a `"d"` tag set to receivers pubkey.
|
||||
|
||||
The `.content` field is a base64 encoded string of a bloom filter containing message ids (gift wrapped) saw by receiver.
|
||||
The `.content` field has 4 sections separated by `:`:
|
||||
|
||||
1. The number of bits in the bit array,
|
||||
2. The number of hash rounds applied.
|
||||
3. The Base64 encoded string of a bloom filter containing message ids (gift wrapped) saw by receiver.
|
||||
4. The salt encoded in the Base64.
|
||||
|
||||
The sender pubkey's client MAY query that specific event to check which messaged in this chat is seen by receiver to enhance user experience.
|
||||
|
||||
Bloom filters MUST use `SHA256` functions applied to the concatenation of the key, salt, and index, as demonstrated in the pseudocode below:
|
||||
|
||||
```js
|
||||
class BloomFilter(size: Int, rounds: Int, buffer: ByteArray, salt: ByteArray) {
|
||||
val bits = BitArray(buffer)
|
||||
|
||||
fun bitIndex(value: ByteArray, index: Byte) {
|
||||
return BigInt(sha256(value || salt || index)) % size
|
||||
}
|
||||
|
||||
fun add(id: HexID) {
|
||||
val value = id.hexToByteArray()
|
||||
|
||||
for (index in 0 until rounds) {
|
||||
bits[bitIndex(value, index)] = true
|
||||
}
|
||||
}
|
||||
|
||||
fun mightContains(id: HexID): Boolean {
|
||||
val value = id.hexToByteArray()
|
||||
|
||||
for (index in 0 until rounds) {
|
||||
if (!bits[bitIndex(value, index)]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun encode() {
|
||||
return size + ":" + rounds + ":" + base64Encode(bits.toByteArray()) + ":" + base64Encode(salt)
|
||||
}
|
||||
|
||||
fun decode(str: String): BloomFilter {
|
||||
val [sizeStr, roundsStr, bufferB64, saltB64] = str.split(":")
|
||||
return BloomFilter(sizeStr.toInt(), roundsStr.toInt(), base64Decode(bufferB64), base64Decode(saltB64))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Example event:
|
||||
|
||||
```json
|
||||
{
|
||||
"pubkey" : "badbdda507572b397852048ea74f2ef3ad92b1aac07c3d4e1dec174e8cdc962a",
|
||||
"kind": 30010,
|
||||
"created_at": 1738964056,
|
||||
"tags": [
|
||||
@ -120,10 +167,12 @@ Example event:
|
||||
"bd4ae3e67e29964d494172261dc45395c89f6bd2e774642e366127171dfb81f5"
|
||||
]
|
||||
],
|
||||
"content": "AAAAAAAACJEAAAAAAAAAAQAAAAAAAAiRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"content": "100:10:AAAkAQANcYQFCQoB:hZkZYqqdxcE",
|
||||
}
|
||||
```
|
||||
|
||||
In this example the pubkey `badbdda507572b397852048ea74f2ef3ad92b1aac07c3d4e1dec174e8cdc962a`, has confirmed that they saw the messages with ids of `ca29c211f1c72d5b6622268ff43d2288ea2b2cb5b9aa196ff9f1704fc914b71b` and `460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c` from pubkey `bd4ae3e67e29964d494172261dc45395c89f6bd2e774642e366127171dfb81f5`.
|
||||
|
||||
A client MAY encrypt the `.content` based on [NIP-44](44.md) for more privacy.
|
||||
|
||||
## Relays
|
||||
|
Loading…
Reference in New Issue
Block a user