Hurma & Meiko
Hurma Hurma
Hey, I was thinking about how we could design a lightweight cryptographic protocol that keeps activists safe online—want to bounce some ideas?
Meiko Meiko
Sure, just give me the rough specs and I'll see where the loopholes are. No promises that it'll be bulletproof, though.
Hurma Hurma
Here’s a quick sketch: - Use a 256‑bit symmetric key derived from a 128‑bit random seed plus a user‑chosen passphrase hashed with Argon2id (memory‑bound, 2 rounds). - Encrypt messages with ChaCha20‑Poly1305, including a 12‑byte nonce that’s the first 12 bytes of a 32‑byte counter incremented per message. - Sign the ciphertext with an Ed25519 signature that covers the nonce, ciphertext, and a short metadata block (timestamp, recipient ID). - Store keys in a secure enclave or TPM; for field use, the app can keep the seed in a hardware‑backed keystore. - For broadcast, allow “one‑time keys” – generate a fresh 256‑bit key per broadcast, send the public key encrypted with the seed’s asymmetric pair. - Add a simple “message expiry” by embedding a future timestamp and having receivers reject any packet older than that. That gives you speed, low overhead, and a decent defense against casual snooping. Let me know where you see gaps.
Meiko Meiko
Looks solid on the surface, but a few things bite: 128‑bit seed gives you a 128‑bit entropy floor, not ideal if an attacker guesses the passphrase. Also the counter‑derived nonce—if the counter ever wraps, you’re signing over the same nonce, and ChaCha20‑Poly1305 will silently decrypt wrong data. Make the counter 64‑bit at least and store it securely. For the broadcast key, you say “encrypt with the seed’s asymmetric pair” but you never actually generate a key pair from that seed; you need a deterministic key‑pair derivation or a proper asymmetric scheme. Finally, the timestamp‑based expiry assumes all parties have tight clock sync; a 5‑minute drift will reject all valid messages. A small tweak for each of those and you’ll have something that’s not just fast but actually survivable.
Hurma Hurma
You’re right on all the points. For the seed I’ll bump it to 256 bits so the passphrase hash is the real limiter. I’ll replace the 32‑bit counter with a 64‑bit counter stored in the secure enclave, and add a wrap‑around check that aborts if the counter ever resets. For the broadcast key, I’ll use a HKDF‑derived Ed25519 key pair from the seed so it’s deterministic but still strong. And instead of a hard timestamp, I’ll let the receiver reject only if the clock drift exceeds a configurable margin—say 15 minutes—while still including a freshness field so an attacker can’t replay old packets. That should shore up the weaknesses you spotted.
Meiko Meiko
Nice tightening. Just one more thought: HKDF‑derived Ed25519 gives you a deterministic pair, but if that seed leaks, you’re basically handing over every past broadcast key. You might want a per‑broadcast random key pair and just encrypt its public key with the seed‑derived master. Also, the 15‑minute drift guard feels arbitrary; if someone’s clock is off by a few hours, they’ll be locked out. A better approach is to use a sequence number in the metadata and have the receiver accept anything newer than the last seen, rejecting replayed packets regardless of clock. That keeps the system robust even in the field.
Hurma Hurma
Good points. I’ll switch to a per‑broadcast Ed25519 pair, generated randomly, and just encrypt its public key with the master seed. That way a leak only exposes the current broadcast, not all history. For timing I’ll drop the clock check entirely and rely on a monotonically increasing sequence number in the metadata; the receiver will remember the last sequence seen and reject anything older. That covers replay without clock sync, keeping the system usable even when devices aren’t perfectly time‑locked.