bxenc
Rust CLI encryption vault, steganography layer, and Darkroom anonymous chat research artifact using XChaCha20-Poly1305, Argon2id, ML-KEM-768, X25519, Zeroize, and atomic metadata writes.
Unaudited by design, but every claim is bounded by file-format proof, tests, and explicit limitations.
Darkroom separates relay-visible public room text from private-message envelopes established through hybrid X25519 plus ML-KEM-768 key exchange.
The whitespace, base64, BXENC header, salt, nonce, ciphertext, tag, and recovered plaintext line up as a real parse path.
The page keeps unaudited status, SSD limits, allocator residue, and compromised-host assumptions visible instead of marketing past them.
Whitespace stego pipeline
Vault: Rust CLI plus Darkroom anonymous chat research system
Private messaging: hybrid ML-KEM-768 + X25519 PQXDH-style handshake
Symmetric layer: XChaCha20-Poly1305, Argon2id, Zeroize, atomic writes
Stego: notes.txt contains 1,088 tabs/spaces encoding BXENC ciphertext
Structure: 7B header + 16B salt + 24B nonce + 50B ciphertext/tag
Recovery: reveal.bxenc decrypted to recovered.dat independently
Verification: focused Darkroom PQXDH/PME, bxenc core, and integration tests pass locally
Status: unaudited research artifact, not production software
bxenc: Rust Encryption Vault + Darkroom
bxenc is a Rust CLI encryption vault with a steganography layer and a companion anonymous chat system called Darkroom. The file format is built around XChaCha20-Poly1305 and Argon2id. Darkroom adds I2P-routed chat, invite-controlled access, and private-message envelopes established through a hybrid X25519 + ML-KEM-768 handshake.
The whitespace encoder hides ciphertext as tabs and spaces: notes.txt in this demo contains 1,088 whitespace characters encoding an XChaCha20-Poly1305 ciphertext. To a diff tool or a human reader, the file looks empty.
This is not a production password manager. It is an unaudited research implementation with public source and a USB demo artifact, with the value concentrated in the design decisions, file-format proof, and documented limitations.
What I Built
- Rust CLI vault: A command-line encryption tool designed around explicit cryptographic and filesystem tradeoffs.
- Darkroom anonymous chat: A Rust async relay designed for I2P tunnels, invite-based access, revocation, and private-message envelope routing.
- Hybrid post-quantum / X25519 private messaging: Darkroom uses a PQXDH-style flow that combines X25519 DH outputs with an ML-KEM-768 shared secret before deriving a session key with HKDF-SHA256.
- XChaCha20-Poly1305 encryption: Authenticated symmetric encryption with a 192-bit nonce.
- Argon2id key derivation: Password-based key derivation using the RFC 9106 interactive parameter direction.
- Zeroize discipline: Key material and sensitive caller-owned buffers are zeroed where the program controls memory.
- Encrypted vault metadata: Vault metadata is encrypted at rest instead of written as plaintext JSON.
- Atomic metadata writes: Metadata updates use write-temp, fsync, and rename semantics so a power loss mid-write is less likely to corrupt the vault.
- Whitespace steganography: Ciphertext can be wrapped into tabs and spaces so the carrier file appears blank.
- Tested boundaries: Local focused test runs passed for Darkroom PQXDH/PME behavior, bxenc core crypto, vault metadata protection, stego round trips, and integration checks.
Darkroom
Darkroom is the networked system built around bxenc. It treats the server as a relay rather than a trusted message reader: plaintext private messages are rejected, key bundles are validated before storage, KX1/KX2 handshake blobs are routed as opaque base64url envelopes, and PME payloads are delivered for client-side decryption.
The private-message handshake uses the ml-kem crate's MlKem768 type for the post-quantum KEM and x25519-dalek for classical Diffie-Hellman. The session key is derived from three X25519 shared secrets plus the ML-KEM-768 shared secret through HKDF-SHA256. Message envelopes then use XChaCha20-Poly1305 with transcript/session associated data.
ML-KEM-768 is a NIST-standardized post-quantum key encapsulation mechanism. X25519 remains the classical elliptic-curve Diffie-Hellman half of the hybrid design.
Important limit: Darkroom currently supports E2E private messages through PME. Public room messages still route as relay-visible text, so this project should be described as E2E encrypted private messaging over an anonymous relay, not universal E2E chat.
Real Demo Artifact
The demo files in this artifact parse cleanly at every layer:
notes.txtcontains 1,088 whitespace characters: 498 tabs and 590 spaces, with zero other characters.- Decoding those tabs and spaces produces
84 00 00 00, a little-endian length prefix for 132 bytes, followed by 132 bytes of base64. - That base64 decodes to a 97-byte BXENC blob beginning with
BXENC\x01\x00. - The encrypted structure is 7 bytes of header, 16 bytes of Argon2id salt, 24 bytes of XChaCha20 nonce, and 50 bytes of ciphertext plus Poly1305 tag.
- The plaintext message,
The eagle has landed in Stockholm\n, is 34 bytes; the Poly1305 tag accounts for the remaining 16 bytes. recovered.datcontainsPRIVATE_KEY_DATA_DO_NOT_LEAK, confirming a second independent decryption fromreveal.bxenc.
The artifact is built from those real file values, not a mocked screenshot.
Cryptographic Choices
- ML-KEM-768 + X25519: Darkroom combines post-quantum key encapsulation with classical X25519 agreement, so the private-message design is not betting on only one asymmetric assumption.
- XChaCha20-Poly1305: Chosen for authenticated encryption and a 192-bit nonce that makes random nonce collision risk structurally small.
- Argon2id: Chosen for password-based key derivation with memory-hard brute-force resistance.
- bincode over JSON: Chosen for compact binary metadata and less string-allocation surface than JSON metadata.
- readpass / Zeroize: Chosen so password input and key material can be wrapped in zeroizing containers where the program controls ownership.
- Atomic writes: Chosen because vault metadata corruption is a real failure mode, not a theoretical edge case.
Known Limitations
The limitations are part of the artifact. They are included because the project is a security study, not a polished production vault.
| Limitation | Why it matters | Portfolio framing |
|---|---|---|
| Not audited | No third-party cryptographic or implementation review has been performed. | Research implementation only. |
| Public source, unaudited release | Source is public, but that does not make the tool production-reviewed. | Treat as research tooling unless independently audited. |
| SSD wear-leveling | Secure delete cannot reliably erase old physical flash cells. | Use full-disk encryption for device-level protection. |
| Windows keyfile permissions | Windows does not map cleanly to POSIX-style 0600 file permissions. | Documented platform limitation. |
| readpass internal reallocations | Very long password input may leave allocator-level copies the program cannot recover. | Zeroize is applied to owned outputs, not every internal allocation. |
| bincode / serde allocation residue | Serialization internals may allocate buffers outside direct caller control. | Acknowledged sensitive-memory limitation. |
| Compromised OS or keylogger | Local malware can observe passwords before encryption code runs. | Outside bxenc's threat model. |
Publication Status
- Source: github.com/bibbisalsd/bxenc
- No production release is advertised.
- The artifact is not audited for production use.
- The demo is intended for USB distribution and portfolio review.
- Local verification passed for
cargo test -p darkroom-server pqxdh -- --nocapture. - Local verification passed for
cargo test -p bxenc-core -p bxenc-integration -- --nocapture.
Proof
- Interactive artifact:
/artifacts/bxenc-stego-pipeline.html - Public source:
https://github.com/bibbisalsd/bxenc - Local file proof:
notes.txt,secret.bxenc,reveal.bxenc, andrecovered.datwere checked from the Downloads folder. - Structural proof: the whitespace layer, base64 layer, BXENC header, salt, nonce, ciphertext, tag, and recovered plaintext all agree.