━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
OPEN IMAGE NETWORK
Post-Quantum Encrypted Image Hosting
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
A project by Vinavil
OPEN IMAGE NETWORK
Post-Quantum Encrypted Image Hosting
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
A project by Vinavil
What Is This?
Most image hosts have full access to everything you upload. Imgur, Discord CDN, whatever. Your files are accessible on their servers, they can scan them, hand them over on request, or lose them in a breach. You're trusting a third party with your data because there was never a real alternative.
OIN is the alternative. Upload an image, it gets encrypted in your browser before it ever touches the server. The encrypted blob gets chunked, wrapped in post-quantum cryptography, and distributed across storage nodes. The gateway that coordinates everything never sees plaintext. The nodes that store your data can't decrypt it even if they wanted to. The decryption key lives in the URL fragment, which browsers never send to servers. Click a link, your browser pulls the ciphertext, decrypts locally, displays the image. Nobody in between sees anything.
No accounts. No tracking. No ads.
Why Should You Care?
Two words: harvest now, decrypt later. Intelligence agencies and state actors are stockpiling encrypted traffic today, waiting for quantum computers capable of breaking classical cryptography. RSA, ECDH, the stuff protecting most of the internet right now, all of it becomes worthless the day a sufficiently large quantum computer exists. Most estimates say 10-15 years. Some say sooner.
OIN doesn't wait for that to be a problem. Every manifest is encrypted with AES-256-GCM using keys exchanged through ML-KEM-1024, which is NIST's post-quantum key encapsulation standard. Every envelope is dual-signed with ML-DSA-87 (lattice-based) and SLH-DSA-SHAKE-256s (hash-based). If lattice math breaks tomorrow, the hash signatures still hold. If both break, you still have the browser-side AES-256-GCM layer that has 128-bit post-Grover security with no asymmetric key exchange to attack with Shor's algorithm.
Three layers of encryption. Two independent signature schemes. Zero trust required.
How It Actually Works
No hand-waving. Here's the real pipeline, every step.
► Browser-Side Encryption (E2E Layer)
Before your image ever leaves the browser, WebCrypto generates a 32-byte random seed and 12-byte IV. HKDF-SHA256 derives an AES-256-GCM key from the seed. The image gets encrypted. An HMAC-SHA256 of the ciphertext is computed for integrity verification. The encrypted blob is what gets uploaded. The gateway receives ciphertext that it cannot distinguish from random noise.
► Gateway Processing (PQC Layer)
The gateway takes the ciphertext and chunks it using Reed-Solomon erasure coding, creating data shards and parity shards. Each chunk is encrypted with a per-image AES-256-GCM key. The manifest containing chunk locations and the image key is then wrapped in a PQC envelope: ML-KEM-1024 establishes a quantum-safe shared secret, HKDF-SHA3-256 combines it with classical randomness to derive a hybrid key, AES-256-GCM encrypts the manifest, and both ML-DSA-87 and SLH-DSA-SHAKE-256s sign the envelope. The classical key portion goes into the share link.
► Node Storage (Zero-Knowledge)
Encrypted chunks get distributed to storage nodes. Nodes store opaque blobs. The node codebase literally imports zero cryptographic decryption functions. It can't see your images. It doesn't know what it's storing. It just holds bytes and serves them back when asked. If a node goes rogue or gets compromised, the attacker gets encrypted garbage.
► Viewer Decryption
Someone opens your share link. The browser parses the URL fragment (never sent to the server), fetches the encrypted data, verifies the HMAC to detect tampering, and decrypts with AES-256-GCM. All client-side. The server delivered ciphertext, the browser produced the image. No plugin, no extension, no app required.
The Crypto Stack
Everything here is NIST standardized. No homebrew, no experimental schemes.
ML-KEM-1024 (FIPS 203)
Lattice-based key encapsulation. Security Level 5. Generates quantum-safe shared secrets that get mixed with classical randomness via HKDF-SHA3-256 to produce hybrid encryption keys. Both the quantum and classical components must be broken simultaneously.
ML-DSA-87 (FIPS 204)
Lattice-based digital signatures. Security Level 5. 4,627-byte signatures. Fast verification. Signs every PQC envelope so you know the manifest hasn't been tampered with since encryption.
SLH-DSA-SHAKE-256s (FIPS 205)
Hash-based digital signatures. Security Level 5. 29,792-byte signatures. Zero algebraic structure to attack. If every lattice assumption falls apart tomorrow, this signature scheme still stands because it's built on hash functions, not math problems. The conservative backup.
AES-256-GCM
The workhorse. Browser-side E2E encryption, per-chunk encryption, and manifest encryption inside the PQC envelope. Hardware-accelerated via AES-NI. 128-bit security post-Grover.
Architecture
I'm not going to pretend this is fully decentralized. It's not. Here's what it actually is.
The gateway is a central coordinator. It receives uploads, encrypts and chunks data, distributes to nodes, and reassembles on download. It does not store data permanently. After nodes confirm replication, the gateway evicts the image from RAM. But it's still a single point of coordination. If the gateway goes down, share links stop working until it comes back.
Nodes are the distributed part. They're independent, can run anywhere, and store only encrypted blobs. The pull architecture means nodes poll the gateway for work, so no port forwarding is needed. NAT-friendly. Works behind any firewall. Multiple nodes provide redundancy through Reed-Solomon erasure coding, so images survive partial node failure.
Call it hybrid-decentralized. The storage is distributed, the coordination is centralized. That's the honest picture.
Code
Browser Gateway Nodes
│ │ │
├── AES-256-GCM encrypt ──────→│ │
│ (key stays in browser) ├── chunk + Reed-Solomon │
│ ├── AES-256-GCM per chunk │
│ ├── ML-KEM-1024 key exchange │
│ ├── ML-DSA-87 + SLH-DSA sign │
│ ├── distribute ────────────────→│
│←── link with key in #fragment│ │
│ │ │
├── request image ────────────→│ │
│ ├── verify PQC signatures │
│ ├── pull from nodes ←──────────│
│←── encrypted response ──────│ │
├── HMAC-SHA256 verify │ │
├── AES-256-GCM decrypt │ │
├── display │ │Running A Node
Minimal barrier to entry. Download a binary, run it. Done.
► Windows
Code
oin-node-windows-x64.exe► Linux / macOS
Code
chmod +x oin-node-*
./oin-node-linux-x64► Build From Source
Code
git clone https://github.com/VinavilDev/OpenImageNetwork.git
cd OpenImageNetwork
cargo build --release -p oin-node
./target/release/oin-nodeNo configuration files, no environment setup, no accounts. The node auto-detects all available disks, allocates 3.5% of total space, connects to the gateway, and starts accepting encrypted chunks. Cross-platform: Windows, macOS (ARM + Intel), Linux. Single binary, no dependencies.
Here's what it looks like when it starts:
Code
2026-03-07T14:22:10Z INFO location: auto-detected
2026-03-07T14:22:10Z INFO detected 1 disk(s):
2026-03-07T14:22:10Z INFO /dev/sda1 - total: 500 GB, available: 420 GB
2026-03-07T14:22:10Z INFO storage plan: 17.5 GB across 1 disk(s) (3.5%)
2026-03-07T14:22:10Z INFO OIN Node [a1b2c3d4e5f6] on :9090
2026-03-07T14:22:38Z INFO sync 855622384066
2026-03-07T14:22:40Z INFO synced 855622384066 - 6/6 chunksThat's it. Node is live, syncing encrypted chunks, contributing storage to the network. Every chunk it stores is opaque ciphertext it can never decrypt.
The Tech Stack
- Language: 100% Rust. Memory-safe with 2 unsafe blocks (FFI calls for disk space queries, both bounds-checked).
- Crypto: fips203, fips204, fips205 crates for PQC. aes-gcm for symmetric encryption. hkdf + sha3 for key derivation.
- Erasure Coding: Reed-Solomon via reed-solomon-erasure crate. Data + parity shards survive partial node loss.
- Web Framework: Axum with Tokio async runtime. Gateway handles uploads, downloads, node coordination, admin panel.
- Browser Crypto: WebCrypto API. AES-256-GCM, HKDF-SHA256, HMAC-SHA256. No JavaScript crypto libraries, all native browser APIs.
Links
Upload an image: https://oin.vinavildev.com
Foundation page: https://oinfoundation.vinavildev.com
Source code: https://github.com/VinavilDev/OpenImageNetwork
Download binaries: https://github.com/VinavilDev/OpenImageNetwork/releases
Closing Notes
I built this because I was tired of trusting image hosts with my data. Every platform says they care about privacy while scanning every upload and complying with every request that shows up. The fundamental problem is architectural: if the server can see your data, it will eventually be seen by someone you didn't intend.
OIN flips that. The server is blind by design. The gateway processes ciphertext it can't read. Nodes store blobs they can't open. The only entity that ever sees the plaintext image is the person holding the share link, in their browser, decrypted locally. Post-quantum crypto means even the harvest-now-decrypt-later crowd gets nothing useful.
It's hybrid-decentralized, not fully decentralized. The gateway is a single point of coordination. I'm honest about that. But the data layer is distributed, the crypto is real, and every claim in this post maps to actual code you can audit. MIT licensed. Pure Rust. Check the source.
If you want to support the network, download the node binary and run it. Takes 30 seconds. You'll be storing encrypted chunks you can never read, helping make the network more resilient for everyone.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Own Your Images. Trust No One.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Own Your Images. Trust No One.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
In the dark we hide, in fear we thrive.



