2021-01-24 13:09:49 +03:00
|
|
|
/+ btc
|
2021-01-11 12:27:40 +03:00
|
|
|
|%
|
|
|
|
+$ bits [wid=@ dat=@ub]
|
|
|
|
++ params
|
|
|
|
|%
|
|
|
|
++ p 19
|
2021-01-22 20:10:47 +03:00
|
|
|
++ m 784.931
|
2021-01-11 12:27:40 +03:00
|
|
|
--
|
2021-01-24 13:09:49 +03:00
|
|
|
::
|
2021-01-22 11:59:38 +03:00
|
|
|
++ siphash
|
|
|
|
|= [k=byts m=byts]
|
|
|
|
^- byts
|
|
|
|
|^
|
|
|
|
?> =(wid.k 16)
|
|
|
|
?> (lte (met 3 dat.k) wid.k)
|
|
|
|
?> (lte (met 3 dat.m) wid.m)
|
|
|
|
=. k (flim:sha k)
|
|
|
|
=. m (flim:sha m)
|
|
|
|
(flim:sha (fin (comp m (init dat.k))))
|
|
|
|
:: Initialise internal state
|
|
|
|
::
|
|
|
|
++ init
|
|
|
|
|= k=@
|
|
|
|
^- [@ @ @ @]
|
|
|
|
=/ k0=@ (end [6 1] k)
|
|
|
|
=/ k1=@ (cut 6 [1 1] k)
|
|
|
|
:^ (mix k0 0x736f.6d65.7073.6575)
|
|
|
|
(mix k1 0x646f.7261.6e64.6f6d)
|
|
|
|
(mix k0 0x6c79.6765.6e65.7261)
|
|
|
|
(mix k1 0x7465.6462.7974.6573)
|
|
|
|
::
|
|
|
|
:: Compression rounds
|
|
|
|
++ comp
|
|
|
|
|= [m=byts v=[v0=@ v1=@ v2=@ v3=@]]
|
|
|
|
^- [@ @ @ @]
|
|
|
|
=/ len=@ud (div wid.m 8)
|
|
|
|
=/ last=@ (lsh [3 7] (mod wid.m 256))
|
|
|
|
=| i=@ud
|
|
|
|
=| w=@
|
|
|
|
|-
|
|
|
|
=. w (cut 6 [i 1] dat.m)
|
|
|
|
?: =(i len)
|
|
|
|
=. v3.v (mix v3.v (mix last w))
|
|
|
|
=. v (rnd (rnd v))
|
|
|
|
=. v0.v (mix v0.v (mix last w))
|
|
|
|
v
|
|
|
|
%= $
|
|
|
|
v =. v3.v (mix v3.v w)
|
|
|
|
=. v (rnd (rnd v))
|
|
|
|
=. v0.v (mix v0.v w)
|
|
|
|
v
|
|
|
|
i (add i 1)
|
|
|
|
==
|
|
|
|
::
|
|
|
|
:: Finalisation rounds
|
|
|
|
++ fin
|
|
|
|
|= v=[v0=@ v1=@ v2=@ v3=@]
|
|
|
|
^- byts
|
|
|
|
=. v2.v (mix v2.v 0xff)
|
|
|
|
=. v (rnd (rnd (rnd (rnd v))))
|
|
|
|
:- 8
|
|
|
|
:(mix v0.v v1.v v2.v v3.v)
|
|
|
|
::
|
|
|
|
:: Sipround
|
|
|
|
++ rnd
|
|
|
|
|= [v0=@ v1=@ v2=@ v3=@]
|
|
|
|
^- [@ @ @ @]
|
|
|
|
=. v0 (~(sum fe 6) v0 v1)
|
|
|
|
=. v2 (~(sum fe 6) v2 v3)
|
|
|
|
=. v1 (~(rol fe 6) 0 13 v1)
|
|
|
|
=. v3 (~(rol fe 6) 0 16 v3)
|
|
|
|
=. v1 (mix v1 v0)
|
|
|
|
=. v3 (mix v3 v2)
|
|
|
|
=. v0 (~(rol fe 6) 0 32 v0)
|
|
|
|
=. v2 (~(sum fe 6) v2 v1)
|
|
|
|
=. v0 (~(sum fe 6) v0 v3)
|
|
|
|
=. v1 (~(rol fe 6) 0 17 v1)
|
|
|
|
=. v3 (~(rol fe 6) 0 21 v3)
|
|
|
|
=. v1 (mix v1 v2)
|
|
|
|
=. v3 (mix v3 v0)
|
|
|
|
=. v2 (~(rol fe 6) 0 32 v2)
|
|
|
|
[v0 v1 v2 v3]
|
|
|
|
--
|
2021-01-11 13:12:14 +03:00
|
|
|
:: +str: bit streams
|
2021-01-11 15:08:05 +03:00
|
|
|
:: read is from the front
|
|
|
|
:: write appends to the back
|
2021-01-11 12:27:40 +03:00
|
|
|
::
|
2021-01-11 13:12:14 +03:00
|
|
|
++ str
|
2021-01-11 12:27:40 +03:00
|
|
|
|%
|
|
|
|
++ read-bit
|
|
|
|
|= s=bits
|
|
|
|
^- [bit=@ub rest=bits]
|
|
|
|
?> (gth wid.s 0)
|
|
|
|
:* ?:((gth wid.s (met 0 dat.s)) 0b0 0b1)
|
|
|
|
[(dec wid.s) (end [0 (dec wid.s)] dat.s)]
|
|
|
|
==
|
|
|
|
::
|
2021-01-11 13:12:14 +03:00
|
|
|
++ read-bits
|
|
|
|
|= [n=@ s=bits]
|
|
|
|
^- [bits rest=bits]
|
|
|
|
=| bs=bits
|
|
|
|
|-
|
|
|
|
?: =(n 0) [bs s]
|
|
|
|
=^ b s (read-bit s)
|
2021-01-11 15:08:05 +03:00
|
|
|
$(n (dec n), bs (write-bits bs [1 b]))
|
2021-01-11 13:12:14 +03:00
|
|
|
::
|
2021-01-11 15:08:05 +03:00
|
|
|
++ write-bits
|
|
|
|
|= [s1=bits s2=bits]
|
2021-01-11 12:27:40 +03:00
|
|
|
^- bits
|
2021-01-11 15:08:05 +03:00
|
|
|
[(add wid.s1 wid.s2) (can 0 ~[s2 s1])]
|
2021-01-11 12:27:40 +03:00
|
|
|
--
|
|
|
|
:: +gol: Golomb-Rice encoding/decoding
|
|
|
|
::
|
|
|
|
++ gol
|
|
|
|
|%
|
2021-01-11 15:08:05 +03:00
|
|
|
:: +en: encode x and append to end of s
|
2021-01-22 20:10:47 +03:00
|
|
|
:: - s: bits stream
|
|
|
|
:: - x: number to add to the stream
|
|
|
|
:: - p: golomb-rice p param
|
2021-01-11 15:08:05 +03:00
|
|
|
::
|
2021-01-11 12:27:40 +03:00
|
|
|
++ en
|
2021-01-11 15:08:05 +03:00
|
|
|
|= [s=bits x=@ p=@]
|
|
|
|
^- bits
|
|
|
|
=+ q=(rsh [0 p] x)
|
|
|
|
=+ unary=[+(q) (lsh [0 1] (dec (bex q)))]
|
|
|
|
=+ r=[p (end [0 p] x)]
|
|
|
|
%+ write-bits:str s
|
|
|
|
(write-bits:str unary r)
|
2021-01-11 12:27:40 +03:00
|
|
|
::
|
|
|
|
++ de
|
2021-01-11 13:12:14 +03:00
|
|
|
|= [s=bits p=@]
|
|
|
|
^- [delta=@ rest=bits]
|
2021-01-11 15:08:05 +03:00
|
|
|
|^ ?> (gth wid.s 0)
|
2021-01-11 13:12:14 +03:00
|
|
|
=^ q s (get-q s)
|
|
|
|
=^ r s (read-bits:str p s)
|
|
|
|
[(add dat.r (lsh [0 p] q)) s]
|
|
|
|
::
|
|
|
|
++ get-q
|
|
|
|
|= s=bits
|
|
|
|
=| q=@
|
|
|
|
=^ first-bit s (read-bit:str s)
|
|
|
|
|-
|
|
|
|
?: =(0 first-bit) [q s]
|
|
|
|
=^ b s (read-bit:str s)
|
|
|
|
$(first-bit b, q +(q))
|
|
|
|
--
|
2021-01-11 12:27:40 +03:00
|
|
|
--
|
2021-01-23 11:27:59 +03:00
|
|
|
:: +hsh
|
|
|
|
::
|
|
|
|
++ hsh
|
|
|
|
|%
|
|
|
|
:: +to-range
|
|
|
|
:: - item: scriptpubkey to hash
|
|
|
|
:: - f: N*M
|
|
|
|
:: - k: key for siphash (end of blockhash, reversed)
|
|
|
|
::
|
|
|
|
++ to-range
|
|
|
|
|= [item=byts f=@ k=byts]
|
|
|
|
^- @
|
|
|
|
(rsh [0 64] (mul f (swp 3 dat:(siphash k item))))
|
|
|
|
:: +set-construct: return sorted hashes of scriptpubkeys
|
|
|
|
::
|
|
|
|
++ set-construct
|
|
|
|
|= [items=(list byts) k=byts f=@]
|
|
|
|
^- (list @)
|
2021-01-23 12:51:46 +03:00
|
|
|
%+ sort
|
|
|
|
%+ turn items
|
|
|
|
|= item=byts
|
|
|
|
(to-range item f k)
|
|
|
|
lth
|
2021-01-23 11:27:59 +03:00
|
|
|
--
|
2021-01-23 12:38:40 +03:00
|
|
|
:: +get-n: get N from head of block filter, little endian
|
|
|
|
::
|
|
|
|
++ get-n
|
|
|
|
|= filter=@ux
|
2021-01-23 12:51:46 +03:00
|
|
|
^- @ux
|
2021-01-23 12:38:40 +03:00
|
|
|
=+ start=(dec (met 3 filter))
|
|
|
|
=/ n=@ux
|
|
|
|
(cut 3 [start 1] filter)
|
|
|
|
%+ swp 3
|
|
|
|
?: =(n 0xfd) (cut 3 [(sub start 2) 2] filter)
|
|
|
|
?: =(n 0xfe) (cut 3 [(sub start 4) 4] filter)
|
|
|
|
?: =(n 0xff) (cut 3 [(sub start 8) 8] filter)
|
|
|
|
n
|
2021-01-24 13:09:49 +03:00
|
|
|
::
|
2021-01-23 12:51:46 +03:00
|
|
|
++ parse-filter
|
|
|
|
|= [filter=@ux]
|
2021-01-23 13:52:30 +03:00
|
|
|
^- [n=@ux gcs-set=bits]
|
2021-01-23 12:51:46 +03:00
|
|
|
=+ n=(get-n filter)
|
|
|
|
=+ gcs-size=(sub (met 3 filter) (met 3 n))
|
2021-01-23 13:52:30 +03:00
|
|
|
[n [(mul 8 gcs-size) `@ub`(end [3 gcs-size] filter)]]
|
2021-01-24 13:09:49 +03:00
|
|
|
:: +to-key: blockhash (little endian) to key for siphash
|
|
|
|
::
|
|
|
|
++ to-key
|
|
|
|
|= blockhash=tape
|
|
|
|
^- byts
|
|
|
|
%+ take:byt:btc 16
|
|
|
|
%- flip:byt:btc
|
|
|
|
[32 (to-hex:btc (crip blockhash))]
|
2021-01-23 13:52:30 +03:00
|
|
|
:: +match: whether block filter matches *any* target scriptpubkeys
|
|
|
|
:: - filter: full block filter, with leading N
|
2021-01-23 11:27:59 +03:00
|
|
|
:: - k: key for siphash (end of blockhash, reversed)
|
2021-01-23 13:52:30 +03:00
|
|
|
:: - targets: scriptpubkeys to match
|
2021-01-23 11:27:59 +03:00
|
|
|
::
|
|
|
|
++ match
|
2021-01-23 13:52:30 +03:00
|
|
|
|= [filter=@ux k=byts targets=(list byts)]
|
|
|
|
^- ?
|
|
|
|
=/ [p=@ m=@] [p:params m:params]
|
|
|
|
=/ [n=@ux gcs-set=bits] (parse-filter filter)
|
2021-01-23 11:27:59 +03:00
|
|
|
=+ target-hs=(set-construct:hsh targets k (mul n m))
|
2021-01-24 13:09:49 +03:00
|
|
|
=+ last-val=0
|
2021-01-23 13:52:30 +03:00
|
|
|
|-
|
|
|
|
?: (lth wid.gcs-set p) %.n
|
2021-01-24 13:09:49 +03:00
|
|
|
?~ target-hs %.n
|
|
|
|
=^ delta gcs-set
|
|
|
|
(de:gol gcs-set p)
|
|
|
|
=. last-val
|
|
|
|
(add delta last-val)
|
|
|
|
?: =(last-val i.target-hs)
|
|
|
|
%.y
|
|
|
|
?: (lth last-val i.target-hs)
|
|
|
|
$
|
|
|
|
$(target-hs t.target-hs)
|
|
|
|
:: +all-match: returns all target byts that match
|
|
|
|
:: - filter: full block filter, with leading N
|
|
|
|
:: - k: key for siphash (end of blockhash, reversed)
|
|
|
|
:: - targets: scriptpubkeys to match
|
|
|
|
::
|
|
|
|
++ all-match
|
|
|
|
|= [filter=@ux k=byts targets=(list byts)]
|
|
|
|
^- (list byts)
|
|
|
|
=/ [p=@ m=@] [p:params m:params]
|
|
|
|
=/ [n=@ux gcs-set=bits] (parse-filter filter)
|
|
|
|
=/ target-map=(map @ byts)
|
|
|
|
%- ~(gas by *(map @ byts))
|
|
|
|
%+ turn targets
|
|
|
|
|=(t=byts [(to-range:hsh t (mul n m) k) t])
|
|
|
|
=+ target-hs=~(tap in ~(key by target-map))
|
|
|
|
=+ last-val=0
|
|
|
|
=| matches=(list @)
|
|
|
|
|-
|
|
|
|
?: (lth wid.gcs-set p)
|
|
|
|
(murn matches ~(get by target-map))
|
|
|
|
?~ target-hs
|
|
|
|
(murn matches ~(get by target-map))
|
2021-01-23 13:52:30 +03:00
|
|
|
=^ delta gcs-set
|
|
|
|
(de:gol gcs-set p)
|
2021-01-24 13:09:49 +03:00
|
|
|
=. last-val
|
|
|
|
(add delta last-val)
|
|
|
|
?: =(last-val i.target-hs)
|
|
|
|
%= $
|
|
|
|
target-hs t.target-hs
|
|
|
|
matches [last-val matches]
|
|
|
|
==
|
|
|
|
?: (lth last-val i.target-hs)
|
|
|
|
$
|
|
|
|
$(target-hs t.target-hs)
|
2021-01-23 12:38:40 +03:00
|
|
|
--
|