Inspiration

Well if I were to word my original inspiration, it started when I programmed my first native Linux TCP chat using sockets.h without any external libraries nor coding assistance. Seeing my text pop up in two terminals sparked profound satisfaction and propelled me further into networking, security and eventually, post quantum cryptography. Reading about how quantum computers will potentially pose a substantial threat to classical encryption and security standards we rely on today made me curious. I wanted to build something where PQC wasn't a patch bolted onto an existing system, but the foundation from the first line of code. And I wanted to build it in C, in a terminal, with nothing hidden behind a framework. It stands as an open source proof of concept to anyone enthusiastic about post quantum cryptography and a lightweight reference implementation of what a fully quantum-safe chat pipeline actually looks like end-to-end.

What it does

AnonComm shines in its simplicity to the user while hiding all the fascinating wiring of PQC underneath. A user starts their client.c file; the client authenticates the server, validates credentials over SCRAM, and both sides derive a shared session key via ML-KEM-768 key encapsulation. ML-DSA-3 signs the handshake itself, so authentication is quantum-safe too — not just the encryption. AES-256-GCM then secures the live, fully-duplex chat pipeline that opens directly in the terminal. There are no logs, no client-side history of connections, no reused session keys. The server side houses a whitelist and fail2ban-style blocklisting if any client IP spams invalid connection requests, plus on-demand server key rotation if a long-term key is ever suspected compromised.

How I built it

The entire timeline of events and updates is well documented in my Github repo's readme (link attached). Here's an abridged version: v0 - bare sockets. A plain TCP chat with zero cryptography, just to get concurrent send/receive plumbing right in C. v1 - naive symmetric cipher. A Vigenère-style cipher stood in for encryption with a hardcoded key in the server & client files. v2 - classical key exchange. Diffie-Hellman replaced the toy cipher with actual cryptographic key agreement — solid against a classical adversary, but with an expiration date against a quantum one. v3 — the post-quantum rewrite (main & prototype branches). The classical exchange was torn out entirely. ML-KEM-768 (FIPS 203) now handles key encapsulation. A SCRAM-based challenge-response layer handles authentication before any session key is trusted, and ML-DSA-3 (FIPS 204) signs the handshake so authentication is quantum-safe too. AES-256-GCM secures the live session once the shared key is established, giving authenticated encryption rather than encryption alone.

Around that core: an ncurses terminal UI, token-bucket rate limiting and IP allowlisting as hardening, and an RTT checker for diagnosing connection latency. The cryptographic primitives come from liboqs (Open Quantum Safe) but the transport, authentication flow, UI, and defenses are all hand-written in C. Built with a plain Makefile and setup.sh, and tested across WSL, Termux, and a VMware Kali/Ubuntu box to rule out environment-specific conclusions.

Challenges I ran into

Migrating off Diffie-Hellman wasn't a drop-in swap. ML-KEM-768 keys and ciphertexts are an order of magnitude larger than ECDH's 32-byte keys, so the wire protocol's framing and buffer sizing had to be rebuilt around variable, larger payloads instead of the fixed-size assumptions the DH version got away with. Authentication almost became the layer I skipped. It would've been easy to call the project "post-quantum" the moment ML-KEM-768 was handling key exchange — most demo projects making that claim stop exactly there. Building SCRAM-based challenge-response and signing it with ML-DSA-3 meant the harder, less glamorous half of the protocol got the same rigor as the encryption. Cross-environment testing surfaced real friction, not just box-checking — compiling against liboqs behaved differently across WSL, Termux, and a VMware Kali/Ubuntu box, and chasing down environment-specific build failures was its own debugging exercise, separate from the cryptography itself.

Accomplishments that I'm proud of

Every cryptographic layer in the live handshake — key exchange and authentication — is NIST-standardized post-quantum, with zero classical fallback anywhere in the path. That's a stricter bar than most "PQC chat" projects hold themselves to, since most stop at the key exchange and leave authentication on classical signatures. Benchmarking the ML-KEM-768 handshake against classical Diffie-Hellman and finding the latency differential comes in under half a millisecond — proof this isn't just academically interesting, it's production-viable today. Building the entire transport layer, authentication flow, terminal UI, and abuse defenses by hand in C, with liboqs as the only outside dependency, used strictly for the cryptographic primitives themselves. Nothing about how this thing works is a black box. Lastly,I've went out and made a scientific breakdown and analysis of this entire architecture as a technical poster for further reference.

What I learned

Algorithm strength and implementation security are two different problems. A NIST-standardized PQC primitive can still leak through a careless C implementation — security has to be argued at both layers, not just the math layer. The existence of the liboqs library makes a low level transition to post quantum solutions relatively streamlined for any individual or organization level attempt at post quantum migration.

What's next for AnonComm

Closing the gap between main and the prototype branch so the full SCRAM + ML-DSA-3 authentication stack ships as one stable build instead of living split across two. Group chat support, which means rethinking the current one-to-one session-key model for multi-party key agreement. Experimental branches with other NIST contestant algorithms of post quantum key exchange and authentication. Extending the implementation to IoT systems and tackle the gravest drawback of this innovative ecosystem: the size of post quantum keys and the resource availability in IoT end devices.

Built With

Share this project:

Updates