[Code Review] XChaCha20-Poly1305 + Ed25519 sync protocol — correct crypto usage?
⚓ Rust 📅 2026-02-23 👤 surdeus 👁️ 5[Code Review] SYNC-0: XChaCha20-Poly1305 + Ed25519 pack/grant protocol — looking for feedback on crypto usage
Hi,
I'm building a local-first medical scheduling app (PraxisTools) with an end-to-end encrypted folder-based sync protocol (no server, iCloud/Dropbox as untrusted transport).
I'd appreciate a review of my crypto usage — specifically whether I'm using XChaCha20-Poly1305, Ed25519 and BLAKE3 correctly and securely.
What the protocol does:
- Devices pair offline via signed
.ptgrantfiles (Ed25519, sealed group key via X25519) - Each device writes encrypted packs (XChaCha20-Poly1305) with device signature over (header || ciphertext || tag)
- Header is AAD, includes
msg_typefor domain separation - Nonces are random (OsRng), stored in pack header, no reuse via durable draft + atomic rename
- BLAKE3 for pack_hash and chain integrity
- Checkpoints are ADMIN-only, same crypto pattern
Crates used:
ed25519-dalek,x25519-dalek,chacha20poly1305,blake3,zeroize
What I want reviewed (not the full codebase):
- Is my AAD construction correct? (header_jcs as AAD)
- Is domain separation via
msg_typein JCS header sufficient? - Any nonce-reuse risk I'm missing despite the durable-draft pattern?
- Is my Ed25519 signing correct — signing over
header_jcs || ciphertext || tag? - Any obvious misuse of the crates?
Code is ~400 lines of relevant crypto, no PII, deterministic test vectors included.
I can share the relevant module as a Gist if there's interest. Happy to answer questions about the protocol design.
Thanks in advance!
Full review package (GAP analysis, line references, reviewer checklist):
1 post - 1 participant
🏷️ Rust_feed