feat: group file envelope encryption - #891
Open
dastansam wants to merge 4 commits into
Open
Conversation
dastansam
marked this pull request as ready for review
June 20, 2026 16:38
dastansam
force-pushed
the
feat/group-file-envelope-encryption
branch
from
June 20, 2026 17:51
0b7ebf4 to
1e84d0d
Compare
Per-file random symmetric key + one ciphertext body for the whole group, with the file key distributed to each member via the existing per-peer session (envelope / hybrid encryption). Cuts group file send cost from O(members × file_size) to O(file_size) + O(members × 32 bytes). Covers: file-side encryption (ChaCha20-Poly1305 body, BLAKE3 digest binding), FileKeyEnvelope delivery over CryptoService, receiver envelope/body matching, membership edges (late joiners via rate-limited key relay, removed members), protobuf shape, file_keys sled tree, GroupFiles config, capability negotiation with per-send fallback, risks, rollback, and a decision gate. Supersedes the earlier draft on docs/group-file-encryption-fanout (docs/proposals/Group-File-Encryption-Fanout.md).
First slice of envelope (hybrid) encryption for group files (docs/proposals/Efficient-Group-File-Encryption.md): encrypt the body once under a random per-file key and distribute that key per-member, instead of encrypting the whole file once per recipient. - Wire: FileKeyEnvelope + FileKeyRelayRequest added to CryptoserviceContainer (crypto_net.proto); regenerated. file_id kept as uint64 to match the existing file infrastructure. - Crypto primitives: services/chat/file_envelope.rs — generate_file_key (32 random bytes), encrypt_body/decrypt_body (reuse Noise ChaCha20-Poly1305 CipherState; fixed nonce is safe since the key is fresh per file), body_digest (SHA-256, binds envelope to body). 5 unit tests (round-trip, wrong key, tamper, digest binding, key uniqueness). - Config: GroupFiles section (envelope_enabled default false, allow_key_relay, envelope_ttl_seconds=30d, max_relay_requests_per_minute), serde(default) + upgrade path. - sessionmanager: placeholder receive arms for the new variants. Builds clean, libqaul tests pass. Follow-ups (next slices): file_keys sled tree; sender path in services/chat/file.rs (encrypt body once + fan out envelopes); a sign-only body distribution path so the body isn't re-encrypted per member; receiver envelope<->body matching + digest verify; key relay for late joiners. Capability-based per-member downgrade is deferred — it needs the Capabilities bitset infra that currently lives only on the crypto-session-rotation branch.
Add a per-account `file_keys` sled tree (on UserFiles) keyed by file_id, holding `FileKey` entries — received envelope keys awaiting their body and locally generated keys for sent files that may need relay. Includes save/get/delete plus TTL-based prune (GroupFiles.envelope_ttl_seconds), wired through all UserFiles construction sites incl. the graceful tree-open fallbacks. delete zeroizes via drop. 2 unit tests (save/get/delete round-trip, prune-only-expired). Builds clean; libqaul tests pass.
…t working]
Integrates the envelope path end-to-end (structurally): sender encrypts
the body once and distributes it via a new signed-but-not-encrypted
"plain" messaging payload, plus fans out the per-file key to each member.
- messaging: EnvelopPayload::Plain variant (proto) + pack_and_send_plain_data
+ receive routing through on_decrypted_message (signature still verified).
- chatfile: ChatFileInfo.body_digest marks envelope mode + binds the body.
- sender: ChatFile::send_envelope (gated on GroupFiles.envelope_enabled) —
encrypt body once, store FileKey locally, send FileInfo+body chunks via
the plain path, fan out FileKeyEnvelope per member over the per-peer
session; Group::send_to_remote_members_plain.
- receiver: process_file_key_envelope stores the key + retries assembly;
store_file is envelope-aware (reassemble body_ct, verify SHA-256 digest,
decrypt with the file key, write plaintext). FileHistory.body_digest
remembers envelope mode across chunk arrivals.
- CryptoSessionManager::create_file_key_envelope_message + receive arm.
Builds clean; libqaul unit tests pass (incl. the earlier envelope crypto
+ file_keys tests). Fixed an off-by-one (envelope message_count must use
the legacy "actual+1" convention the receiver's completion check expects).
KNOWN-NOT-WORKING (live 2-node test): the encrypted FileKeyEnvelope
reaches the receiver, but the plain body messages do not reach the
receiver's file handler (0 chunks saved), so the file never assembles.
Also: confirmations for plain/crypto control messages fail before a Noise
session exists on first contact ("Can't send further messages after
handshake"). Both need debugging next:
- why the EnvelopPayload::Plain body isn't dispatched on the receiver
(encrypted path works; plain doesn't) — likely send/schedule or the
CommonMessage are_members gate on the direct group.
- confirmation path should tolerate "no session yet" (queue/retry).
dastansam
force-pushed
the
feat/group-file-envelope-encryption
branch
from
July 24, 2026 05:41
1e84d0d to
4049180
Compare
|
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.



No description provided.