QR Crypt
Exchange keys in person. Encrypt text permanently offline.
6 followers
Exchange keys in person. Encrypt text permanently offline.
6 followers
In-person key exchange. Encryption and decryption stay on permanently offline devices. Only ciphertext crosses the air gap, via QR codes.




Hey Product Hunt. I'm transparent-pegasus, and I built QR Crypt.
Why I built it
Mercenary spyware attacks the endpoint, not the cipher. A Pegasus-class implant can read what you type, what appears on screen, camera frames, and secrets stored on the device. If an attacker can observe plaintext before encryption or after decryption, replacing one protocol with a stronger one does not solve the problem.
So I stopped asking how to make an online device trustworthy and started asking where plaintext should exist instead. QR Crypt's answer is a dedicated device that stays disconnected from every network while it holds keys or plaintext.
For high-assurance use, the default installation route is a signed static ZIP. You verify its signature and checksum on a separate trusted computer, independently rebuild and compare it, transfer it to the offline device, and serve it only from 127.0.0.1. A direct-origin PWA installation route also exists, but it cannot give the user a verifiable integrity check for the bundle delivered to that device.
How it works
Each person uses two devices: one dedicated offline device and one ordinary online device that acts only as a carrier.
You type the message on the offline device. QR Crypt encrypts it and displays either one QR code or a sequence of QR frames. Your everyday phone uses the Relay page to scan the frames into text, carries that text through whatever messenger you already use, and recreates the QR frames for the recipient. The recipient's offline device authenticates, decrypts, and displays the message.
Only ciphertext and the framing data needed to carry it cross the offline boundary. The online device never needs the decryption keys, although anyone observing the transport can still see the approximate transfer size and the number of frames.
Key exchange is also performed face to face. In shared-key mode, one person creates a symmetric key and hands it to the other as a QR code. In public-key mode, people exchange public identities and compare their fingerprints in person. There are no accounts, no QR Crypt key server, no cloud key escrow, and no account sync.
What the crypto is
Both modes encrypt the message body with AES-256-GCM and use HKDF-SHA256 to derive a different AES key for every message.
Shared-key mode is intended for one-to-one communication. Each message key is derived from the symmetric key that the two people exchanged in person. The shared-key message format is deliberately capped so that every supported message fits in a single QR code.
Public-key mode is useful when several senders need to write to one recipient without giving those senders a secret that can decrypt messages. ML-KEM-1024 establishes the message secret from the recipient's public key. ML-DSA-87 signs every post-quantum message so the recipient can verify a sender whose public identity was previously fingerprint-checked in person.
The message body in public-key mode is still encrypted with AES-256-GCM. ML-KEM changes how the message secret is established, and ML-DSA adds sender verification. The KEM ciphertext, public-key identifiers, and signature make this mode substantially larger, so messages are transferred as multiple QR frames.
Both symmetric keys and post-quantum identities can be rotated. Superseded generations remain available for decryption until the user explicitly discards them. I did not invent any of these cryptographic primitives.
On the quantum question, the distinction matters. The post-quantum mode does not make the AES ciphertext itself stronger. Shared-key mode avoids public-key key agreement entirely because the symmetric secret is exchanged in person. Public-key mode uses implementations of the FIPS 203 ML-KEM and FIPS 204 ML-DSA algorithms for post-quantum key establishment and signatures.
Implementing those algorithms is not the same as receiving FIPS 140 validation, an independent audit, or a guarantee that the complete application is secure.
What it does not do
An attacker who controls the OS, browser, firmware, or installed application can defeat the design. QR Crypt does not protect against keyloggers, screen recording, screenshots, malware that captures camera frames, a compromised installation path, physical theft, accidental sharing of a secret QR code, or loss of keys through browser-data deletion.
The offline indicator is information about the device's current network state, not proof that the device is trustworthy. Airplane mode alone is not a security boundary.
With wipe-on-online enabled, which is the default, the app attempts best-effort logical deletion only after network reachability has been confirmed. Logical deletion does not guarantee physical erasure. Flash storage, browser databases, garbage collection, and internal copies may leave recoverable remnants. When the data must become unrecoverable, use a storage-appropriate sanitization procedure or physically destroy the medium.
There is no in-place update mechanism. To install a new version on a device that has held keys, identities, or plaintext-bearing state, sanitize the device and install the application again. Do not reconnect such a device to a network without first sanitizing it.
Neither the complete application nor the adopted post-quantum JavaScript implementation has received an independent security audit. The post-quantum mode is experimental, constant-time execution under JavaScript and JIT environments is not guaranteed, and JavaScript cannot guarantee complete memory erasure.
The repository contains the v2 QR protocol for both shared-key and post-quantum messages, the threat model, the boot and reset contract, the security-review record, and the full high-assurance signed-ZIP installation procedure.
Tell me where the design breaks.