Skip to main content

qfall_math/integer_mod_q/z_q/
get.rs

1// Copyright 2023 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//! Get elements of [`Zq`] like its [`Z`] value and [`Modulus`].
10
11use crate::{
12    integer::Z,
13    integer_mod_q::{Modulus, Zq},
14};
15
16impl Zq {
17    /// Returns the [`Z`] value of the [`Zq`] element.
18    ///
19    /// The representation in the range `[0, modulus)` is returned.
20    /// Use [`Zq::get_representative_least_absolute_residue`] if they should be
21    /// in the range `[-modulus/2, modulus/2]`.
22    ///
23    /// # Examples
24    /// ```
25    /// use qfall_math::integer_mod_q::Zq;
26    /// use qfall_math::integer::Z;
27    /// let zq_value = Zq::from((4, 7));
28    ///
29    /// let z_value = zq_value.get_representative_least_nonnegative_residue();
30    ///
31    /// assert_eq!(Z::from(4), z_value);
32    /// ```
33    pub fn get_representative_least_nonnegative_residue(&self) -> Z {
34        self.value.clone()
35    }
36
37    /// Returns the [`Z`] value of the [`Zq`] element with the representatives close to `0`.
38    ///
39    /// The output value is in the range of `[-modulus/2, modulus/2]`.
40    /// For even moduli, the positive representative is chosen for the element `modulus / 2`.
41    /// Use [`Zq::get_representative_least_nonnegative_residue`] if they should be
42    /// in the range `[0, modulus)`.
43    ///
44    /// # Examples
45    /// ```
46    /// use qfall_math::integer_mod_q::Zq;
47    /// use qfall_math::integer::Z;
48    /// let zq_value = Zq::from((5, 7));
49    ///
50    /// let z_value = zq_value.get_representative_least_absolute_residue();
51    ///
52    /// assert_eq!(Z::from(-2), z_value);
53    /// ```
54    pub fn get_representative_least_absolute_residue(&self) -> Z {
55        let mod_z = Z::from(&self.modulus);
56        let mod_half = mod_z.div_floor(2);
57        if self.value > mod_half {
58            &self.value - mod_z
59        } else {
60            self.value.clone()
61        }
62    }
63
64    /// Returns the [`Modulus`] of the [`Zq`] element.
65    ///
66    /// # Examples
67    /// ```
68    /// use qfall_math::integer_mod_q::{Zq, Modulus};
69    /// use std::str::FromStr;
70    /// let value = Zq::from((4, 7));
71    /// let cmp = Modulus::from(7);
72    ///
73    /// let modulus = value.get_mod();
74    ///
75    /// assert_eq!(cmp, modulus);
76    /// ```
77    pub fn get_mod(&self) -> Modulus {
78        self.modulus.clone()
79    }
80}
81
82#[cfg(test)]
83mod test_get_representative_least_nonnegative_residue {
84    use super::{Z, Zq};
85
86    /// Check whether `get_representative_least_nonnegative_residue` outputs the correct value for small values
87    #[test]
88    fn get_small() {
89        let value_0 = Zq::from((2, 20));
90        let value_1 = Zq::from((-2, 20));
91
92        let res_0 = value_0.get_representative_least_nonnegative_residue();
93        let res_1 = value_1.get_representative_least_nonnegative_residue();
94
95        assert_eq!(res_0, Z::from(2));
96        assert_eq!(res_1, Z::from(18));
97    }
98
99    /// Check whether `get_representative_least_nonnegative_residue` outputs the correct value for large values
100    #[test]
101    fn get_large() {
102        let value_0 = Zq::from((i64::MAX, u64::MAX));
103        let value_1 = Zq::from((i64::MIN, u64::MAX));
104
105        let res_0 = value_0.get_representative_least_nonnegative_residue();
106        let res_1 = value_1.get_representative_least_nonnegative_residue();
107
108        assert_eq!(res_0, Z::from(i64::MAX));
109        assert_eq!(res_1, Z::from(i64::MAX));
110    }
111}
112
113#[cfg(test)]
114mod test_get_representative_least_absolute_residue {
115    use super::{Z, Zq};
116
117    /// Check whether `get_representative_least_absolute_residue` outputs the correct value for small values
118    #[test]
119    fn get_small() {
120        let value_0 = Zq::from((2, 20));
121        let value_1 = Zq::from((-2, 20));
122
123        let res_0 = value_0.get_representative_least_absolute_residue();
124        let res_1 = value_1.get_representative_least_absolute_residue();
125
126        assert_eq!(res_0, Z::from(2));
127        assert_eq!(res_1, Z::from(-2));
128    }
129
130    /// Check whether `get_representative_least_absolute_residue` outputs the correct value for large values
131    #[test]
132    fn get_large() {
133        let value_0 = Zq::from((i64::MAX, u64::MAX));
134        let value_1 = Zq::from((u64::MAX - 1, u64::MAX));
135
136        let res_0 = value_0.get_representative_least_absolute_residue();
137        let res_1 = value_1.get_representative_least_absolute_residue();
138
139        assert_eq!(res_0, Z::from(i64::MAX));
140        assert_eq!(res_1, Z::from(-1));
141    }
142
143    /// Check whether `get_representative_least_absolute_residue` outputs the correct value for special cases
144    #[test]
145    fn get_special() {
146        let value_0 = Zq::from((10, 20));
147        let value_1 = Zq::from((0, 20));
148        let value_2 = Zq::from((11, 21));
149
150        let res_0 = value_0.get_representative_least_absolute_residue();
151        let res_1 = value_1.get_representative_least_absolute_residue();
152        let res_2 = value_2.get_representative_least_absolute_residue();
153
154        assert_eq!(res_0, Z::from(10));
155        assert_eq!(res_1, Z::from(0));
156        assert_eq!(res_2, Z::from(-10));
157    }
158}
159
160#[cfg(test)]
161mod test_get_mod {
162    use super::{Modulus, Zq};
163
164    /// Check whether `get_mod` outputs the correct modulus for small moduli
165    #[test]
166    fn get_small() {
167        let value = Zq::from((2, 20));
168
169        let modulus = value.get_mod();
170
171        assert_eq!(modulus, Modulus::from(20));
172    }
173
174    /// Check whether `get_mod` outputs the correct modulus for large moduli
175    #[test]
176    fn get_large() {
177        let value = Zq::from((2, u64::MAX));
178
179        let modulus = value.get_mod();
180
181        assert_eq!(modulus, Modulus::from(u64::MAX));
182    }
183}