惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
A
About on SuperTechFans
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
雷峰网
雷峰网
博客园_首页
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
IT之家
IT之家
博客园 - 叶小钗
Google DeepMind News
Google DeepMind News
aimingoo的专栏
aimingoo的专栏
博客园 - 聂微东
B
Blog RSS Feed
H
Help Net Security
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
L
LangChain Blog
Vercel News
Vercel News

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Adding a post-quantum hybrid handshake to a Rust VPN
Alexandr Litvinov · 2026-06-19 · via DEV Community

Alexandr Litvinov

I maintain Qeli, a self-hosted VPN whose core and server are written in Rust. For the 0.7.x line I added a hybrid post-quantum key exchange to the inner handshake, and wired the same primitive into the non-Rust clients. Here is how it is built and what bit me.

Why hybrid, not pure PQ

The threat is "harvest now, decrypt later": traffic captured today, decrypted once a large quantum computer exists. Classical X25519 does not survive that; pure ML-KEM is young, and I do not want one new primitive to be the only thing between you and plaintext. So the handshake runs both and mixes the results - you are safe unless both X25519 and ML-KEM-768 fall.

The shape of the handshake

  • Classical: X25519 ephemeral ECDH.
  • Post-quantum: ML-KEM-768 (FIPS 203), via the RustCrypto stack - one side encapsulates to the other's ephemeral KEM public key.
  • The two shared secrets are concatenated and run through HKDF-SHA256 to derive the session keys. The data plane is ChaCha20-Poly1305; password-derived secrets use Argon2id.

Mixing both secrets in the KDF (instead of picking one) is what makes it hybrid: an attacker has to break both to recover the key.

One PQ core across Rust, C# and Kotlin

Qeli has native clients on Windows/macOS (C#) and Android (Kotlin). Rather than reimplement ML-KEM three times, the Rust implementation is the single source of truth, and the other clients call into a small native core over FFI (C#) and JNI (Android). Same wire format everywhere, and the PQ code gets reviewed once.

Things that bit me

  • Wire compatibility. Turning on PQ changed the handshake bytes. I kept it wire-compatible within 0.7.x, but it is a breaking change versus older clients - versioning the handshake from day one would have saved pain.
  • Message sizes. ML-KEM-768 public keys and ciphertexts are ~1.1 KB, far larger than X25519's 32 bytes. Worth accounting for in your framing and MTU assumptions.
  • Keep the classical path. It is tempting to drop X25519 once PQ works, but hybrid is the whole point - the KDF step has to bind both.

Try it

Code is open (AGPL-3.0 core, MPL-2.0 clients): https://github.com/litvinovtd/qeli - and there is a project site at https://qeli.ru. Feedback on the handshake and transport code is very welcome.