ssbc / ssb-db2

A new database for secure-scuttlebutt
47 stars 8 forks source link

Optimize box2 decryption for multiple recps #346

Closed arj03 closed 2 years ago

arj03 commented 2 years ago

We need to figure out why box2 decryption is around 3 times slower than box1. See https://github.com/ssbc/ssb-db2/pull/342#issuecomment-1125980482

arj03 commented 2 years ago

Seems like @staltz solved this one :accordion: :smile:

arj03 commented 2 years ago

Nope ;)

staltz commented 2 years ago

Could we make a simple benchmark where we use private-box directly and envelope-js directly, and check what is the performance of decrypting 10000 ciphertexts? This could give us a baseline of the cost of running the cryptography for box1 and box2, independently from any ssb or database architecture.

arj03 commented 2 years ago

IIIRC the last time I looked at this it was something to do with the way the key in box2 is dependent on the previous message. The new benchmark with groups will bring a fresh perspective, so I'll give this a go again :)

arj03 commented 2 years ago

I discovered that the performance difference is mainly related to the number of recipients, if you lower that down to 1, then box1 and box2 are very close.

The difference with multiple recipients being:

box1: simple loop:

https://github.com/auditdrivencrypto/private-box/blob/ffe1e4a8a35959f64c9586ea69940b47d49dafa3/index.js#L48

box2: loop with multiple steps

https://github.com/ssbc/envelope-js/blob/2920b2e5892191ac35bae5693e0a37b35b2dbe34/unbox.js#L47

where:

unslot = copy trial keys into msg_key, xor with key slot derive = hkdf.expand

Some numbers:

# box1 (6 recps)
ok 9 unbox 1000 box1 msgs first run: 184.49ms
ok 10 unbox 1000 box1 msgs second run: 98.61ms
# private box2 (6 recps)
ok 15 unbox 1000 box2 msgs first run: 301.22ms
ok 16 unbox 1000 box2 msgs second run: 228.42ms
# private box2 group keys (1 key)
ok 19 unbox 1000 box2 group msgs first run: 228.74ms
ok 20 unbox 1000 box2 group msgs second run: 106.67ms

----

# box1 (1 recps)
ok 9 unbox 1000 box1 msgs first run: 177.77ms
ok 10 unbox 1000 box1 msgs second run: 90.78ms
# private box2 (1 recps)
ok 15 unbox 1000 box2 msgs first run: 180.65ms
ok 16 unbox 1000 box2 msgs second run: 94.69ms
# private box2 group keys (1 key)
ok 19 unbox 1000 box2 group msgs first run: 247.77ms
ok 20 unbox 1000 box2 group msgs second run: 114.02ms

I found that slp encode used in box2 could be optimized, with that box2 is even a tiny bit faster for 1 recipient :)

And for 6 recipients:

# box1
ok 8 add 1000 box1 msgs: 1240.37ms
ok 9 unbox 1000 box1 msgs first run: 189.28ms
ok 10 unbox 1000 box1 msgs second run: 104.36ms
# private box2
ok 14 add 1000 box2 msgs: 460.47ms
ok 15 unbox 1000 box2 msgs first run: 290.87ms
ok 16 unbox 1000 box2 msgs second run: 201.31ms
arj03 commented 2 years ago

Also one last thing, the reason why groups is slower than DM on a single author is that it has 30% can decrypt. If you lower that to 0% then the numbers are more or less the same as they should be.