From 867d2d9788339bf06b3ed4e4f7ff9e0ac4897d87 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sun, 3 Nov 2024 16:49:02 -0300 Subject: [PATCH] nip45: negate pow attacks on hyperloglog using a stupid hack. --- 45.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/45.md b/45.md index ea0b7f5..f6ecbee 100644 --- a/45.md +++ b/45.md @@ -41,13 +41,14 @@ This is so it enables merging results from multiple relays and yielding a reason ### Algorithm -The HLL value must be calculated with a precision of `8`, i.e. with 256 registers. +This section describes the steps a relay should take in order to return HLL values to clients. -To compute HLL values, first initi the 256 registers to `0` each; then, for on every event to be counted, - - 1. take byte `16` of the `id` and use it to determine the register index; - 2. count the number of leading zero bits in the following bytes `17..24` of the `id`; - 3. if the number of leading zeros is bigger than what was previously stored in that register, overwrite it. +1. Upon receiving a filter, if it has a single `#e`, `#p`, `#a` or `#q` item, read its 32th ascii character as a byte and take its modulo over 24 to obtain an `offset` -- in the unlikely case that the filter doesn't meet these conditions, set `offset` to the number 16; +2. Initialize 256 registers to 0 for the HLL value; +3. For all the events that are to be counted according to the filter, do this: + 1. Read byte at position `offset` of the event `pubkey`, its value will be the register index `ri`; + 2. Count the number of leading zero bits starting at position `offset+1` of the event `pubkey`; + 3. Compare that with the value stored at register `ri`, if the new number is bigger, store it. That is all that has to be done on the relay side, and therefore the only part needed for interoperability.