qfall_math/integer_mod_q/mat_ntt_polynomial_ring_zq.rs
1// Copyright 2025 Jan Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! [`MatNTTPolynomialRingZq`] containts the NTT representations of matrices over polynomials.
10
11use crate::{integer::Z, integer_mod_q::ModulusPolynomialRingZq};
12use derive_more::Display;
13use serde::{Deserialize, Serialize};
14
15mod arithmetic;
16mod cmp;
17mod from;
18mod get;
19mod sample;
20
21/// [`MatNTTPolynomialRingZq`] contains the NTT representation of a matrix over polynomials with respect to
22/// a [`NTTBasisPolynomialRingZq`](super::NTTBasisPolynomialRingZq) that itself isn't aware of.
23///
24/// Any polynomial in NTT representation in row `i` and column `j` can be accessed via `matrix[j * nr_columns + i]`.
25///
26/// Attributes
27/// - `matrix`: holds the matrix entries with its coefficients
28/// - `nr_rows`: the number of rows of the matrix
29/// - `nr_columns`: the number of columns of the matrix
30/// - `modulus`: the [`ModulusPolynomialRingZq`] defining the modulus `q`, the ring `Z_q[X]/f(X)`, and
31/// the NTT transform [`NTTBasisPolynomialRingZq`](crate::integer_mod_q::NTTBasisPolynomialRingZq)
32///
33/// # Examples
34/// ```
35/// use qfall_math::integer_mod_q::{Modulus, MatPolynomialRingZq, MatNTTPolynomialRingZq, ModulusPolynomialRingZq};
36/// use std::str::FromStr;
37///
38/// // setup modulus with ability to transform to NTT
39/// let mut modulus = ModulusPolynomialRingZq::from_str("5 1 0 0 0 1 mod 257").unwrap();
40/// modulus.set_ntt_unchecked(64);
41///
42/// // sample random matrix
43/// let mat_rnd = MatNTTPolynomialRingZq::sample_uniform(2, 2, &modulus);
44/// // or instantiate matrix from MatPolynomialRingZq
45/// let mat_poly_ring = MatPolynomialRingZq::identity(2, 2, &modulus);
46/// let mat_ntt_poly_ring = MatNTTPolynomialRingZq::from(&mat_poly_ring);
47///
48/// // multiply, add and subtract objects
49/// let mut tmp_mat_ntt = mat_ntt_poly_ring * &mat_rnd;
50/// tmp_mat_ntt += &mat_rnd;
51/// tmp_mat_ntt -= &mat_rnd;
52///
53/// // Return to MatPolynomialRingZq
54/// let res = tmp_mat_ntt.inv_ntt();
55/// ```
56#[derive(PartialEq, Eq, Serialize, Deserialize, Display, Clone, Debug)]
57#[display("{} / {}", print_vec_z(&self.matrix), self.modulus)]
58pub struct MatNTTPolynomialRingZq {
59 pub matrix: Vec<Z>,
60 pub nr_rows: usize,
61 pub nr_columns: usize,
62 pub modulus: ModulusPolynomialRingZq,
63}
64
65/// Quick solution to print a vector of [`Z`] values in the format `[1, 2, 3, 4, 5]`.
66pub(crate) fn print_vec_z(vector: &Vec<Z>) -> String {
67 let mut out = String::new();
68 for v in vector {
69 out.push_str(&format!("{v}, "));
70 }
71 // Remove last whitespace and comma
72 out.pop().unwrap();
73 out.pop().unwrap();
74 format!("[{out}]")
75}