Posts  / #POST-229252
REDDIT

I took the feedback on BLUE and shipped the rewrite. Looking for round 2.

M
Jun 4, 2026 · 13:08

[Three weeks ago I asked this sub to try to prove that BLUE (the deniability protocol in my pycryptox library) didn't work.](https://www.reddit.com/r/crypto/comments/1tdcchk/try_to_prove_that_my_denial_protocol_doesnt_work/) Two people landed clean hits, and they were right. I shipped 3.0.0 today with the fixes. Here's what changed, what I added, and where I still want round 2.

**What I removed because of your feedback**

The original BLUE v1.0 wire format had what I called "chemical mixing": the bytes of the two encrypted channels were shuffled together with 100–9000 random noise bytes, and the per-channel byte positions were encrypted as a separate "chemical key" alongside.

u/Cryptizard correctly pointed out this added no security: as long as the underlying primitives are IND$-CPA secure (ChaCha20-Poly1305 here) and both ciphertexts are padded to the same size, simple concatenation gives the same guarantee. u/SirJohnSmith reinforced the point: the noise was security theatre and Kerckhoffs already applies.

BLUE v2.0 now has this wire format:

[1-byte order_flag][4-byte len(enc_first)][enc_first][enc_second]

where `order_flag` is a uniformly random bit set at encryption time (`secrets.randbits(1)`) deciding which of the two slots goes first. Both ciphertexts are padded to the same bucket size before encryption (8 buckets from 4 KB up to 1 GiB). At decryption the recipient passes `slot="x"` or `slot="y"` explicitly ; no try-both fallback that would leak timing.

**What I added on top**

* A documentation pass on every protocol introducing a "Me vs Opponent" section that explicitly walks through the attacks I think a competent adversary tries (size correlation, timing oracle, mono-mode detection, structural fingerprinting), the design choice that defeats each one, and the attacks I explicitly do not address (coerced disclosure of both keys, RAM forensics, network metadata, decoy credibility).
* An async progress + ETA system for the larger buckets : ML-KEM encap + ChaCha20 over a 1 GiB padded message takes long enough to justify progress reporting.
* PURPLE v2.0 (the password-based protocol) with adjustable Argon2id strength (4 levels) and an `update_bundle` path so users can re-encrypt under stronger params without re-prompting for the passphrase elsewhere.

**Where I still want round 2**

Three specific things I'd like sharper eyes on:

1. **Mono mode.** When the sender supplies only one real message, the protocol generates an ephemeral ML-KEM-512 keypair for the unused slot, encrypts uniformly random bytes of the same length as the real message, and immediately destroys the ephemeral private key. The bundle is structurally identical to a dual bundle. My question: can a multi-snapshot adversary (someone watching the same sender over many bundles) distinguish "always mono" from "always dual" through network metadata, timing across the population, or anything I haven't thought of?
2. **The "Me vs Opponent" framing itself.** Does it cover the right attack surface, or am I missing entire categories? I tried to be honest about what BLUE does and does not protect against, but blind spots are blind by definition.
3. **Multi-slot generalisation.** u/Cryptizard suggested moving to a 0/1/2/3+ hidden-volumes model, citing Blass/Mayberry/Noubir/Onarlioglu, *"Toward Robust Hidden Volumes Using Write-Only Oblivious RAM"* (CCS 2014, pp. 203–214). I haven't gone there yet because expanding to n slots also expands the attack surface (per-slot key management, decoy credibility per slot, performance scaling), and I want the 2-slot case bulletproof first. Open question: is that the wrong order to be doing this in?

**Links**

* Repository: [https://github.com/cryptoxsystems/pycryptox](https://github.com/cryptoxsystems/pycryptox)
* BLUE protocol documentation (EN): [https://github.com/cryptoxsystems/pycryptox/blob/main/pycryptox/documentation/en/blue.md](https://github.com/cryptoxsystems/pycryptox/blob/main/pycryptox/documentation/en/blue.md) (FR also available)
* v3.0.0 release notes: [https://github.com/cryptoxsystems/pycryptox/releases/tag/v3.0.0](https://github.com/cryptoxsystems/pycryptox/releases/tag/v3.0.0)
* Acknowledgments (u/Cryptizard explicitly credited for the wire-format simplification): [https://github.com/cryptoxsystems/pycryptox/blob/main/THANKS.md](https://github.com/cryptoxsystems/pycryptox/blob/main/THANKS.md)
* PyPI: [https://pypi.org/project/pycryptox/3.0.0/](https://pypi.org/project/pycryptox/3.0.0/)

**AI disclosure (sub rule 8)**

Same posture as last time, with detail on what happened between threads:

1. **Python implementation**: AI-assisted (translation from my design to code, plus refactors and test scaffolding). The protocol design, threat model, primitive choices, and "Me vs Opponent" framing are mine. No cryptographic primitive was AI-invented; all primitives come from established standards (FIPS 203 for ML-KEM, RFC 9106 for Argon2id, RFC 8439 for ChaCha20-Poly1305).
2. **Documentation**: AI helped me structure and tighten the markdown. The technical content originates from my notes; the AI did the prose work.
3. **This post**: AI compressed my long draft into the structure above. I checked every claim against the actual codebase before submitting.

Initial prompt to the AI for this post: "Help me write a follow-up Reddit post for r/crypto announcing pycryptox 3.0.0. Reference the previ

Post image