how it works
introduction
what is steganography?
steganography hides messages in plain sight. unlike encryption which scrambles a message so it can't be read, steganography hides the message inside something ordinary like an image. anyone looking at the image sees just a normal picture.
what is post-quantum encryption?
today's encryption (RSA, elliptic curves) can be broken by quantum computers using Shor's algorithm. post-quantum cryptography uses mathematical problems that remain hard even for quantum computers. ML-KEM is a lattice-based algorithm standardized by NIST in 2024 specifically for this purpose.
what is LSB encoding?
every pixel in an image has color values stored as 8-bit numbers (0-255). the least significant bit (LSB) is the rightmost bit, and changing it only shifts the value by 1. for example, changing a red value from 180 to 181 is invisible to the human eye.
lsb embedding example
each pixel has three color channels (red, green, blue), so each pixel can hide 3 bits of data. a 1000×1000 image has 1 million pixels, giving you 375 KB of hiding capacity.
LSB steganography is hard to detect because the changes are statistically random and visually imperceptible. detection tools look for unusual patterns, but at low embedding rates the modifications blend into the natural noise of any image.
the big picture
plainsight combines these ideas: your message is encrypted with ML-KEM-768 and AES-256-GCM, then hidden inside an image using LSB encoding. the image can be shared on social media, email, or messaging apps without raising suspicion.
encryption pipeline
the receiver extracts and decrypts the message using their private key. if anyone tampers with the image, decryption fails and the system detects the modification.
decryption pipeline
key generation
the receiver generates a keypair using ML-KEM-768. the public key can be shared with anyone who wants to send them a message. the private key is kept secret and used for decryption.
ml-kem-768 keypair generation
encryption steps
encryption happens in three steps. first, the sender uses the receiver's public key to create a shared secret that only the receiver can recover.
key encapsulation
the shared secret is used to derive an AES-256-GCM key. this symmetric cipher encrypts the actual message and adds an authentication tag that detects any tampering.
symmetric encryption
finally, the encrypted data is hidden inside an image using LSB steganography.
lsb steganography
decryption
the receiver reverses the process: extract the hidden data, recover the shared secret using their private key, and decrypt the message. only the private key holder can read it.
complete decryption process
performance
post-quantum cryptography has a reputation for being slow, but ML-KEM is fast. all operations complete in under 100 microseconds. these benchmarks were measured using a rust implementation.
ml-kem operation times across variants (lower is better)
operation time ───────────────────────────────────── ml-kem-768 key generation 44 μs ml-kem-768 encapsulation 41 μs ml-kem-768 decapsulation 53 μs aes-256-gcm encryption < 1 μs lsb embedding 29 μs lsb extraction 17 μs ───────────────────────────────────── total encryption ~115 μs total decryption ~71 μs
benchmarks on amd ryzen 5 7535HS
image quality
PSNR (peak signal-to-noise ratio) measures image quality. values above 40 dB are considered imperceptible to humans. even at 100% capacity, PSNR stays above 51 dB. in practice, a typical message uses less than 1% of capacity.
psnr vs embedding capacity (higher is better)
data sizes
each message has about 1.1 KB of overhead for the cryptographic data. a typical photograph can hide tens or hundreds of kilobytes of data.
component size ───────────────────────────────────── ml-kem public key 1,184 bytes ml-kem private key 2,400 bytes ml-kem ciphertext 1,088 bytes aes-gcm iv 12 bytes aes-gcm auth tag 16 bytes ───────────────────────────────────── overhead per message ~1,116 bytes 500×500 image capacity ~93 kb 1000×1000 image capacity ~375 kb