Skip to content

ML-KEM API Design #12824

@reaperhulk

Description

@reaperhulk

Here's a strawman, let's discuss.

A few thoughts:

  • I don't want to use public/private, but Encapsulation and Decapsulation are quite verbose. I've used Encap/Decap below but we can use the full words if people think it's better.
  • I see no reason to support/allow anything other than seed only PKCS8 for both loading and serialization.
  • Do we want to support bare seed loading? The current API proposal below does allow it similar to how we do it in Ed/X keys.
  • If we support bare seed loading then we should support bare seed serialization. We can repurpose PrivateFormat.Raw for this I suppose.
  • How do we load PKCS8? We have load_{pem,der}_{public,private}_key functions, but if we don't want to use the public/private nomenclature we may want new functions.
  • This proposal makes the parameter set a property of the class rather than a value to be passed. We could choose to expose an enum of parameter sets (768 and 1024...maybe 512 if necessary, although it seems no one is implementing that) instead of this. Go has chosen separate concrete interfaces (crypto/mlkem: new package golang/go#70122) for this and I generally think separate types are a reasonable choice here, although a consequence is that code that supports multiple MLKEM sizes will need to have type signatures like input: MLKEM768EncapKey | MLKEM1024EncapKey
class MLKEM768DecapKey:
    @classmethod
    def generate(cls) -> "MLKEM768DecapKey":
        ...

    def decap(self, ciphertext: bytes) -> bytes:
        ...

    def encap_key(self) -> "MLKEM768EncapKey":
        ...

    def decap_bytes(
        self,
        encoding: serialization.Encoding,
        format: serialization.PrivateFormat,
        encryption_algorithm: serialization.KeySerializationEncryption,
    ) -> bytes:
        ...

    @classmethod
    def from_seed_bytes(cls, data: bytes) -> "MLKEM768DecapKey":
        ...


class MLKEM768EncapKey:
    def encap(self) -> Tuple[bytes, bytes]:
        """
        Note that this tuple should be shared_secret, ciphertext to match the spec
        """
        ...

    def encap_bytes(
        self,
        encoding: serialization.Encoding,
        format: serialization.PublicFormat,
    ) -> bytes:
        ...

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions