diff options
Diffstat (limited to 'docs/MESHBAY_DESIGN.md')
| -rw-r--r-- | docs/MESHBAY_DESIGN.md | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/docs/MESHBAY_DESIGN.md b/docs/MESHBAY_DESIGN.md index 74c1050..23c587e 100644 --- a/docs/MESHBAY_DESIGN.md +++ b/docs/MESHBAY_DESIGN.md @@ -638,17 +638,17 @@ Every private key lives in an encrypted keystore on the machine that owns it. Th hub never sees one. **Domain separation is consistent and mandatory.** Every derivation uses a -distinct `info` string, and the AES variant adds an `:aes` suffix so two ciphers -can never derive the same key from one group key. This is a small detail that -prevents cross-protocol key reuse, and it is checked rather than assumed. +distinct `info` string, so no two purposes can derive the same key from one group +key. The chunk and wrap strings end in `:aes`, left from a second cipher that no +longer exists; it stays because it is part of every key already derived. ### 4.2 Group key wrapping (ECIES) ``` wrap: sk_eph, pk_eph = X25519.generate() # fresh per bundle shared = X25519(sk_eph, pk_recipient) - wrap_key = HKDF(shared, salt=pk_eph, info="meshbay:gek_wrap:v1", len=32) - wrapped = AEAD(wrap_key).encrypt(nonce, gek, aad=pk_recipient) + wrap_key = HKDF(shared, salt=pk_eph, info="meshbay:gek_wrap:v1:aes", len=32) + wrapped = AES-256-GCM(wrap_key).encrypt(nonce, gek, aad=pk_recipient) bundle = pk_eph ‖ nonce ‖ wrapped unwrap: shared = X25519(sk_recipient, pk_eph) # same derivation @@ -678,20 +678,19 @@ time. This avoids double storage and makes key rotation feasible without re-encrypting terabytes. ``` -disk (plaintext) → compress → per-chunk AEAD under a group-derived key → transport → client +disk (plaintext) → per-chunk AES-256-GCM under a group-derived key → transport → client ``` - Chunk size 1 MB: amortises AEAD overhead and enables seeking, because each chunk is independently decryptable. -- `chunk_key = HKDF(GEK, salt=None, info="file:" ‖ blake3(file) ‖ ":chunk:" ‖ index)`. +- `chunk_key = HKDF(GEK, salt=None, info="file:" ‖ blake3(file) ‖ ":chunk:" ‖ index ‖ ":aes")`. The salt is omitted deliberately: the group key is CSPRNG output and already uniform, so the file and chunk context belongs in `info`, which is the correct HKDF usage (**M5**, first review). - **Chunk authentication is the AEAD tag**, not a per-chunk signature. The tag authenticates the ciphertext under a key only members hold, which is what the signature was for. -- Compression precedes encryption, because compression is ineffective on - ciphertext. +- **Chunks are not compressed**: a chunk is encrypted and sent as it was read. - Upload chunk size is 48 KB, which is what fits the SCTP limit after msgpack overhead. |