Skip to content

perf(upload): derive v4 filename-metadata Argon2id via libsodium (~15x faster) - #2

Merged
chogarcia merged 1 commit into
mainfrom
perf/argon2id-libsodium-metadata
Jul 3, 2026
Merged

perf(upload): derive v4 filename-metadata Argon2id via libsodium (~15x faster)#2
chogarcia merged 1 commit into
mainfrom
perf/argon2id-libsodium-metadata

Conversation

@chogarcia

Copy link
Copy Markdown
Contributor

encryptMetadataV4 derived its per-file metadata key with @noble pure-JS Argon2id at interactive params (t=2, m=64 MiB) — ~1.1 s per file, once per file, so sf sync / sf push over many small files was KDF-bound (all that time before any bytes move).

Switch the encrypt side to libsodium crypto_pwhash (ARGON2ID13, opslimit=2, memlimit=64 MiB), which is byte-identical to @noble at these params (verified here for both interactive and moderate) but ~15× faster (~74 ms).

  • The v4 envelope (v/ct/iv/tag/salt/kdf) is unchanged → filenames still decrypt on web + mobile and are indistinguishable on the wire. No server change, no migration, no stored-data touch.
  • decryptMetadataV4 stays on @noble — off the upload hot path, and keeping a second independent Argon2id implementation guards reads against a libsodium regression.
  • libsodium-wrappers-sumo is already a dependency and already initialised in the unlock path — no new dep.
  • encryptMetadataV4 becomes async (libsodium ready gate); its only caller createUploadSession is already async.

Verify: the metadata round-trip test now encrypts with libsodium and decrypts with @noble (proving the backends agree byte-for-byte), plus a new test reconstructs a legacy @noble-produced envelope and asserts it still decrypts. 36/36 pass.

Independent of PR #1 (WebCrypto chunk encryption + part retry) — different function, no conflict.

…x faster)

encryptMetadataV4 derived its per-file metadata key with @noble pure-JS
argon2id at interactive params (t=2, m=64 MiB) — ~1.1 s per file, once per
file, so `sf sync`/`sf push` over many small files was KDF-bound. Switch the
ENCRYPT side to libsodium crypto_pwhash (ARGON2ID13, opslimit=2, memlimit=64
MiB), which is byte-identical to @noble at these params (verified for both
interactive and moderate) but ~15x faster (~74 ms).

The v4 envelope (v/ct/iv/tag/salt/kdf) is unchanged, so filenames still decrypt
on the web and mobile clients and are indistinguishable on the wire — no server
change, no migration. decryptMetadataV4 stays on @noble: it is off the upload
hot path and keeping a second independent Argon2id implementation guards reads
against a libsodium regression. libsodium-wrappers-sumo is already a dependency
and already initialised in the unlock path.

encryptMetadataV4 becomes async (libsodium ready gate); its only caller,
createUploadSession, is already async.

Tests: the metadata round-trip now encrypts with libsodium and decrypts with
@noble (proving the backends agree), plus a new test reconstructs a legacy
@noble-produced envelope and asserts it still decrypts. 36/36 pass.
@chogarcia
chogarcia merged commit e0b6fd1 into main Jul 3, 2026
1 check passed
@chogarcia
chogarcia deleted the perf/argon2id-libsodium-metadata branch July 3, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant