Skip to main content

Kem

Trait Kem 

Source
pub trait Kem: Sized {
    type PublicKey: Clone;
    type SecretKey: Clone;
    type EncappedKey: Clone;

    const HPKE_KEM_ID: u16;
    const SHARED_SECRET_SIZE: usize;
    const ENCAPPED_KEY_SIZE: usize;
    const PUBLIC_KEY_SIZE: usize;
    const SECRET_KEY_SIZE: usize;
    const RANDOMNESS_SIZE: usize = Self::SECRET_KEY_SIZE;
Show 13 methods // Required methods fn derive_keypair( input_keying_material: &[u8], ) -> Result<(Self::SecretKey, Self::PublicKey), HpkeError>; fn derive_public_key(secret_key: &Self::SecretKey) -> Self::PublicKey; fn public_key_to_bytes( out: &mut [u8], public_key: &Self::PublicKey, ) -> Result<(), HpkeError>; fn public_key_from_bytes(bytes: &[u8]) -> Result<Self::PublicKey, HpkeError>; fn secret_key_to_bytes( out: &mut [u8], secret_key: &Self::SecretKey, ) -> Result<(), HpkeError>; fn secret_key_from_bytes(bytes: &[u8]) -> Result<Self::SecretKey, HpkeError>; fn encapped_key_to_bytes( out: &mut [u8], encapped_key: &Self::EncappedKey, ) -> Result<(), HpkeError>; fn encapped_key_from_bytes( bytes: &[u8], ) -> Result<Self::EncappedKey, HpkeError>; fn encap_with_ephemeral( ephemeral_secret_key: &Self::SecretKey, recipient_public_key: &Self::PublicKey, ) -> Result<(Hash, Self::EncappedKey), HpkeError>; fn decap( encapped_key: &Self::EncappedKey, recipient_secret_key: &Self::SecretKey, ) -> Result<Hash, HpkeError>; // Provided methods fn generate_keypair( ) -> Result<(Self::SecretKey, Self::PublicKey), HpkeError> { ... } fn encap( recipient_public_key: &Self::PublicKey, ) -> Result<(Hash, Self::EncappedKey), HpkeError> { ... } fn encap_deterministic( recipient_public_key: &Self::PublicKey, randomness: &[u8], ) -> Result<(Hash, Self::EncappedKey), HpkeError> { ... }
}
Expand description

Key encapsulation mechanism (KEM) usable within an HPKE ciphersuite.

A KEM encapsulates a shared secret against a public key: the sender runs Kem::encap to obtain a (shared secret, encapsulated key) pair, and the recipient runs Kem::decap on the encapsulated key to recover the same shared secret.

draft-ietf-hpke-hpke-05 removed the authenticated modes of RFC 9180, so a KEM only needs encap/decap; the AuthEncap/AuthDecap interface is not part of HPKE anymore. Sender authentication is provided by the pre-shared key mode or by a signature over the (encapped_key, ciphertext) tuple.

§Example

use hpke::kem::{Kem, X25519HkdfSha256};

let (secret_key, public_key) = X25519HkdfSha256::generate_keypair().unwrap();
let (shared_secret, encapped_key) = X25519HkdfSha256::encap(&public_key).unwrap();
let decapsulated = X25519HkdfSha256::decap(&encapped_key, &secret_key).unwrap();
assert_eq!(shared_secret.as_ref(), decapsulated.as_ref());

§Custom KEMs

Implement this trait to use a custom KEM (e.g. ML-KEM for the post-quantum HPKE draft) inside HPKE. The shared secret returned by encap/decap must be exactly Kem::SHARED_SECRET_SIZE bytes long. Use Kdf::labeled_extract/Kdf::labeled_expand (two-stage KDFs) or Kdf::labeled_derive (single-stage KDFs) to derive keys exactly like the KEMs in draft-ietf-hpke-hpke-05 do.

Required Associated Constants§

Source

const HPKE_KEM_ID: u16

The HPKE KEM identifier (draft-ietf-hpke-hpke-05 Section 7.1, IANA “HPKE KEM Identifiers”), used to build the ciphersuite suite_id.

Source

const SHARED_SECRET_SIZE: usize

The size of the shared secret produced by this KEM.

Must not exceed 64 bytes, the maximum capacity of [struct@Hash].

Source

const ENCAPPED_KEY_SIZE: usize

The size of an encapsulated key.

Source

const PUBLIC_KEY_SIZE: usize

The size of a serialized public key.

Source

const SECRET_KEY_SIZE: usize

The size of a serialized secret key.

Provided Associated Constants§

Source

const RANDOMNESS_SIZE: usize = Self::SECRET_KEY_SIZE

