clacc/
bigint.rs

1//! Module for implementations using [`::num_bigint`].
2use num_bigint::{
3    BigInt,
4    Sign,
5    ToBigInt,
6};
7use num_integer::Integer;
8use num_modular::ModularUnaryOps;
9use std::ops::Neg;
10
11#[cfg_attr(docsrs, doc(cfg(feature = "bigint")))]
12impl crate::BigInt for BigInt {
13
14    /// ```
15    /// use num_bigint::BigInt;
16    /// let x: BigInt = <BigInt as clacc::BigInt>::from_i64(256);
17    /// let y: BigInt = 256.into();
18    /// assert_eq!(x, y);
19    /// ```
20    fn from_i64(v: i64) -> Self {
21        return v.into()
22    }
23
24    /// ```
25    /// use num_bigint::BigInt;
26    /// let x: BigInt = <BigInt as clacc::BigInt>::from_bytes_be(
27    ///     vec![0x01, 0x00].as_slice(),
28    /// );
29    /// let y: BigInt = 256.into();
30    /// assert_eq!(x, y);
31    /// ```
32    fn from_bytes_be(bytes: &[u8]) -> Self {
33        BigInt::from_bytes_be(Sign::Plus, bytes)
34    }
35
36    /// ```
37    /// use num_bigint::BigInt;
38    /// let x = vec![0x01, 0x00];
39    /// let y: BigInt = 256.into();
40    /// assert_eq!(x, <BigInt as clacc::BigInt>::to_bytes_be(&y));
41    /// ```
42    fn to_bytes_be(&self) -> Vec<u8> {
43        BigInt::to_bytes_be(self).1
44    }
45
46    /// ```
47    /// use num_bigint::BigInt;
48    /// let x: BigInt = 240.into();
49    /// let y: BigInt = 46.into();
50    /// let (g, a, b) = <BigInt as clacc::BigInt>::gcdext(&x, &y);
51    /// assert_eq!(g, 2.into());
52    /// assert_eq!(a, (-9).into());
53    /// assert_eq!(b, 47.into());
54    /// ```
55    fn gcdext(&self, y: &Self) -> (Self, Self, Self) {
56        let gcd = self.extended_gcd(y);
57        (gcd.gcd, gcd.x, gcd.y)
58    }
59
60    /// ```
61    /// use num_bigint::BigInt;
62    /// let b: BigInt = 5.into();
63    /// let e: BigInt = 3.into();
64    /// let m: BigInt = 13.into();
65    /// let c = <BigInt as clacc::BigInt>::powm(&b, &e, &m);
66    /// assert_eq!(c, 8.into());
67    /// ```
68    /// ```
69    /// use num_bigint::BigInt;
70    /// let b: BigInt = 3.into();
71    /// let e: BigInt = (-1).into();
72    /// let m: BigInt = 11.into();
73    /// let c = <BigInt as clacc::BigInt>::powm(&b, &e, &m);
74    /// assert_eq!(c, 4.into());
75    /// ```
76    fn powm(&self, e: &Self, m: &Self) -> Self {
77        match e.sign() {
78            Sign::Plus | Sign::NoSign => self.modpow(e, m),
79            Sign::Minus => {
80                self.to_biguint().unwrap().invm(
81                    &m.to_biguint().unwrap(),
82                ).unwrap().to_bigint().unwrap().modpow(&e.neg(), m)
83            },
84        }
85    }
86
87    /// ```
88    /// use num_bigint::BigInt;
89    /// let a: BigInt = 3.into();
90    /// assert_eq!(<BigInt as clacc::BigInt>::size_in_bits(&a), 2);
91    /// let b: BigInt = 256.into();
92    /// assert_eq!(<BigInt as clacc::BigInt>::size_in_bits(&b), 9);
93    /// ```
94    fn size_in_bits(&self) -> usize {
95        BigInt::bits(self) as usize
96    }
97}