qfall_math/integer_mod_q/mat_polynomial_ring_zq/
cmp.rs

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