The size of the randomness consumed by Kem::encap_deterministic.

Defaults to Kem::SECRET_KEY_SIZE, the size of an ephemeral secret key / the DeriveKeyPair input for the Diffie-Hellman KEMs. KEMs whose deterministic encapsulation takes a different amount of randomness (e.g. MLKEM768X25519) override this.

Required Associated Types§

Source

type PublicKey: Clone

The public (encapsulation) key type.

Source

type SecretKey: Clone

The secret (decapsulation) key type.

Source

type EncappedKey: Clone

The encapsulated key type (the KEM ciphertext sent alongside the first encrypted message).

Required Methods§

Source

fn derive_keypair( input_keying_material: &[u8], ) -> Result<(Self::SecretKey, Self::PublicKey), HpkeError>

Deterministically derives a key pair from input keying material.

input_keying_material SHOULD be at least Kem::SECRET_KEY_SIZE bytes long and contain at least that many bytes of entropy (draft-ietf-hpke-hpke-05 Sections 7.1.3 and 9.2.1). It MUST NOT be reused for any other purpose, in particular not with another KEM.

§Errors

Returns HpkeError::DeriveKeyPairError when no valid key pair could be derived (rejection sampling exhausted).

Source

fn derive_public_key(secret_key: &Self::SecretKey) -> Self::PublicKey

Derives the public key of a secret key.

Source

fn public_key_to_bytes( out: &mut [u8], public_key: &Self::PublicKey, ) -> Result<(), HpkeError>

Serializes a public key into out, which must be exactly Kem::PUBLIC_KEY_SIZE bytes long.

§Errors

Returns HpkeError::DeserializeError when out has the wrong length.

Source

fn public_key_from_bytes(bytes: &[u8]) -> Result<Self::PublicKey, HpkeError>

Deserializes a public key from bytes, which must be exactly Kem::PUBLIC_KEY_SIZE bytes long and a valid, fully validated public key.

§Errors

Returns HpkeError::DeserializeError when bytes has the wrong length or does not encode a valid public key.

Source

fn secret_key_to_bytes( out: &mut [u8], secret_key: &Self::SecretKey, ) -> Result<(), HpkeError>

Serializes a secret key into out, which must be exactly Kem::SECRET_KEY_SIZE bytes long.

§Errors

Returns HpkeError::DeserializeError when out has the wrong length.

Source

fn secret_key_from_bytes(bytes: &[u8]) -> Result<Self::SecretKey, HpkeError>

Deserializes a secret key from bytes, which must be exactly Kem::SECRET_KEY_SIZE bytes long.

§Errors

Returns HpkeError::DeserializeError when bytes has the wrong length or does not encode a valid secret key.

Source

fn encapped_key_to_bytes( out: &mut [u8], encapped_key: &Self::EncappedKey, ) -> Result<(), HpkeError>

Serializes an encapsulated key into out, which must be exactly Kem::ENCAPPED_KEY_SIZE bytes long.

§Errors

Returns HpkeError::DeserializeError when out has the wrong length.

Source

fn encapped_key_from_bytes(bytes: &[u8]) -> Result<Self::EncappedKey, HpkeError>

Deserializes an encapsulated key from bytes, which must be exactly Kem::ENCAPPED_KEY_SIZE bytes long.

§Errors

Returns HpkeError::DeserializeError when bytes has the wrong length or does not encode a valid encapsulated key.

Source

fn encap_with_ephemeral( ephemeral_secret_key: &Self::SecretKey, recipient_public_key: &Self::PublicKey, ) -> Result<(Hash, Self::EncappedKey), HpkeError>

Encapsulates a shared secret against recipient_public_key, using the given ephemeral secret key ephemeral_secret_key.

Returns the shared secret and the encapsulated key that the owner of recipient_public_key can use to recover it. This is the deterministic variant of Kem::encap; it exists for protocols that need reproducible encapsulation (e.g. test vectors) and MUST NOT be called with a non-fresh ephemeral_secret_key.

§Errors

Returns HpkeError::EncapError when recipient_public_key is invalid.

Source

fn decap( encapped_key: &Self::EncappedKey, recipient_secret_key: &Self::SecretKey, ) -> Result<Hash, HpkeError>

Recovers the shared secret encapsulated in encapped_key with the secret key recipient_secret_key.

§Errors

Returns HpkeError::DecapError when encapped_key is invalid or when the key exchange fails.

Provided Methods§

Source

fn generate_keypair() -> Result<(Self::SecretKey, Self::PublicKey), HpkeError>

Generates a fresh random key pair using the operating system’s random number generator.

§Errors

Returns HpkeError::Random when the operating system’s random number generator is unavailable or fails.

