Hybrid keys

A hybrid key combines a post-quantum key with a traditional one: the result stays secure as long as at least one of the two algorithms is secure. It protects against quantum computers (thanks to the post-quantum algorithm) without relying only on an algorithm that is still relatively new (the traditional one is still there, should the post-quantum one fail).

The combination is selected by the param_set argument, one of the members of the enum Crypto.PublicKey.Hybrid.ParamSet (also available as constants at the module level, for instance Hybrid.MLKEM768_X25519). The parameter set also decides what the key can be used for.

Currently, hybrid keys can only be generated, and used with HPKE: they cannot be exported or imported.

Hybrid KEMs (ML-KEM + ECDH)

A hybrid KEM combines a post-quantum KEM (ML-KEM) with a traditional one (ECDH), to agree on a shared secret. This module implements the hybrid KEM MLKEM768-X25519 of draft-irtf-cfrg-concrete-hybrid-kems, also used by HPKE (draft-ietf-hpke-pq):

Hybrid KEM

Constant

Components

Public key

Ciphertext

MLKEM768-X25519

Hybrid.MLKEM768_X25519

ML-KEM-768 and X25519

1216 bytes

1120 bytes

MLKEM768-X25519 is the same as X-Wing. The other hybrid KEMs of the draft (MLKEM768-P256 and MLKEM1024-P384) are not supported yet, as their definition may still change.

A private key is a seed of 32 random bytes: the ML-KEM key and the ECDH key are both derived from it. The two private keys are never used on their own, or with another algorithm. The public key is the ML-KEM public key, followed by the X25519 public key (32 bytes).

With this module you can generate a new hybrid KEM key, and get its public key:

>>> from Crypto.PublicKey import Hybrid
>>>
>>> key = Hybrid.generate(param_set=Hybrid.MLKEM768_X25519)
>>> pub_key = key.public_key()

To encrypt data with these keys, use HPKE (Crypto.Protocol.HPKE).

API

Hybrid keys: a post-quantum key combined with a traditional one.

Currently, the only supported keys are those of the hybrid KEM X-Wing (ML-KEM-768 combined with X25519).

class Crypto.PublicKey.Hybrid.ParamSet(value)

The combinations of a post-quantum and a traditional algorithm. The value of each member is the name of the combination.

Currently, the only member is a hybrid KEM (draft-irtf-cfrg-concrete-hybrid-kems, Section 4).

MLKEM768_X25519 = 'MLKEM768-X25519'

ML-KEM-768 and X25519 (same as X-Wing)

Crypto.PublicKey.Hybrid.MLKEM768_X25519 = ParamSet.MLKEM768_X25519

Same as ParamSet.MLKEM768_X25519

class Crypto.PublicKey.Hybrid.HybridKey(*, param_set, seed=None, pk=None)

Class defining a hybrid key (private or public): a post-quantum key and a traditional key, combined as defined by its parameter set. For the hybrid KEMs, an ML-KEM key and an ECDH key, as in draft-irtf-cfrg-concrete-hybrid-kems. Do not instantiate directly. Use generate() instead.

Variables:

param_set (ParamSet) – The combination of algorithms.

has_private()

True if this is a private key.

Return type:

bool

public_key()

A matching hybrid public key.

Return type:

HybridKey

Returns:

a new HybridKey object

Crypto.PublicKey.Hybrid.generate(*, param_set, randfunc=None)

Generate a new hybrid private key.

Parameters:
  • param_set (ParamSet) – Mandatory. The combination of algorithms, for instance Hybrid.MLKEM768_X25519.

  • randfunc (callable) – Optional. The RNG to read the seed from (32 bytes for the hybrid KEMs). If None, Crypto.Random.get_random_bytes() is used.

Returns:

a new private key

Return type:

HybridKey