Class HybridKexContexts
This class implements the SDK-level composition layer for hybrid key exchange. It does not introduce new core contracts; instead, it composes existing core contexts:
AgreementContextfor the classic (pre-quantum) leg (e.g. X25519, ECDH, DH), andMessageAgreementContextfor the post-quantum leg (typically a KEM-style agreement, e.g. ML-KEM exposed asKeyUsage.AGREEMENT).
Handshake model
The two legs have different wire semantics:
- Classic leg generally uses a peer public key supplied out-of-band
(certificate, directory, or a higher-level handshake message). This is
represented by
AgreementContext.setPeerPublic(java.security.PublicKey)and does not necessarily produce any explicit "to-be-sent" bytes. - PQC leg is message-based: the initiator produces an encapsulation
message (e.g. KEM ciphertext) via
MessageAgreementContext.getPeerMessage(), and the responder consumes it viaMessageAgreementContext.setPeerMessage(byte[]).
HybridKexContext unifies these semantics by emitting and consuming a
single hybrid peer message that carries both legs (with the classic part
typically empty for classic-only public-key exchange).
Error handling
Context construction is in-memory and reports configuration or provider
failures through the security exception model of ZeroEchoSession. I/O
failures remain associated with later stream processing.
Thread safety
This factory is stateless and thread-safe. Produced contexts are mutable and not thread-safe.
- Since:
- 1.0
-
Method Summary
Modifier and TypeMethodDescriptionstatic HybridKexContextinitiator(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, PrivateKey classicInitiatorPrivate, PublicKey classicPeerPublic, ContextSpec classicSpec, String pqcAlgId, PublicKey pqcPeerPublic, ContextSpec pqcSpec) Creates an initiator-side hybrid KEX context.static HybridKexContextinitiatorPairMessage(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, KeyPairKey classicInitiatorKeyPair, ContextSpec classicSpec, String pqcAlgId, PublicKey pqcPeerPublic, ContextSpec pqcSpec) Creates an initiator-side hybrid KEX where the classic leg is message-based (PAIR_MESSAGE).static HybridKexContextresponder(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, PrivateKey classicResponderPrivate, PublicKey classicPeerPublic, ContextSpec classicSpec, String pqcAlgId, PrivateKey pqcResponderPrivate, ContextSpec pqcSpec) Creates a responder-side hybrid KEX context.static HybridKexContextresponderPairMessage(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, KeyPairKey classicResponderKeyPair, ContextSpec classicSpec, String pqcAlgId, PrivateKey pqcResponderPrivate, ContextSpec pqcSpec) Creates a responder-side hybrid KEX where the classic leg is message-based (PAIR_MESSAGE).
-
Method Details
-
initiator
public static HybridKexContext initiator(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, PrivateKey classicInitiatorPrivate, PublicKey classicPeerPublic, ContextSpec classicSpec, String pqcAlgId, PublicKey pqcPeerPublic, ContextSpec pqcSpec) Creates an initiator-side hybrid KEX context.This method constructs:
- a classic
AgreementContextfrom the initiator's classicPrivateKeyand configures it with the peer's classicPublicKey, and - a PQC
MessageAgreementContextfrom the peer's PQCPublicKey(encapsulation side).
The returned
HybridKexContextwill typically produce a peer message whose PQC part is non-empty (e.g. KEM ciphertext), while the classic part is empty unless the chosen classic implementation itself supports message mode.- Parameters:
session- explicit policy and audit boundaryprofile- hybrid profile defining HKDF binding and output lengthclassicAlgId- classic agreement algorithm identifier (for example"X25519","ECDH","DH")classicInitiatorPrivate- initiator private key for the classic legclassicPeerPublic- peer public key for the classic legclassicSpec- optional classic context spec (may benullif the algorithm supports a default)pqcAlgId- post-quantum agreement algorithm identifier (for example"ML-KEM"exposed viaKeyUsage.AGREEMENT)pqcPeerPublic- peer public key for the PQC leg (encapsulation side)pqcSpec- optional PQC context spec (may benullif the algorithm supports a default)- Returns:
- initiator-side
HybridKexContext - Throws:
NullPointerException- if any required argument isnull- Since:
- 1.0
- a classic
-
responder
public static HybridKexContext responder(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, PrivateKey classicResponderPrivate, PublicKey classicPeerPublic, ContextSpec classicSpec, String pqcAlgId, PrivateKey pqcResponderPrivate, ContextSpec pqcSpec) Creates a responder-side hybrid KEX context.This method constructs:
- a classic
AgreementContextfrom the responder's classicPrivateKeyand configures it with the peer's classicPublicKey, and - a PQC
MessageAgreementContextfrom the responder's PQCPrivateKey(decapsulation side).
The returned
HybridKexContextis typically used after receiving the initiator's hybrid peer message and passing it toHybridKexContext.setPeerMessage(byte[]).- Parameters:
session- explicit policy and audit boundaryprofile- hybrid profile defining HKDF binding and output lengthclassicAlgId- classic agreement algorithm identifierclassicResponderPrivate- responder private key for the classic legclassicPeerPublic- peer public key for the classic legclassicSpec- optional classic context spec (may benull)pqcAlgId- post-quantum agreement algorithm identifierpqcResponderPrivate- responder private key for the PQC leg (decapsulation side)pqcSpec- optional PQC context spec (may benull)- Returns:
- responder-side
HybridKexContext - Throws:
NullPointerException- if any required argument isnull- Since:
- 1.0
- a classic
-
initiatorPairMessage
public static HybridKexContext initiatorPairMessage(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, KeyPairKey classicInitiatorKeyPair, ContextSpec classicSpec, String pqcAlgId, PublicKey pqcPeerPublic, ContextSpec pqcSpec) Creates an initiator-side hybrid KEX where the classic leg is message-based (PAIR_MESSAGE).The classic message is the SPKI encoding of the initiator's classic public key as produced by the underlying
MessageAgreementContext. The PQC message is the PQC encapsulation payload (typically KEM ciphertext).- Parameters:
session- explicit policy and audit boundaryprofile- hybrid profile defining HKDF binding and output lengthclassicAlgId- classic agreement algorithm identifier (e.g. "X25519", "ECDH", "DH")classicInitiatorKeyPair- classic initiator key pair wrapped asKeyPairKeyclassicSpec- classic context spec (may benullif supported)pqcAlgId- post-quantum agreement algorithm identifier (e.g. "ML-KEM")pqcPeerPublic- PQC peer public key (encapsulation side)pqcSpec- optional PQC context spec (may benull)- Returns:
- initiator-side
HybridKexContext - Throws:
NullPointerException- if any required argument isnull- Since:
- 1.0
-
responderPairMessage
public static HybridKexContext responderPairMessage(ZeroEchoSession session, HybridKexProfile profile, String classicAlgId, KeyPairKey classicResponderKeyPair, ContextSpec classicSpec, String pqcAlgId, PrivateKey pqcResponderPrivate, ContextSpec pqcSpec) Creates a responder-side hybrid KEX where the classic leg is message-based (PAIR_MESSAGE).The responder must call
HybridKexContext.setPeerMessage(byte[])with the initiator's hybrid message before callingHybridKexContext.deriveSecret().- Parameters:
session- explicit policy and audit boundaryprofile- hybrid profile defining HKDF binding and output lengthclassicAlgId- classic agreement algorithm identifierclassicResponderKeyPair- classic responder key pair wrapped asKeyPairKeyclassicSpec- classic context spec (may benull)pqcAlgId- post-quantum agreement algorithm identifierpqcResponderPrivate- PQC responder private key (decapsulation side)pqcSpec- optional PQC context spec (may benull)- Returns:
- responder-side
HybridKexContext - Throws:
NullPointerException- if any required argument isnull- Since:
- 1.0
-