1use crate::ntrait::NumberTheory;
2
3#[derive(Clone)]
8pub struct Certificate<T: NumberTheory>{
9 pub(crate) n: T,
10 pub(crate) witness: T,
11 pub(crate) fctr: Vec<T>,
12}
13
14impl<T: NumberTheory> Certificate<T>{
15
16 pub(crate) fn new(n: T, witness: T, fctr: Vec<T>) -> Self{
17 Self{n,witness,fctr}
18 }
19
20
21 pub fn check(&self) -> bool{
23 if self.fctr.is_empty(){
24 return false;
25 }
26
27 if !self.n.clone().strong_fermat(self.witness.clone()){
28 return false;
29 }
30
31 for i in self.fctr.iter(){
32 if self.witness.exp_residue(i.clone(), self.n.clone()).is_unit() {
33 return false
34 }
35 }
36 return true;
37 }
38
39}
40
41#[derive(Clone,Default)]
43pub struct Factorization<T>{
44 pub(crate) base: Vec<T>,
45 pub(crate) power: Vec<u64>,
46}
47
48impl <T: NumberTheory> Factorization<T>{
49
50 pub fn new() -> Self{
51 Self{base: vec![], power: vec![]}
52 }
53
54 pub fn from_components(base: Vec<T>,power: Vec<u64>) -> Self{
55 Self{base,power}
56 }
57
58 pub fn factor_iter(&self) -> std::slice::Iter<T>{
59 self.base.iter()
60 }
61
62 pub fn power_iter(&self) -> std::slice::Iter<u64>{
63 self.power.iter()
64 }
65
66 pub fn add_factor(&mut self, fctr: T){
67 self.base.push(fctr);
68 }
69
70 pub fn add_power(&mut self, power: u64){
71 self.power.push(power);
72 }
73
74 pub fn pair_iter(&self) -> std::iter::Zip<std::slice::Iter<T>,std::slice::Iter<u64>>{
75 self.base.iter().zip(self.power.iter())
76 }
77
78 pub fn max(&self) -> T{
79 self.factor_iter().max().unwrap().clone()
80 }
81
82 pub fn k_free(&self, k: u64) -> bool{
83 for i in self.power_iter(){
84 if *i >= k{
85 return false;
86 }
87 }
88 return true;
89 }
90
91 pub fn prime_omega(&self) -> u64{
92 self.power_iter().sum::<u64>()
93 }
94
95 }
96
97 impl<T: NumberTheory> std::fmt::Display for Factorization<T>{
98
99 fn fmt(&self,f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>{
100
101 let mut output = String::new();
102 if self.power[0] != 1{
103 output+=&(self.base[0].to_string()+"^"+&self.power[0].to_string());
104 }
105 else{
106 output+=&(self.base[0].to_string());
107 }
108 if self.base.len() > 1{
109 for i in 1..self.base.len(){
110 if self.power[i] != 1{
111 let pair = self.base[i].to_string()+"^"+&self.power[i].to_string();
112 output+=&(" * ".to_owned() + &pair);
113 }
114 else{
115 let pair = self.base[i].to_string();
116 output+= &(" * ".to_owned()+&pair);
117 }
118 }
119 }
120 write!(f,"{}",output)
121 }
122}
123
124