hypercore-protocol / hypercore-next

Hypercore 10 is an append only log with multi-writer primitives built in.
MIT License
150 stars 15 forks source link

Implement optional encryption of Hypercores #51

Closed kasperisager closed 2 years ago

kasperisager commented 2 years ago

This PR introduces optional encryption of Hypercores by means of a new encryptionKey option in the Hypercore constructor. When an encryption key is supplied, every block written to the Hypercore is encrypted using the XSalsa20 cipher (https://doc.libsodium.org/advanced/stream_ciphers/xsalsa20) with a ~random~ 192 bit nonce ~that~ of which 64 bits is prepended to the block and the remaining bits inferred from the core. To account for the additional bytes prepended to every block, the ByteSeeker class can now be supplied with a padding argument so that Merkle tree seeks work as expected.

mafintosh commented 2 years ago

This looks GREAT! Good job @kasperisager

Some minor things:

  1. NONCEBYTES is how long the nonce should be, but it's actually not how much padding we need. The nonce is public and has no requirements other than "DO NOT EVER USE THE NAME NONCE TWICE". Your impl here works but we can make it more efficient by using only 8 bytes as padding to store the fork id .core.tree.fork (it's actually much smaller than 8 bytes, but it should have fixed size, so 8 is def more than enough, we can discuss if 4 bytes is fine also). With the stored fork id a valid nonce is fork-id + block-seq + zero-padding.
  2. We should have a mode, if forking is not enabled (currently it always is but we'll have an opt-in/out mode soon), where no padding is ever needed as fork-id is fixed so the nonce can just be 0 + block-seq + zero-padding.
mafintosh commented 2 years ago

Summoning @chm-diederichs in case I'm saying silly things

mafintosh commented 2 years ago

Looking really good, added some comments and will review the encryption itself next.

@kasperisager i think we should subarray the padding out also when blocks are emitted in the download event (also in index.js), wdyt?

mafintosh commented 2 years ago

10.0.0-alpha.7