1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//! Module for implementations using [`::num_bigint`].
use num_bigint::{
    BigInt,
    Sign,
    ToBigInt,
};
use num_integer::Integer;
use num_modular::ModularUnaryOps;
use num_prime::nt_funcs::next_prime;
use std::ops::Neg;

#[cfg_attr(docsrs, doc(cfg(feature = "bigint")))]
impl crate::BigInt for BigInt {

    /// ```
    /// use num_bigint::BigInt;
    /// let x: BigInt = <BigInt as clacc::BigInt>::from_i64(256);
    /// let y: BigInt = 256.into();
    /// assert_eq!(x, y);
    /// ```
    fn from_i64(v: i64) -> Self {
        return v.into()
    }

    /// ```
    /// use num_bigint::BigInt;
    /// let x: BigInt = <BigInt as clacc::BigInt>::from_bytes_be(
    ///     vec![0x01, 0x00].as_slice(),
    /// );
    /// let y: BigInt = 256.into();
    /// assert_eq!(x, y);
    /// ```
    fn from_bytes_be(bytes: &[u8]) -> Self {
        BigInt::from_bytes_be(Sign::Plus, bytes)
    }

    /// ```
    /// use num_bigint::BigInt;
    /// let x = vec![0x01, 0x00];
    /// let y: BigInt = 256.into();
    /// assert_eq!(x, <BigInt as clacc::BigInt>::to_bytes_be(&y));
    /// ```
    fn to_bytes_be(&self) -> Vec<u8> {
        BigInt::to_bytes_be(self).1
    }

    /// ```
    /// use num_bigint::BigInt;
    /// let x: BigInt = 240.into();
    /// let y: BigInt = 46.into();
    /// let (g, a, b) = <BigInt as clacc::BigInt>::gcdext(&x, &y);
    /// assert_eq!(g, 2.into());
    /// assert_eq!(a, (-9).into());
    /// assert_eq!(b, 47.into());
    /// ```
    fn gcdext(&self, y: &Self) -> (Self, Self, Self) {
        let gcd = self.extended_gcd(y);
        (gcd.gcd, gcd.x, gcd.y)
    }

    /// ```
    /// use num_bigint::BigInt;
    /// let b: BigInt = 5.into();
    /// let e: BigInt = 3.into();
    /// let m: BigInt = 13.into();
    /// let c = <BigInt as clacc::BigInt>::powm(&b, &e, &m);
    /// assert_eq!(c, 8.into());
    /// ```
    /// ```
    /// use num_bigint::BigInt;
    /// let b: BigInt = 3.into();
    /// let e: BigInt = (-1).into();
    /// let m: BigInt = 11.into();
    /// let c = <BigInt as clacc::BigInt>::powm(&b, &e, &m);
    /// assert_eq!(c, 4.into());
    /// ```
    fn powm(&self, e: &Self, m: &Self) -> Self {
        match e.sign() {
            Sign::Plus | Sign::NoSign => self.modpow(e, m),
            Sign::Minus => {
                self.to_biguint().unwrap().invm(
                    &m.to_biguint().unwrap(),
                ).unwrap().to_bigint().unwrap().modpow(&e.neg(), m)
            },
        }
    }

    /// ```
    /// use num_bigint::BigInt;
    /// let x: BigInt = 32.into();
    /// let p = <BigInt as clacc::BigInt>::next_prime(&x);
    /// assert_eq!(p, 37.into());
    /// ```
    fn next_prime(&self) -> Self {
        next_prime(
            &self.to_biguint().unwrap(),
            None,
        ).unwrap().to_bigint().unwrap()
    }

    /// ```
    /// use num_bigint::BigInt;
    /// let a: BigInt = 3.into();
    /// assert_eq!(<BigInt as clacc::BigInt>::size_in_bits(&a), 2);
    /// let b: BigInt = 256.into();
    /// assert_eq!(<BigInt as clacc::BigInt>::size_in_bits(&b), 9);
    /// ```
    fn size_in_bits(&self) -> usize {
        BigInt::bits(self) as usize
    }
}