crypto_bigint/uint/boxed/
gcd.rs1use super::BoxedUint;
4use crate::{Gcd, NonZero, Odd, modular::safegcd};
5
6impl Gcd for BoxedUint {
7 type Output = Self;
8
9 fn gcd(&self, rhs: &Self) -> Self {
11 safegcd::boxed::gcd::<false>(self, rhs)
12 }
13
14 fn gcd_vartime(&self, rhs: &Self) -> Self::Output {
15 safegcd::boxed::gcd::<true>(self, rhs)
16 }
17}
18
19impl Gcd<BoxedUint> for NonZero<BoxedUint> {
20 type Output = NonZero<BoxedUint>;
21
22 fn gcd(&self, rhs: &BoxedUint) -> Self::Output {
23 safegcd::boxed::gcd_nz::<false>(self, rhs)
24 }
25
26 fn gcd_vartime(&self, rhs: &BoxedUint) -> Self::Output {
27 safegcd::boxed::gcd_nz::<true>(self, rhs)
28 }
29}
30
31impl Gcd<BoxedUint> for Odd<BoxedUint> {
32 type Output = Odd<BoxedUint>;
33
34 fn gcd(&self, rhs: &BoxedUint) -> Self::Output {
35 safegcd::boxed::gcd_odd::<false>(self, rhs)
36 }
37
38 fn gcd_vartime(&self, rhs: &BoxedUint) -> Self::Output {
39 safegcd::boxed::gcd_odd::<true>(self, rhs)
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use crate::{BoxedUint, Gcd, Resize};
46
47 #[test]
48 fn gcd_relatively_prime() {
49 let f = BoxedUint::from(59u32 * 67).to_odd().unwrap();
51 let g = BoxedUint::from(61u32 * 71);
52 let gcd = f.gcd(&g);
53 assert_eq!(gcd.0, BoxedUint::one());
54 }
55
56 #[test]
57 fn gcd_nonprime() {
58 let f = BoxedUint::from(4391633u32).to_odd().unwrap();
59 let g = BoxedUint::from(2022161u32);
60 let gcd = f.gcd(&g);
61 assert_eq!(gcd.0, BoxedUint::from(1763u32));
62 }
63
64 #[test]
65 fn gcd_zero() {
66 let zero = BoxedUint::from(0u32);
67 let one = BoxedUint::from(1u32);
68
69 assert_eq!(zero.gcd(&zero), zero);
70 assert_eq!(zero.gcd(&one), one);
71 assert_eq!(one.gcd(&zero), one);
72 }
73
74 #[test]
75 fn gcd_one() {
76 let f = BoxedUint::from(1u32);
77 assert_eq!(BoxedUint::from(1u32), f.gcd(&BoxedUint::from(1u32)));
78 assert_eq!(BoxedUint::from(1u32), f.gcd(&BoxedUint::from(2u8)));
79 }
80
81 #[test]
82 fn gcd_two() {
83 let f = BoxedUint::from(2u32);
84 assert_eq!(f, f.gcd(&f));
85
86 let g = BoxedUint::from(4u32);
87 assert_eq!(f, f.gcd(&g));
88 assert_eq!(f, g.gcd(&f));
89 }
90
91 #[test]
92 fn gcd_different_sizes() {
93 let f = BoxedUint::from(4391633u32).resize(128).to_odd().unwrap();
95 let g = BoxedUint::from(2022161u32);
96 let gcd = f.gcd(&g);
97 assert_eq!(gcd.0, BoxedUint::from(1763u32));
98 }
99
100 #[test]
101 fn gcd_vartime_different_sizes() {
102 let f = BoxedUint::from(4391633u32).resize(128).to_odd().unwrap();
104 let g = BoxedUint::from(2022161u32);
105 let gcd = f.gcd_vartime(&g);
106 assert_eq!(gcd.0, BoxedUint::from(1763u32));
107 }
108}