Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CMS-KEM Types

synta.kem provides KEMRecipientInfo and CMSORIforKEMOtherInfo for RFC 9629 quantum-safe KEM recipient structures, along with ML-KEM (FIPS 203) OID constants.

KEMRecipientInfo is carried as an OtherRecipientInfo alternative identified by id-ori-kem (1.2.840.113549.1.9.16.13.3).

import synta.kem as kem

These types are also re-exported from synta.cms.

KEMRecipientInfo

RFC 9629 §5 recipient structure for KEM-based key transport.

class KEMRecipientInfo:
    @staticmethod
    def from_der(data: bytes) -> KEMRecipientInfo: ...
    def to_der(self) -> bytes: ...

    version: int                             # always 0
    recipient_id: bytes                      # raw RecipientIdentifier CHOICE TLV
    kem_algorithm_oid: ObjectIdentifier      # KEM algorithm (e.g. ML-KEM-768)
    kem_algorithm_params: bytes | None
    kem_ciphertext: bytes                    # KEM ciphertext (kemct field)
    kdf_algorithm_oid: ObjectIdentifier      # key-derivation algorithm
    kdf_algorithm_params: bytes | None
    kek_length: int                          # KEK length in bytes (1–65535)
    ukm: bytes | None                        # user keying material
    key_encryption_algorithm_oid: ObjectIdentifier  # key-wrap algorithm
    key_encryption_algorithm_params: bytes | None
    encrypted_key: bytes                     # encrypted content-encryption key

CMSORIforKEMOtherInfo

RFC 9629 §5.3 — otherInfo input to the KDF when deriving a KEK from a KEM shared secret.

class CMSORIforKEMOtherInfo:
    @staticmethod
    def from_der(data: bytes) -> CMSORIforKEMOtherInfo: ...
    def to_der(self) -> bytes: ...

    key_encryption_algorithm_oid: ObjectIdentifier
    key_encryption_algorithm_params: bytes | None
    kek_length: int
    ukm: bytes | None

OID constants

ML-KEM OIDs (FIPS 203)

ConstantOIDDescription
ID_ML_KEM_5122.16.840.1.101.3.4.4.1ML-KEM-512 key encapsulation
ID_ML_KEM_7682.16.840.1.101.3.4.4.2ML-KEM-768 key encapsulation
ID_ML_KEM_10242.16.840.1.101.3.4.4.3ML-KEM-1024 key encapsulation

CMS OtherRecipientInfo OIDs (RFC 9629 §6.2)

ConstantOIDDescription
ID_ORI1.2.840.113549.1.9.16.13Root arc for OtherRecipientInfo alternatives
ID_ORI_KEM1.2.840.113549.1.9.16.13.3Identifies a KEMRecipientInfo

Usage

import synta
import synta.kem as kem

# Parse a KEMRecipientInfo from an OtherRecipientInfo body
kri = kem.KEMRecipientInfo.from_der(ori_body_der)
print(f"KEM algorithm: {kri.kem_algorithm_oid}")
print(f"KDF algorithm: {kri.kdf_algorithm_oid}")
print(f"KEK length:    {kri.kek_length}")
print(f"ciphertext:    {kri.kem_ciphertext.hex()}")

# Check if this is an ML-KEM-768 recipient
if kri.kem_algorithm_oid == kem.ID_ML_KEM_768:
    # Decapsulate with a PrivateKey
    priv_key = synta.PrivateKey.from_der(kem_priv_der)
    shared_secret = priv_key.kem_decapsulate(kri.kem_ciphertext)
    # Then apply KDF (kri.kdf_algorithm_oid) over shared_secret + kri.ukm to derive KEK

See also Keys for PublicKey.kem_encapsulate() and PrivateKey.kem_decapsulate(), and CMS Overview for the full module import.