qfall_math/integer_mod_q/polynomial_ring_zq.rs
1// Copyright © 2023 Marvin Beckmann
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//! [`PolynomialRingZq`] is a type of ring over PolyOverZq/f(X).
10//! Where f(X) is a [`PolyOverZq`](crate::integer_mod_q::PolyOverZq).
11//! This implementation uses the [FLINT](https://flintlib.org/) library.
12
13// For **DEVELOPERS**: Many functions assume that the [`PolynomialRingZq`] instances are reduced.
14// To avoid unnecessary checks and reductions, always return canonical/reduced
15// values. The end-user should be unable to obtain a non-reduced value.
16// Therefore, the DEVELOPER has to call the [`PolynomialRingZq::reduce`], whenever
17// a computation may exceed the modulus, because it is not reduced automatically
18
19use super::ModulusPolynomialRingZq;
20use crate::integer::PolyOverZ;
21use derive_more::Display;
22use serde::{Deserialize, Serialize};
23use std::fmt;
24
25mod arithmetic;
26mod cmp;
27mod coefficient_embedding;
28mod from;
29mod get;
30mod norm;
31mod properties;
32mod reduce;
33mod sample;
34mod set;
35mod to_string;
36mod unsafe_functions;
37
38/// [`PolynomialRingZq`] represents polynomials over the finite field
39/// [`PolyOverZq`](crate::integer_mod_q::PolyOverZq)/f(X) where f(X) is a polynomial over [`Zq`](super::Zq).
40///
41/// Attributes
42/// - `poly`: holds the value
43/// - `modulus`: holds the modulus q and f(X)
44///
45/// # Examples
46/// ```
47/// # use qfall_math::error::MathError;
48/// use qfall_math::integer::PolyOverZ;
49/// use qfall_math::integer_mod_q::ModulusPolynomialRingZq;
50/// use qfall_math::integer_mod_q::PolyOverZq;
51/// use qfall_math::integer_mod_q::PolynomialRingZq;
52/// use std::str::FromStr;
53///
54/// let poly_mod = PolyOverZq::from_str("3 1 0 1 mod 17").unwrap();
55/// let modulus = ModulusPolynomialRingZq::from(poly_mod);
56///
57/// // instantiation
58/// let a = PolynomialRingZq::from((PolyOverZ::from(5), &modulus));
59/// let b = PolynomialRingZq::from((PolyOverZ::from_str("2 1 5").unwrap(), &modulus));
60/// let _ = a.clone();
61///
62/// // arithmetics
63/// let _ = &a + &b;
64/// let _ = &a * &b;
65///
66/// // to_string incl. (de-)serialization
67/// assert_eq!("1 5 / 3 1 0 1 mod 17", &a.to_string());
68/// let _ = serde_json::to_string(&a).unwrap();
69///
70/// # Ok::<(), MathError>(())
71/// ```
72#[derive(PartialEq, Eq, Serialize, Deserialize, Display, Clone)]
73#[display("{poly} / {modulus}")]
74pub struct PolynomialRingZq {
75 pub(crate) poly: PolyOverZ,
76 pub(crate) modulus: ModulusPolynomialRingZq,
77}
78
79impl fmt::Debug for PolynomialRingZq {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 write!(
82 f,
83 "PolynomialRingZq {{poly: {}, modulus {}, storage: {{poly: {:?}, modulus: {:?}}}}}",
84 self.poly, self.modulus, self.poly, self.modulus
85 )
86 }
87}