mlkem.math

This module is only relevant to the pure python implementation and does not apply to the default (C extension) implementation of this package.

mlkem.math.matrix

class mlkem.math.matrix.Matrix(rows: int, cols: int, entries: list[T] | None = None, constructor: Callable[[], T] | None = None)
__add__(other: Matrix[T]) Matrix[T]

Add two matrices together.

The two matrices must have the same dimensions, otherwise a ValueError is raised. Addition is done by going element by element, thus for \(C = A + B\) we would have \(C_{i,j} = A_{i,j} + B_{i,j}\) for all valid indices \((i, j)\).

Args:
other (Matrix): The matrix to add.
Returns:

Matrix: The sum of the matrices.

__getitem__(index: tuple[int, int]) T

Get the element at index (i, j) of the matrix.

The elements of the matrix are interpreted in row-major order. Since the matrix is represented as a flat list, this means that each row advances the index by the amount of columns in the matrix.

Args:
index (tuple[int, int]): A tuple of (row index, column index).
Returns:

T: The element at index (i, j) of the matrix.

__init__(rows: int, cols: int, entries: list[T] | None = None, constructor: Callable[[], T] | None = None) None

Initialize a matrix with the given dimensions and entries.

entries or constructor must be provided. If entries is provided it must be a list of exactly rows * cols elements. The elements should be in row-major order. If constructor is provided then it should be a callable that takes no arguments and returns an instance of T. If neither is provided a ValueError is raised. If both are provided then entries is used.

Args:
rows (int): The number of rows in the matrix.
cols (int): The number of columns in the matrix.
entries (list[T] | None): The values of the matrix elements.
constructor (Callable[[], T] | None): A function to initialize all matrix elements.
__mul__(g: T | Matrix[T]) Matrix[T]

Multiply a matrix.

Two versions of this algorithm exist. One is multiplication by a scalar, the other is multiplication by a matrix. When multiplying by a scalar g, the multiplication is applied to each entry in the matrix such that if \(C = A * g\) then \(C_{i,j} = A_{i,j} * g\). For multiplication by a matrix, the standard matrix multiplication algorithm is applied. If \(C = A * B\) then \(C_{i,j}\) is calculated as the dot product of the i-th row of A and the j-th column of B.

Args:
g (T | Matrix): The scalar or matrix to multiply by.
Returns:

Matrix: The result of the multiplication.

__setitem__(index: tuple[int, int], value: T) None

Set the element at index (i, j) of the matrix.

The elements of the matrix are interpreted in row-major order. Since the matrix is represented as a flat list, this means that each row advances the index by the amount of columns in the matrix.

Args:
index (tuple[int, int]): A tuple of (row index, column index).
value (T): The value to set at the given index.

mlkem.math.field

class mlkem.math.field.Zm(val: int, m: int)

Represents elements of the field \(\mathbb{Z}_m\).

__add__(y: Zm) Zm

Add two elements x and y where \(x, y \in \mathbb{Z}_m\).

The resulting element will also be in \(\mathbb{Z}_m\).

Args:
y (Zm): The element to add to x (represented by self).
Returns:

Zm: An element equal to \(x + y \pmod{m}\).

__init__(val: int, m: int)

Initialize an element in the field \(\mathbb{Z}_m\).

Args:
val (int): The (unreduced) value of the field element.
m (int): The modulus / order of the field.
__mul__(y: Zm) Zm

Multiply two elements x and y where \(x, y \in \mathbb{Z}_m\).

The resulting element will also be in \(\mathbb{Z}_m\).

Args:
y (Zm): The element to multiply x by (represented by self).
Returns:

Zm: An element equal to \(x * y \pmod{m}\).

__sub__(y: Zm) Zm

Subtract two elements x and y where \(x, y \in \mathbb{Z}_m\).

The resulting element will also be in \(\mathbb{Z}_m\).

Args:
y (Zm): The element to subtract from x (represented by self).
Returns:

Zm: An element equal to \(x - y \pmod{m}\).

mlkem.math.polynomial_ring

class mlkem.math.polynomial_ring.PolynomialRing(coefficients: list[Zm] | None = None, representation: RingRepresentation = RingRepresentation.STANDARD)

Represents elements of the ring \(\mathbb{Z}^n_q\).

__add__(g: PolynomialRing) PolynomialRing

Add two elements f and g where \(f, g \in \mathbb{Z}^n_m\).

The resulting element will also be in \(\mathbb{Z}^n_m\).

Args:
g (PolynomialRing): The element to add to f (represent by self).
Returns:

PolynomialRing: An element equal to \(f + g\).

__eq__(other: object) bool

Compare two polynomial rings for equality.

They must have the following conditions met to be equal:
  • The same representation

  • The same coefficients

  • The same order (length of coefficients)

Args:
other (object): The object to compare to (must be a PolynomialRing instance).
Returns:

bool: Whether the two objects are equal.

__getitem__(index: int) Zm

Get the coefficient at index.

Args:
index (int): The index of the coefficient to get.
Returns:

mlkem.math.field.Zm: The value of the coefficient.

__init__(coefficients: list[Zm] | None = None, representation: RingRepresentation = RingRepresentation.STANDARD)

Initialize a polynomial ring element.

The coefficients are indexed based on the degree of their corresponding term. In other words, coefficients[i] corresponds to the coefficient \(a_i\) in the term \(a_i X^i\). If no coefficients are provided then all coefficients are initialized to 0.

Args:
coefficients (list[mlkem.math.field.Zm] | None): The coefficients of the polynomial.
representation (RingRepresentation): The mathematical representation of the polynomial.
__mul__(a: Zm | PolynomialRing) PolynomialRing

Multiply by an element in \(\mathbb{Z}^m\) or \(\mathbb{Z}^n_m\).

If \(a \in \mathbb{Z}_m\) and \(f \in \mathbb{Z}^n_m\) the i-th coefficient of the polynomial \(a \cdot f \in \mathbb{Z}^n_m\) is equal to \(a \cdot f_i \pmod{m}\).

If \(a \in \mathbb{Z}^n_m\) and \(f \in \mathbb{Z}^n_m\) then both polynomials must be in NTT representation. NTT multiplication is then used to multiply the two together.

Args:
a (mlkem.math.field.Zm | PolynomialRing): The value to multiply by.
Returns:

PolynomialRing: The element in \(\mathbb{Z}^n_m\) multiplied by a.

__rmul__(a: Zm | PolynomialRing) PolynomialRing

Equivalent to self.__mul__(a).

__setitem__(index: int, value: Zm) None

Set the coefficient at index to value.

Args:
index (int): The index of the coefficient to set.
value (mlkem.math.field.Zm): The value to set.
__sub__(g: PolynomialRing) PolynomialRing

Subtract two elements f and g where \(f, g \in \mathbb{Z}^n_m\).

The resulting element will also be in \(\mathbb{Z}^n_m\).

Args:
g (PolynomialRing): The element to subtract from f (represent by self).
Returns:

PolynomialRing: An element equal to \(f - g\).

class mlkem.math.polynomial_ring.RingRepresentation(*values)

The mathmetical representation of a PolynomialRing.

  • STANDARD = The conventional representation.

  • NTT = The representation after the number theoretic transform (NTT) has been applied.