本文へスキップ
ecdsa.com

HPKE プレイグラウンド:ハイブリッド公開鍵暗号と Oblivious HTTP

暗号スイート(DHKEM(X25519)、DHKEM(P-256)、ML-KEM、X-Wing のいずれかに、HKDF と、AES-GCM または ChaCha20-Poly1305 を組み合わせたもの)を選び、公開鍵宛てにメッセージを暗号化してから、秘密鍵で復号します。RFC 9180 の鍵スケジュールの中間値はすべて表示されます。Oblivious HTTP タブでは、ゲートウェイの鍵設定をデコードし、リクエストとレスポンスの一連の処理を実行できます。

100% ローカル:鍵、PSK、平文はブラウザー内にとどまります。HPKE はこのサイトから読み込まれる Web Worker で動作し、どこにも何も送信しません

実行する内容

暗号スイート

0x0041 · 0x0001 · 0x0001 · draft-ietf-hpke-pq-05

モード

受信者の公開鍵宛てに暗号化します。誰でも送信者になり得ます。 ML-KEM-768 には認証付きモードがありません。auth と auth_psk には Diffie-Hellman 系の KEM が必要です。

enc 1,088 バイト · 公開鍵 1,184 バイト · 秘密鍵 64 バイト · 共有秘密 32 バイト

1 メッセージあたりに追加されるバイト:enc と 16 バイトのタグ
KEMenc(カプセル化された鍵)
ML-KEM-768
1,104 バイト
DHKEM(X25519, HKDF-SHA256)
48 バイト
DHKEM(P-256, HKDF-SHA256)
81 バイト

受信者

非公開:このブラウザー内にとどまり、共有リンクには含まれません

メッセージ

エンコーディング(info)
エンコーディング(関連データ)
エンコーディング(平文)
エンコーディング(エクスポーターのコンテキスト)
決定的な暗号化(テストベクトル専用)

カプセル化用の乱数:ML-KEM では 32 バイト、X-Wing では 64 バイト。空欄のままにすると、新しい乱数が生成されます。この値を知っている人は誰でも復号できます。

暗号文

HPKE in one paragraph

Hybrid Public Key Encryption, RFC 9180, encrypts a message to someone's public key. It is a recipe built from three parts named by IANA code points. A key encapsulation mechanism (KEM) agrees on a shared secret and outputs enc, the value the sender transmits. A key derivation function (KDF, here HKDF) stretches that secret into keys. An AEAD (AES-GCM or ChaCha20-Poly1305) encrypts and authenticates the message itself. "Hybrid" means public-key and symmetric cryptography together, not classical and post-quantum: that second kind of hybrid comes from the KEM. HPKE sits under TLS Encrypted Client Hello, Messaging Layer Security (RFC 9420) and Oblivious HTTP.

Four modes and the key schedule

RFC 9180 defines four modes. base only encrypts: anyone who knows the recipient's public key could be the sender. psk mixes in a pre-shared key of at least 32 bytes, which authenticates the sender and keeps the message confidential even if the KEM is broken. auth authenticates the sender's own key pair through Diffie-Hellman, and auth_psk does both. The playground enforces the RFC's rules: a PSK and its identifier come together, auth modes need a sender key, and they need a KEM that supports authentication.

Whatever the mode, the shared secret passes through the key schedule of RFC 9180 §5.1. The mode, the hash of the PSK identifier and the hash of info form key_schedule_context. The shared secret and the PSK form secret. From these come the AEAD key, the base_nonce (message n uses base_nonce XOR n) and the exporter_secret, from which both sides can derive further secrets without sending anything. The playground recomputes every one of these values next to the reference implementation, @hpke/core, and shows them. That makes it easy to see where an interoperability bug sits: in the KEM output, in info, in the PSK, or only in the associated data.

Post-quantum HPKE

With DHKEM(X25519) or DHKEM(P-256), a message recorded today can be decrypted once a large quantum computer exists (harvest now, decrypt later). Swapping the KEM is all it takes to fix that, and the playground runs the post-quantum KEMs of draft-ietf-hpke-pq: ML-KEM-512, -768 and -1024 (KEM ids 0x0040–0x0042) and X-Wing (0x647A), the hybrid of ML-KEM-768 and X25519. Their identifiers are in the IANA HPKE registry, but the document that defines how to use them is still an Internet-Draft as of 20 October 2026, so details such as key derivation could still change. The cost is size: enc grows from 32 bytes to 1,088 for ML-KEM-768 or 1,120 for X-Wing, which the chart beside the suite picker compares.

Two limits come with them. ML-KEM and X-Wing have no authenticated mode, so auth and auth_psk stay Diffie-Hellman-only and are not post-quantum. And the draft's private keys are seeds (64 bytes for ML-KEM, 32 for X-Wing), expanded on use, while derived keys come from a SHAKE256 labeled derivation that the playground computes itself, because @hpke does not implement it yet.

Oblivious HTTP

RFC 9458 uses HPKE so that a relay sees who is asking but not what, and the gateway sees what is asked but not who. A gateway publishes a key configuration: a key id, a KEM and its public key, and the KDF and AEAD pairs it accepts, served as application/ohttp-keys. The client encapsulates a Binary HTTP request into a header, enc and a ciphertext. The gateway decapsulates it and answers with a response encrypted under keys exported from the same HPKE context.

The Oblivious HTTP tab decodes any key configuration or list, byte by byte. It says whether the KEM is post-quantum, and with the gateway's private key it runs both sides of an exchange. The RFC 9458 Appendix A example reproduces the RFC's encapsulated request, response keys and encapsulated response exactly.

Test vectors

The examples are the RFC 9180 vectors for DHKEM(X25519) in base mode and DHKEM(P-256) in auth_psk mode, the draft-ietf-hpke-pq vectors for ML-KEM-768 and X-Wing, and RFC 9458 Appendix A. Each carries the sender's ephemeral input, which makes encryption deterministic, so Seal must reproduce enc, the ciphertext, the key schedule and an exported secret byte for byte; the page checks and says which value differs if one does. Outside test vectors, leave that field empty: whoever knows the ephemeral input can decrypt.

For the KEMs on their own, the ML-KEM lab takes key shares apart byte by byte. Post-quantum migration in 2026 explains why application-level encryption such as HPKE belongs on the migration list next to TLS.