qfall_math/integer_mod_q/z_q/get.rs
1// Copyright © 2023 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 if self.value < mod_z.div_ceil(2) {
57 self.value.clone()
58 } else {
59 Z::from(self.modulus.clone()) - self.value.clone()
60 }
61 }
62
63 /// Returns the [`Modulus`] of the [`Zq`] element.
64 ///
65 /// # Examples
66 /// ```
67 /// use qfall_math::integer_mod_q::{Zq, Modulus};
68 /// use std::str::FromStr;
69 /// let value = Zq::from((4, 7));
70 /// let cmp = Modulus::from(7);
71 ///
72 /// let modulus = value.get_mod();
73 ///
74 /// assert_eq!(cmp, modulus);
75 /// ```
76 pub fn get_mod(&self) -> Modulus {
77 self.modulus.clone()
78 }
79}
80
81#[cfg(test)]
82mod test_get_representative_least_nonnegative_residue {
83 use super::{Z, Zq};
84
85 /// Check whether `get_representative_least_nonnegative_residue` outputs the correct value for small values
86 #[test]
87 fn get_small() {
88 let value_0 = Zq::from((2, 20));
89 let value_1 = Zq::from((-2, 20));
90
91 let res_0 = value_0.get_representative_least_nonnegative_residue();
92 let res_1 = value_1.get_representative_least_nonnegative_residue();
93
94 assert_eq!(res_0, Z::from(2));
95 assert_eq!(res_1, Z::from(18));
96 }
97
98 /// Check whether `get_representative_least_nonnegative_residue` outputs the correct value for large values
99 #[test]
100 fn get_large() {
101 let value_0 = Zq::from((i64::MAX, u64::MAX));
102 let value_1 = Zq::from((i64::MIN, u64::MAX));
103
104 let res_0 = value_0.get_representative_least_nonnegative_residue();
105 let res_1 = value_1.get_representative_least_nonnegative_residue();
106
107 assert_eq!(res_0, Z::from(i64::MAX));
108 assert_eq!(res_1, Z::from(i64::MAX));
109 }
110}
111
112#[cfg(test)]
113mod test_get_representative_least_absolute_residue {
114 use super::{Z, Zq};
115
116 /// Check whether `get_representative_least_absolute_residue` outputs the correct value for small values
117 #[test]
118 fn get_small() {
119 let value_0 = Zq::from((2, 20));
120 let value_1 = Zq::from((-2, 20));
121
122 let res_0 = value_0.get_representative_least_absolute_residue();
123 let res_1 = value_1.get_representative_least_absolute_residue();
124
125 assert_eq!(res_0, Z::from(2));
126 assert_eq!(res_1, Z::from(2));
127 }
128
129 /// Check whether `get_representative_least_absolute_residue` outputs the correct value for large values
130 #[test]
131 fn get_large() {
132 let value_0 = Zq::from((i64::MAX, u64::MAX));
133 let value_1 = Zq::from((u64::MAX - 1, u64::MAX));
134
135 let res_0 = value_0.get_representative_least_absolute_residue();
136 let res_1 = value_1.get_representative_least_absolute_residue();
137
138 assert_eq!(res_0, Z::from(i64::MAX));
139 assert_eq!(res_1, Z::from(1));
140 }
141
142 /// Check whether `get_representative_least_absolute_residue` outputs the correct value for special cases
143 #[test]
144 fn get_special() {
145 let value_0 = Zq::from((10, 20));
146 let value_1 = Zq::from((0, 20));
147
148 let res_0 = value_0.get_representative_least_absolute_residue();
149 let res_1 = value_1.get_representative_least_absolute_residue();
150
151 assert_eq!(res_0, Z::from(10));
152 assert_eq!(res_1, Z::from(0));
153 }
154}
155
156#[cfg(test)]
157mod test_get_mod {
158 use super::{Modulus, Zq};
159
160 /// Check whether `get_mod` outputs the correct modulus for small moduli
161 #[test]
162 fn get_small() {
163 let value = Zq::from((2, 20));
164
165 let modulus = value.get_mod();
166
167 assert_eq!(modulus, Modulus::from(20));
168 }
169
170 /// Check whether `get_mod` outputs the correct modulus for large moduli
171 #[test]
172 fn get_large() {
173 let value = Zq::from((2, u64::MAX));
174
175 let modulus = value.get_mod();
176
177 assert_eq!(modulus, Modulus::from(u64::MAX));
178 }
179}