qfall_math/integer_mod_q/z_q/
properties.rs1use super::Zq;
12use crate::traits::Pow;
13use flint_sys::{fmpz::fmpz_is_zero, fmpz_mod::fmpz_mod_is_one};
14
15impl Zq {
16 pub fn inverse(&self) -> Option<Zq> {
29 self.pow(-1).ok()
30 }
31
32 pub fn is_zero(&self) -> bool {
44 1 == unsafe { fmpz_is_zero(&self.value.value) }
45 }
46
47 pub fn is_one(&self) -> bool {
59 1 == unsafe { fmpz_mod_is_one(&self.value.value, self.modulus.get_fmpz_mod_ctx_struct()) }
60 }
61}
62
63#[cfg(test)]
64mod test_inv {
65 use super::Zq;
66
67 #[test]
69 fn small_values() {
70 let val_0 = Zq::from((4, 7));
71 let val_1 = Zq::from((-2, 7));
72
73 let inv_0 = val_0.inverse().unwrap();
74 let inv_1 = val_1.inverse().unwrap();
75
76 assert_eq!(Zq::from((2, 7)), inv_0);
77 assert_eq!(Zq::from((3, 7)), inv_1);
78 }
79
80 #[test]
82 fn large_values() {
83 let val_0 = Zq::from((i64::MAX, u64::MAX));
84 let val_1 = Zq::from((i64::MIN, u64::MAX));
85
86 let inv_0 = val_0.inverse().unwrap();
87 let inv_1 = val_1.inverse().unwrap();
88
89 assert_eq!(Zq::from((18446744073709551613_u64, u64::MAX)), inv_0);
90 assert_eq!(Zq::from((18446744073709551613_u64, u64::MAX)), inv_1);
91 }
92
93 #[test]
95 fn no_inverse_returns_none() {
96 let val_0 = Zq::from((4, 8));
97 let val_1 = Zq::from((3, 9));
98 let val_2 = Zq::from((0, 7));
99
100 assert!(val_0.inverse().is_none());
101 assert!(val_1.inverse().is_none());
102 assert!(val_2.inverse().is_none());
103 }
104}
105
106#[cfg(test)]
107mod test_is_zero {
108 use super::Zq;
109 use std::str::FromStr;
110
111 #[test]
113 fn zero_detection() {
114 let zero = Zq::from((0, 7));
115
116 assert!(zero.is_zero());
117 }
118
119 #[test]
121 fn zero_rejection() {
122 let small = Zq::from((4, 9));
123 let large =
124 Zq::from_str(&format!("{} mod {}", (u128::MAX - 1) / 2 + 1, u128::MAX)).unwrap();
125
126 assert!(!small.is_zero());
127 assert!(!large.is_zero());
128 }
129}
130
131#[cfg(test)]
132mod test_is_one {
133 use super::Zq;
134 use std::str::FromStr;
135
136 #[test]
138 fn one_detection() {
139 let one = Zq::from((8, 7));
140
141 assert!(one.is_one());
142 }
143
144 #[test]
146 fn one_rejection() {
147 let small = Zq::from((12, 7));
148 let large =
149 Zq::from_str(&format!("{} mod {}", (u128::MAX - 1) / 2 + 2, u128::MAX)).unwrap();
150
151 assert!(!small.is_one());
152 assert!(!large.is_one());
153 }
154}