Skip to main content

crypto_bigint/limb/
gcd.rs

1//! GCD support for [`Limb`].
2
3use super::Limb;
4use crate::{Gcd, NonZero, Odd, Uint};
5
6impl Gcd for Limb {
7    type Output = Limb;
8
9    fn gcd(&self, rhs: &Self) -> Self::Output {
10        Uint::<1>::from(*self).gcd(&Uint::from(*rhs)).limbs[0]
11    }
12
13    fn gcd_vartime(&self, rhs: &Self) -> Self::Output {
14        Uint::<1>::from(*self).gcd_vartime(&Uint::from(*rhs)).limbs[0]
15    }
16}
17
18impl Gcd<Limb> for NonZero<Limb> {
19    type Output = Limb;
20
21    fn gcd(&self, rhs: &Limb) -> Self::Output {
22        NonZero::<Uint<1>>::from(*self).gcd(&Uint::from(*rhs)).limbs[0]
23    }
24
25    fn gcd_vartime(&self, rhs: &Limb) -> Self::Output {
26        NonZero::<Uint<1>>::from(*self)
27            .gcd_vartime(&Uint::from(*rhs))
28            .limbs[0]
29    }
30}
31
32impl Gcd<Limb> for Odd<Limb> {
33    type Output = Limb;
34
35    fn gcd(&self, rhs: &Limb) -> Self::Output {
36        Odd::<Uint<1>>::from(*self).gcd(&Uint::from(*rhs)).limbs[0]
37    }
38
39    fn gcd_vartime(&self, rhs: &Limb) -> Self::Output {
40        Odd::<Uint<1>>::from(*self)
41            .gcd_vartime(&Uint::from(*rhs))
42            .limbs[0]
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use crate::{Gcd, Limb, Odd};
49
50    #[test]
51    fn gcd_expected() {
52        let f = Odd::<Limb>::new(Limb::from(61u32 * 71)).expect("ensured odd");
53        let g = Limb::from(59u32 * 61);
54
55        assert_eq!(Limb::from(61u32), f.gcd(&g));
56        assert_eq!(Limb::from(61u32), f.gcd_vartime(&g));
57
58        let f = f.as_nz_ref();
59        assert_eq!(Limb::from(61u32), f.gcd(&g));
60        assert_eq!(Limb::from(61u32), f.gcd_vartime(&g));
61
62        let f = f.get();
63        assert_eq!(Limb::from(61u32), f.gcd(&g));
64        assert_eq!(Limb::from(61u32), f.gcd_vartime(&g));
65    }
66}