qfall_math/integer_mod_q/ntt_polynomial_ring_zq/
cmp.rs

1// Copyright © 2025 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//! This module contains implementations for comparison of [`PolynomialRingZq`].
10
11use super::NTTPolynomialRingZq;
12use crate::{
13    error::MathError,
14    integer::{PolyOverZ, Z},
15    integer_mod_q::{PolyOverZq, PolynomialRingZq, Zq},
16    macros::compare_base::{
17        compare_base_default, compare_base_get_mod, compare_base_get_mod_get_q, compare_base_impl,
18    },
19    traits::CompareBase,
20};
21
22compare_base_default!(NTTPolynomialRingZq for PolyOverZ);
23compare_base_get_mod!(NTTPolynomialRingZq for PolynomialRingZq NTTPolynomialRingZq);
24compare_base_get_mod_get_q!(NTTPolynomialRingZq for Zq PolyOverZq);
25impl<Integer: Into<Z>> CompareBase<Integer> for NTTPolynomialRingZq {}
26
27/// Test that the [`CompareBase`] trait uses an actual implementation.
28#[cfg(test)]
29mod test_compare_base {
30    use crate::{
31        integer::{PolyOverZ, Z},
32        integer_mod_q::{ModulusPolynomialRingZq, PolyOverZq, PolynomialRingZq, Zq},
33        traits::CompareBase,
34    };
35    use std::str::FromStr;
36
37    /// Ensures that the [`CompareBase`] is available for all types it would be checked against
38    /// where no comparison is needed
39    #[test]
40    fn availability_without_comparisons() {
41        let mut modulus = ModulusPolynomialRingZq::from_str("3  1 0 1 mod 17").unwrap();
42        modulus.set_ntt_unchecked(4);
43        let one_1 = PolynomialRingZq::from(&modulus);
44        let one_1 = one_1.ntt();
45
46        assert!(one_1.compare_base(&Z::ONE));
47        assert!(one_1.compare_base(&PolyOverZ::from_str("1  3").unwrap()));
48        assert!(one_1.compare_base(&0_i8));
49        assert!(one_1.compare_base(&0_i16));
50        assert!(one_1.compare_base(&0_i32));
51        assert!(one_1.compare_base(&0_i64));
52        assert!(one_1.compare_base(&0_u8));
53        assert!(one_1.compare_base(&0_u16));
54        assert!(one_1.compare_base(&0_u32));
55        assert!(one_1.compare_base(&0_u64));
56
57        assert!(one_1.call_compare_base_error(&Z::ONE).is_none());
58        assert!(
59            one_1
60                .call_compare_base_error(&PolyOverZ::from_str("1  3").unwrap())
61                .is_none()
62        );
63        assert!(one_1.call_compare_base_error(&0_i8).is_none());
64        assert!(one_1.call_compare_base_error(&0_i16).is_none());
65        assert!(one_1.call_compare_base_error(&0_i32).is_none());
66        assert!(one_1.call_compare_base_error(&0_i64).is_none());
67        assert!(one_1.call_compare_base_error(&0_u8).is_none());
68        assert!(one_1.call_compare_base_error(&0_u16).is_none());
69        assert!(one_1.call_compare_base_error(&0_u32).is_none());
70        assert!(one_1.call_compare_base_error(&0_u64).is_none());
71    }
72
73    /// Ensures that the [`CompareBase`] is available for all types it would be checked against
74    /// where comparison is needed
75    #[test]
76    fn availability_with_comparisons() {
77        let mut modulus = ModulusPolynomialRingZq::from_str("3  1 0 1 mod 17").unwrap();
78        modulus.set_ntt_unchecked(4);
79        let modulus_other = ModulusPolynomialRingZq::from_str("3  1 0 1 mod 18").unwrap();
80        let one_1 = PolynomialRingZq::from(&modulus);
81        let one_1 = one_1.ntt();
82
83        assert!(one_1.compare_base(&one_1));
84        assert!(one_1.compare_base(&Zq::from((3, 17))));
85        assert!(!one_1.compare_base(&Zq::from((3, 18))));
86        assert!(one_1.compare_base(&PolyOverZq::from_str("1  3 mod 17").unwrap()));
87        assert!(!one_1.compare_base(&PolyOverZq::from_str("1  3 mod 18").unwrap()));
88        assert!(one_1.compare_base(&PolynomialRingZq::from(&modulus)));
89        assert!(!one_1.compare_base(&PolynomialRingZq::from(&modulus_other)));
90
91        assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some());
92        assert!(
93            one_1
94                .call_compare_base_error(&PolyOverZq::from_str("1  3 mod 18").unwrap())
95                .is_some()
96        );
97        assert!(
98            one_1
99                .call_compare_base_error(&PolynomialRingZq::from(&modulus_other))
100                .is_some()
101        );
102    }
103}