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)
| Constant | OID | Description |
|---|---|---|
ID_ML_KEM_512 | 2.16.840.1.101.3.4.4.1 | ML-KEM-512 key encapsulation |
ID_ML_KEM_768 | 2.16.840.1.101.3.4.4.2 | ML-KEM-768 key encapsulation |
ID_ML_KEM_1024 | 2.16.840.1.101.3.4.4.3 | ML-KEM-1024 key encapsulation |
CMS OtherRecipientInfo OIDs (RFC 9629 §6.2)
| Constant | OID | Description |
|---|---|---|
ID_ORI | 1.2.840.113549.1.9.16.13 | Root arc for OtherRecipientInfo alternatives |
ID_ORI_KEM | 1.2.840.113549.1.9.16.13.3 | Identifies 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.