mlkem

mlkem.fast_k_pke

mlkem.k_pke

class mlkem.k_pke.K_PKE(parameters: ParameterSet)

Bases: PKE_Interface

Pure python implementation of the PKE Interface.

decrypt(dk: bytes, c: bytes) bytes

Takes a decryption key dk and a ciphertext c, and produces a plaintext.

The algorithm first parses u’ and v’ out of the ciphertext (see encrypt for how these values are generated). It then uses the secret vector s (which is decoded from dk) to recover the message m. The equation for recovering m is \(m = v' - s^T \cdot u'\). There is also an additional step involving compressing and encoding m in order to transform it from a polynomial in \(\mathbb{Z}^n_q\) to a byte sequence.

Args:
dk (bytes): The decryption key.
c (bytes): The ciphertext message.
Returns:

bytes: The plaintext.

encrypt(ek: bytes, m: bytes, r: bytes) bytes

Takes an encryption key ek, a 32 byte plaintext message m, and randomness r as input and produces a ciphertext c.

The algorithm starts by deriving matrix A and vector t from the encryption key. It then generates a vector \(y \in R^k_q\) and noise terms \(e1 \in R^k_q\) and \(e2 \in R_q\). It then encodes the 256 bit plaintext as a polynomial with degree 255, where each bit of the plaintext is a coefficient of the polynomial. Then a new noisy equation is computed - \((A^T \cdot y + e_1, t^T \cdot y, + e_2)\). An appropriate encoding of the message polynomial is then added to the latter term. Finally, the pair (u, v) is compressed and serialized into a byte array.

Args:
ek (bytes): The encryption key.
m (bytes): The plaintext message.
r (bytes): The randomness.
Returns:

bytes: The ciphertext c = c1 + c2. c1 encodes u and c2 encodes v.

key_gen(d: bytes) tuple[bytes, bytes]

Creates a keypair used for encapsulation and decapsulation.

The decryption (private) key is a vector \(s\) of length k (where k is defined by the ML-KEM parameter set) with elements in \(R_q\). The encryption (public) key is a collection of “noisy” linear equations \((A, As + e)\) in the secret variable \(s\). The rows of matrix A, which is generated pseudorandomly, for the equation coefficients.

Args:
d (bytes): The random seed used to derive the keypair. This should come from a random source suitable for cryptographic applications.
Returns:

tuple[bytes, bytes]: The keypair with the encryption key first and the decryption key second.

class mlkem.k_pke.PKE_Interface

Bases: ABC

Interface for a public key encryption (PKE) scheme based on the module learning with errors (MLWE) problem.

Using the interface directly is NOT allowed by FIPS-203. This scheme is only IND-CPA secure (secure under a chosen plaintext attack), but not IND-CCA secure (secure under a chosen ciphertext attack). mlkem.ml_kem.ML_KEM implements the IND-CCA scheme, which is what is approved for usage in FIPS-203.

abstractmethod decrypt(dk: bytes, c: bytes) bytes

Takes a decryption key dk and a ciphertext c, and produces a plaintext.

The algorithm first parses u’ and v’ out of the ciphertext (see encrypt for how these values are generated). It then uses the secret vector s (which is decoded from dk) to recover the message m. The equation for recovering m is \(m = v' - s^T \cdot u'\). There is also an additional step involving compressing and encoding m in order to transform it from a polynomial in \(\mathbb{Z}^n_q\) to a byte sequence.

Args:
dk (bytes): The decryption key.
c (bytes): The ciphertext message.
Returns:

bytes: The plaintext.

abstractmethod encrypt(ek: bytes, m: bytes, r: bytes) bytes

Takes an encryption key ek, a 32 byte plaintext message m, and randomness r as input and produces a ciphertext c.

The algorithm starts by deriving matrix A and vector t from the encryption key. It then generates a vector \(y \in R^k_q\) and noise terms \(e1 \in R^k_q\) and \(e2 \in R_q\). It then encodes the 256 bit plaintext as a polynomial with degree 255, where each bit of the plaintext is a coefficient of the polynomial. Then a new noisy equation is computed - \((A^T \cdot y + e_1, t^T \cdot y, + e_2)\). An appropriate encoding of the message polynomial is then added to the latter term. Finally, the pair (u, v) is compressed and serialized into a byte array.

Args:
ek (bytes): The encryption key.
m (bytes): The plaintext message.
r (bytes): The randomness.
Returns:

bytes: The ciphertext c = c1 + c2. c1 encodes u and c2 encodes v.

abstractmethod key_gen(d: bytes) tuple[bytes, bytes]

Creates a keypair used for encapsulation and decapsulation.

The decryption (private) key is a vector \(s\) of length k (where k is defined by the ML-KEM parameter set) with elements in \(R_q\). The encryption (public) key is a collection of “noisy” linear equations \((A, As + e)\) in the secret variable \(s\). The rows of matrix A, which is generated pseudorandomly, for the equation coefficients.

Args:
d (bytes): The random seed used to derive the keypair. This should come from a random source suitable for cryptographic applications.
Returns:

tuple[bytes, bytes]: The keypair with the encryption key first and the decryption key second.

mlkem.ml_kem