See: Description
| Class | Description |
|---|---|
| AEAD |
AEAD wrapper backing
HPKEContext.seal(byte[], byte[])/HPKEContext.open(byte[], byte[]). |
| HPKE |
Hybrid Public Key Encryption (HPKE) per
RFC 9180.
|
| HPKEContext |
An HPKE encryption / decryption context produced by one of the
HPKE.setup*R (recipient) factory methods, or — via the
HPKEContextWithEncapsulation subclass — by one of the
HPKE.setup*S (sender) factories. |
| HPKEContextWithEncapsulation |
Sender-side
HPKEContext that additionally carries the enc
octet string produced by the KEM's encapsulation step. |
| KEM |
Abstract base for HPKE Key Encapsulation Mechanisms per
RFC 9180 §4.
|
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).
HPKE exposes the
full RFC 9180 algorithm matrix via short ID constants:
mode_base, mode_psk, mode_auth,
mode_auth_psk.KEM abstract base and
the HPKE(mode, kemId, kdfId, aeadId, KEM, encSize) constructor.HPKEContext.export(byte[], int)
and not seal/open.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(org.bouncycastle.crypto.params.AsymmetricKeyParameter, byte[], byte[], byte[], byte[], byte[], org.bouncycastle.crypto.AsymmetricCipherKeyPair)
and HPKE.open(byte[], org.bouncycastle.crypto.AsymmetricCipherKeyPair, byte[], byte[], byte[], byte[], byte[], org.bouncycastle.crypto.params.AsymmetricKeyParameter) convenience methods do both
steps in one call and return [enc, ct] / the plaintext respectively.
setup*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.