haar_lib/math/
primitive_root.rs1use crate::for_loop;
4use crate::math::mod_ops::pow::*;
5
6pub const fn primitive_root(p: u32) -> u32 {
8 let mut pf = [0; 32];
9 let mut n = p - 1;
10 let mut j = 0;
11 let mut i = 2;
12 while i * i <= n {
13 if n % i == 0 {
14 while n % i == 0 {
15 n /= i;
16 }
17 pf[j] = i;
18 j += 1;
19 }
20 i += 1
21 }
22
23 if n != 1 {
24 pf[j] = n;
25 }
26
27 for_loop!(let mut g = 2; g <= p; g += 1; {
28 let mut ok = true;
29
30 for_loop!(let mut i = 0; i < pf.len(); i += 1; {
31 let f = pf[i];
32 if f == 0 {
33 break;
34 }
35 if mod_pow(g as u64, (p as u64 - 1) / f as u64, p as u64) == 1 {
36 ok = false;
37 break;
38 }
39 });
40
41 if ok {
42 return g;
43 }
44 });
45
46 panic!("No primitive roots.");
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test() {
55 assert_eq!(primitive_root(469762049), 3);
56 assert_eq!(primitive_root(167772161), 3);
57 assert_eq!(primitive_root(754974721), 11);
58 assert_eq!(primitive_root(1012924417), 5);
59
60 struct A<const P: u32, const PR: u32>;
61 impl<const P: u32, const PR: u32> A<P, PR> {
62 fn print(&self) {
63 dbg!(P, PR);
64 }
65 }
66
67 let a = A::<998244353, { primitive_root(998244353) }>;
68 a.print();
69 }
70}