feat(fula-crypto/js): A6b Method-2 recipient bindings (unwrap + owner-file decrypt) — 0.6.19#87
Merged
Merged
Conversation
…rypt cores Method-2 RECIPIENT counterparts to wrap_secret_for_recipient (#86) so the hosted Worker (wasm) can consume a collaboration share without re-implementing fula:v4 crypto in TS. Thin compositions of ShareRecipient::accept_share + Aead + ChunkedDecoder (no new crypto): unwrap_secret_for_recipient (recover the exact 32-byte link secret), describe_shared_file (non-secret framing), decrypt_shared_file_single_block/_chunked (owner encType:fula decrypt, byte-mirroring the native read path; fail-closed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tSharedFile* wasm bindings Method-2 recipient wasm bindings (sibling of wrapSecretForRecipient). Each delegates to the shared fula_crypto::sharing core; fail-closed on bad key length, malformed/expired/tampered/non-addressed token, single-vs-chunked mismatch, or a non-Uint8Array chunk element. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…drift gate Known-answer tests (fixed vectors, fail-closed coverage) + a no-drift cross-check asserting the native read.rs cores and the shared fula_crypto::sharing cores are byte-identical. Per advisor review (GLM F1/F2) the cross-check covers all 3 version arms (Some>=4 / Some<4 / None) and the KAT adds version-downgrade rejection (encryption_version is in the v5 AAD), empty-plaintext, and single-chunk cases. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Releases the Method-2 recipient bindings (unwrapSecretForRecipient + owner-file decrypt) for the hosted Worker. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Method-2 RECIPIENT-side bindings so the hosted Cloudflare Worker (wasm) can consume a collaboration share without re-implementing any
fula:v4crypto in TypeScript. Sibling of #86'swrap_secret_for_recipientproducer.fula-crypto (
sharing.rs) — thin compositions of existing primitives (ShareRecipient::accept_share,Aead,ChunkedDecoder), no new crypto:unwrap_secret_for_recipient→ recover the exact 32-byte group link secretdescribe_shared_file→ non-secret framing{chunked, num_chunks, encryption_version}decrypt_shared_file_single_block/_chunked→ owner (encType:fula) decrypt, byte-mirroring the native MCP read path (AADfula:v4:content:{key}/ per-chunkfula:v4:chunk:{key}:{i}, share nonce, version-gate tristate)fula-js (
lib.rs) — the 4 wasm bindings (unwrapSecretForRecipient,describeSharedFile,decryptSharedFileSingleBlock,decryptSharedFileChunked), all fail-closed.read.rs — production read path is UNCHANGED; only a
#[cfg(test)]no-drift cross-check was added (native cores vs shared cores must stay byte-identical).Version bumped 0.6.18 → 0.6.19 (workspace-wide).
Why
The local MCP uses native fula-crypto, but the hosted Worker (wasm) had no way to unwrap a v5
ShareToken→ it was fail-closed (rejecting the production token shape). These bindings unblock the Worker (#70).Verification
cargo test -p fula-mcp: 84 lib + 9 KAT pass, incl. the no-drift cross-check (now covering all 3 version armsSome(≥4)/Some(<4)/None) and the new KATs.cargo check -p fula-js --target wasm32-unknown-unknown: clean.cargo check -p fula-flutter: clean (Send+Sync gate).Review gate
Crypto change reviewed on the actual diff by GLM-5.2 + MiMo v2.5 Pro + built-in advisor → unanimous SHIP, zero security / fail-open findings (every fail-closed path verified: key length, recipient binding, tamper, expiry, single-vs-chunked routing, nonce, wasm conversion). Kimi/Codex/Cursor were quota-exhausted today (noted; resets not waitable).
Test-coverage findings (GLM F1/F2) were applied post-review (test-only): the 3-arm no-drift cross-check + KATs for version-downgrade rejection (empirically proving
encryption_versionis bound in the v5 AAD), empty-plaintext, and single-chunk.Follow-up (tracked, non-blocking)
read.rsto call the sharedsharing::decrypt_accepted_single_block/assemble_accepted_chunkedand delete the private copies (the no-drift cross-check now fully covers the arms, so this is safe to defer).num_chunksat the Worker fetch layer (a pathological — but authenticated — token could drive a large fetch loop; native has the same property).🤖 Generated with Claude Code