Skip to main content

crypto_bigint/uint/ref_type/
invert_mod.rs

1use super::UintRef;
2use crate::{Limb, Odd, primitives};
3
4impl Odd<UintRef> {
5    /// Returns the multiplicative inverse of the argument modulo 2^N, where 2^N
6    /// is the capacity of a [`Limb`].
7    #[must_use]
8    pub(crate) const fn invert_mod_limb(&self) -> Limb {
9        Odd::new_unchecked(self.as_ref().limbs[0]).multiplicative_inverse()
10    }
11
12    /// Returns the multiplicative inverse of the argument modulo 2^64.
13    #[must_use]
14    pub const fn invert_mod_u64(&self) -> u64 {
15        let value = self.as_ref().lowest_u64();
16        primitives::u64_invert_odd(value)
17    }
18}
19
20#[cfg(test)]
21mod tests {
22    use crate::U128;
23
24    #[test]
25    fn invert_mod_u64() {
26        let q = U128::ONE.to_odd().unwrap();
27        let inv = q.as_uint_ref().invert_mod_u64();
28        assert_eq!(inv, 0x1);
29
30        let q = U128::from(3u64).to_odd().unwrap();
31        let inv = q.as_uint_ref().invert_mod_u64();
32        assert_eq!(inv, 0xaaaaaaaaaaaaaaab);
33
34        let q = U128::from_be_hex("AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD")
35            .to_odd()
36            .unwrap();
37        let inv = q.as_uint_ref().invert_mod_u64();
38        assert_eq!(inv, 0xa6a0916b76276275);
39    }
40}