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}