Package org.bouncycastle.crypto.hpke
package org.bouncycastle.crypto.hpke
Hybrid Public Key Encryption (HPKE) per
RFC 9180.
HPKE composes a Key Encapsulation Mechanism (KEM), a Key Derivation Function (KDF) and an Authenticated-Encryption-with-Additional-Data (AEAD) algorithm into a single hybrid public-key encryption scheme. It's the building block underneath MLS (RFC 9420), TLS Encrypted Client Hello, and Oblivious HTTP (RFC 9458).
Supported parameter sets
The top-level facadeHPKE exposes the
full RFC 9180 algorithm matrix via short ID constants:
- Modes:
mode_base,mode_psk,mode_auth,mode_auth_psk. - KEMs: DHKEM(P-256, HKDF-SHA256), DHKEM(P-384, HKDF-SHA384),
DHKEM(P-521, HKDF-SHA512), DHKEM(X25519, HKDF-SHA256),
DHKEM(X448, HKDF-SHA512). External KEM implementations may be plugged
in via the
KEMabstract base and theHPKE(mode, kemId, kdfId, aeadId, KEM, encSize)constructor. - KDFs: HKDF-SHA256, HKDF-SHA384, HKDF-SHA512.
- AEADs: AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305, and the
export-only sentinel (id 0xFFFF) for callers who only need
HPKEContext.export(byte[], int)and not seal/open.
Typical caller flow (mode_base)
Sender:
HPKE hpke = new HPKE(HPKE.mode_base,
HPKE.kem_X25519_SHA256,
HPKE.kdf_HKDF_SHA256,
HPKE.aead_AES_GCM128);
HPKEContextWithEncapsulation ctx = hpke.setupBaseS(recipientPub, info);
byte[] enc = ctx.getEncapsulation(); // transmit alongside ct
byte[] ct = ctx.seal(aad, plaintext); // ctx is stateful, advances nonce
Receiver:
HPKEContext ctx = hpke.setupBaseR(enc, recipientKeyPair, info); byte[] pt = ctx.open(aad, ct);
For single-message use cases the HPKE.seal(AsymmetricKeyParameter, byte[], byte[], byte[], byte[], byte[], AsymmetricCipherKeyPair)
and HPKE.open(byte[], AsymmetricCipherKeyPair, byte[], byte[], byte[], byte[], byte[], AsymmetricKeyParameter) convenience methods do both
steps in one call and return [enc, ct] / the plaintext respectively.
Sealing semantics
The contexts returned bysetup*S and setup*R are stateful:
each seal / open call advances an internal sequence number
that's XOR-mixed into the AEAD nonce, so a single context can encrypt or
decrypt many messages in order without nonce reuse. The
HPKEContextWithEncapsulation.getEncapsulation()
method returns the enc octet string that must be transmitted alongside
the first ciphertext so the receiver can run the matching setup*R.-
ClassesClassDescriptionAEAD wrapper backing
HPKEContext.seal(byte[], byte[])/HPKEContext.open(byte[], byte[]).Hybrid Public Key Encryption (HPKE) per RFC 9180.An HPKE encryption / decryption context produced by one of theHPKE.setup*R(recipient) factory methods, or — via theHPKEContextWithEncapsulationsubclass — by one of theHPKE.setup*S(sender) factories.Sender-sideHPKEContextthat additionally carries theencoctet string produced by the KEM's encapsulation step.Abstract base for HPKE Key Encapsulation Mechanisms per RFC 9180 §4.