Skip to main content

ps_ecc/polynomial/implementations/
div.rs

1use std::ops::Div;
2
3use crate::{error::PolynomialDivError, Polynomial};
4
5impl<D: AsRef<[u8]>> Div<D> for &Polynomial {
6    type Output = Result<Polynomial, PolynomialDivError>;
7
8    /// Divides two polynomials over GF(256), returning the quotient.
9    ///
10    /// # Errors
11    ///
12    /// Returns `ZeroDivisor` if the divisor is the zero polynomial.
13    fn div(self, rhs: D) -> Self::Output {
14        let (quot, _rem) = self.div_rem(rhs)?;
15
16        Ok(quot)
17    }
18}
19
20impl<D: AsRef<[u8]>> Div<D> for Polynomial {
21    type Output = Result<Self, PolynomialDivError>;
22
23    fn div(self, rhs: D) -> Self::Output {
24        let (quot, _rem) = self.div_rem(rhs)?;
25
26        Ok(quot)
27    }
28}
29
30#[cfg(test)]
31#[allow(clippy::expect_used)]
32mod tests {
33    use std::ops::{Div, Mul};
34
35    use crate::{error::PolynomialDivError, Polynomial};
36
37    #[test]
38    fn div_returns_quotient() {
39        let a = Polynomial::try_from(&[1u8, 0, 1][..]).expect("valid polynomial");
40        let b = Polynomial::try_from(&[1u8, 1][..]).expect("valid polynomial");
41
42        let quot = a.div(&b).expect("division succeeds");
43
44        assert_eq!(quot.coefficients(), &[1, 1]);
45    }
46
47    #[test]
48    fn div_by_slice() {
49        let a = Polynomial::try_from(&[1u8, 0, 1][..]).expect("valid polynomial");
50        let b: &[u8] = &[1, 1];
51
52        let quot = a.div(b).expect("division succeeds");
53
54        assert_eq!(quot.coefficients(), &[1, 1]);
55    }
56
57    #[test]
58    fn div_by_array() {
59        let a = Polynomial::try_from(&[1u8, 0, 1][..]).expect("valid polynomial");
60
61        let quot = a.div([1u8, 1]).expect("division succeeds");
62
63        assert_eq!(quot.coefficients(), &[1, 1]);
64    }
65
66    #[test]
67    fn div_by_zero() {
68        let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
69        let zero = Polynomial::default();
70
71        let result = a.div(&zero);
72
73        assert_eq!(result, Err(PolynomialDivError::ZeroDivisor));
74    }
75
76    #[test]
77    fn div_mul_roundtrip() {
78        let a = Polynomial::try_from(&[3u8, 5, 7][..]).expect("valid polynomial");
79        let b = Polynomial::try_from(&[2u8, 4][..]).expect("valid polynomial");
80
81        let product = (&a).mul(&b).expect("multiplication succeeds");
82        let quot = product.div(&b).expect("division succeeds");
83
84        assert_eq!(quot, a);
85    }
86
87    #[test]
88    fn div_ref_lhs() {
89        let a = Polynomial::try_from(&[1u8, 0, 1][..]).expect("valid polynomial");
90        let b = Polynomial::try_from(&[1u8, 1][..]).expect("valid polynomial");
91
92        let quot = (&a).div(&b).expect("division succeeds");
93
94        assert_eq!(quot.coefficients(), &[1, 1]);
95        // a is still usable
96        assert_eq!(a.coefficients(), &[1, 0, 1]);
97    }
98}