Source

fn encap( recipient_public_key: &Self::PublicKey, ) -> Result<(Hash, Self::EncappedKey), HpkeError>

Encapsulates a fresh shared secret against recipient_public_key using a freshly generated ephemeral key pair.

§Errors

Returns HpkeError::EncapError when recipient_public_key is invalid, or HpkeError::Random when the operating system’s random number generator is unavailable or fails.

Source

fn encap_deterministic( recipient_public_key: &Self::PublicKey, randomness: &[u8], ) -> Result<(Hash, Self::EncappedKey), HpkeError>

Encapsulates a shared secret against recipient_public_key from caller-provided randomness (EncapDerand).

This is the deterministic equivalent of Kem::encap, intended for test vectors and protocols that need reproducible encapsulation. randomness MUST be exactly Kem::RANDOMNESS_SIZE bytes long, uniformly random, and MUST NOT be reused across encapsulations.

The default implementation derives an ephemeral key pair from randomness and forwards to Kem::encap_with_ephemeral, which is correct for the Diffie-Hellman KEMs. KEMs with a different deterministic-encapsulation interface (e.g. MLKEM768X25519, whose randomness is the 64-byte encapsulation randomness rather than a secret key) override this.

§Errors

Returns HpkeError::DeserializeError when randomness does not have exactly Kem::RANDOMNESS_SIZE bytes, or HpkeError::EncapError when recipient_public_key is invalid.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl Kem for MLKEM768X25519

Source§

const HPKE_KEM_ID: u16 = 0x647a

Source§

const SHARED_SECRET_SIZE: usize = crypto::xwing::SHARED_SECRET_SIZE

Source§

const ENCAPPED_KEY_SIZE: usize = crypto::xwing::CIPHERTEXT_SIZE

Source§

const PUBLIC_KEY_SIZE: usize = crypto::xwing::PUBLIC_KEY_SIZE

Source§

const SECRET_KEY_SIZE: usize = crypto::xwing::SECRET_KEY_SIZE

Source§

const RANDOMNESS_SIZE: usize = 64

Source§

type PublicKey = PublicKey

Source§

type SecretKey = SecretKey

Source§

type EncappedKey = [u8; 1120]

Source§

impl Kem for P256HkdfSha256

Source§

const HPKE_KEM_ID: u16 = 0x0010

Source§

const SHARED_SECRET_SIZE: usize = <HkdfSha256 as Kdf>::OUTPUT_SIZE

Source§

const ENCAPPED_KEY_SIZE: usize = <P256Group as DiffieHellmanGroup>::PUBLIC_KEY_SIZE

Source§

const PUBLIC_KEY_SIZE: usize = <P256Group as DiffieHellmanGroup>::PUBLIC_KEY_SIZE

Source§

const SECRET_KEY_SIZE: usize = <P256Group as DiffieHellmanGroup>::SECRET_KEY_SIZE

Source§

type PublicKey = PublicKey

Source§

type SecretKey = SecretKey

Source§

type EncappedKey = PublicKey

Source§

impl Kem for P521HkdfSha512

Source§

const HPKE_KEM_ID: u16 = 0x0012

Source§

const SHARED_SECRET_SIZE: usize = <HkdfSha512 as Kdf>::OUTPUT_SIZE

Source§

const ENCAPPED_KEY_SIZE: usize = <P521Group as DiffieHellmanGroup>::PUBLIC_KEY_SIZE

Source§

const PUBLIC_KEY_SIZE: usize = <P521Group as DiffieHellmanGroup>::PUBLIC_KEY_SIZE

Source§

const SECRET_KEY_SIZE: usize = <P521Group as DiffieHellmanGroup>::SECRET_KEY_SIZE

Source§

type PublicKey = PublicKey

Source§

type SecretKey = SecretKey

Source§

type EncappedKey = PublicKey

Source§

impl Kem for X25519HkdfSha256

Source§

const HPKE_KEM_ID: u16 = 0x0020

Source§

const SHARED_SECRET_SIZE: usize = <HkdfSha256 as Kdf>::OUTPUT_SIZE

Source§

const ENCAPPED_KEY_SIZE: usize = <X25519Group as DiffieHellmanGroup>::PUBLIC_KEY_SIZE

Source§

const PUBLIC_KEY_SIZE: usize = <X25519Group as DiffieHellmanGroup>::PUBLIC_KEY_SIZE

Source§

const SECRET_KEY_SIZE: usize = <X25519Group as DiffieHellmanGroup>::SECRET_KEY_SIZE

Source§

type PublicKey = PublicKey

Source§

type SecretKey = SecretKey

Source§

type EncappedKey = PublicKey