Skip to content

crypto/mlkem: new package #70122

@FiloSottile

Description

@FiloSottile

ML-KEM (FIPS 203, formerly Kyber) is a postquantum (#64537) key exchange method that was recently standardized and is being deployed across the industry. We already have an implementation in the Go tree as part of #67061.

I propose we expose a new package implementing ML-KEM-768 and ML-KEM-1024. Ideally we'd implement only ML-KEM-768, because it's what's being deployed in most settings and because playing the "security levels" game is an obsolete concept, but alas CNSA 2.0 requires ML-KEM-1024 across the board. We have seen no deployments of ML-KEM-512, so we are leaving that out at least for now. This happens to match what BoringSSL implemented. We also only support seeds as the decapsulation key format. This should match the direction the IETF is taking.

The proposed API uses separate types for -768 and -1024 to avoid making the -768 values unnecessarily large. I'm not a big fan of the numeric suffixes, and I'm especially unhappy that 1024 sorts before 768 in godoc, but couldn't find better names.

We are not proposing a KEM interface yet, but note that the methods should be general enough to allow one in the future.

const (
	SharedKeySize = 32
	SeedSize      = 64
)

const (
	CiphertextSize768       = 1088
	EncapsulationKeySize768 = 1184
)
    ML-KEM-768 parameters.

type DecapsulationKey768 struct {
	// Has unexported fields.
}
    A DecapsulationKey768 is the secret key used to decapsulate a shared key
    from a ciphertext. It includes various precomputed values.

func GenerateKey768() (*DecapsulationKey768, error)
    GenerateKey768 generates a new decapsulation key, drawing random bytes from
    crypto/rand. The decapsulation key must be kept secret.

func NewDecapsulationKey768(seed []byte) (*DecapsulationKey768, error)
    NewDecapsulationKey768 parses a decapsulation key from a 64-byte seed in the
    "d || z" form. The seed must be uniformly random.

func (dk *DecapsulationKey768) Bytes() []byte
    Bytes returns the decapsulation key as a 64-byte seed in the "d || z" form.

    The decapsulation key must be kept secret.

func (dk *DecapsulationKey768) Decapsulate(ciphertext []byte) (sharedKey []byte, err error)
    Decapsulate generates a shared key from a ciphertext and a decapsulation
    key. If the ciphertext is not valid, Decapsulate returns an error.

    The shared key must be kept secret.

func (dk *DecapsulationKey768) EncapsulationKey() *EncapsulationKey768
    EncapsulationKey returns the public encapsulation key necessary to produce
    ciphertexts.

type EncapsulationKey768 struct {
	// Has unexported fields.
}
    An EncapsulationKey768 is the public key used to produce ciphertexts to be
    decapsulated by the corresponding DecapsulationKey768.

func NewEncapsulationKey768(encapsulationKey []byte) (*EncapsulationKey768, error)
    NewEncapsulationKey768 parses an encapsulation key from its encoded form. If
    the encapsulation key is not valid, NewEncapsulationKey768 returns an error.

func (ek *EncapsulationKey768) Bytes() []byte
    Bytes returns the encapsulation key as a byte slice.

func (ek *EncapsulationKey768) Encapsulate() (ciphertext, sharedKey []byte)
    Encapsulate generates a shared key and an associated ciphertext from an
    encapsulation key, drawing random bytes from crypto/rand.

    The shared key must be kept secret.

const (
	CiphertextSize1024       = 1568
	EncapsulationKeySize1024 = 1568
)
    ML-KEM-1024 parameters.

type DecapsulationKey1024 struct {
	// Has unexported fields.
}

func GenerateKey1024() (*DecapsulationKey1024, error)
func NewDecapsulationKey1024(seed []byte) (*DecapsulationKey1024, error)
func (dk *DecapsulationKey1024) Bytes() []byte
func (dk *DecapsulationKey1024) Decapsulate(ciphertext []byte) (sharedKey []byte, err error)
func (dk *DecapsulationKey1024) EncapsulationKey() *EncapsulationKey1024

type EncapsulationKey1024 struct {
	// Has unexported fields.
}

func NewEncapsulationKey1024(encapsulationKey []byte) (*EncapsulationKey1024, error)
func (ek *EncapsulationKey1024) Bytes() []byte
func (ek *EncapsulationKey1024) Encapsulate() (ciphertext, sharedKey []byte)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Accepted

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions