ps_ecc/polynomial/implementations/
rem.rs1use std::ops::Rem;
2
3use crate::{error::PolynomialDivError, Polynomial};
4
5impl<D: AsRef<[u8]>> Rem<D> for &Polynomial {
6 type Output = Result<Polynomial, PolynomialDivError>;
7
8 fn rem(self, rhs: D) -> Self::Output {
14 let (_quot, rem) = self.div_rem(rhs)?;
15
16 Ok(rem)
17 }
18}
19
20impl<D: AsRef<[u8]>> Rem<D> for Polynomial {
21 type Output = Result<Self, PolynomialDivError>;
22
23 fn rem(self, rhs: D) -> Self::Output {
24 let (_quot, rem) = self.div_rem(rhs)?;
25
26 Ok(rem)
27 }
28}
29
30#[cfg(test)]
31#[allow(clippy::expect_used)]
32mod tests {
33 use std::ops::{Div, Mul, Rem};
34
35 use crate::{error::PolynomialDivError, Polynomial};
36
37 #[test]
38 fn rem_returns_remainder() {
39 let a = Polynomial::try_from(&[1u8, 1, 1][..]).expect("valid polynomial");
41 let b = Polynomial::try_from(&[1u8, 1][..]).expect("valid polynomial");
42
43 let rem = a.rem(&b).expect("division succeeds");
44
45 let (_quot, expected_rem) = a.div_rem(b).expect("division succeeds");
47
48 assert_eq!(rem, expected_rem);
49 }
50
51 #[test]
52 fn rem_zero_when_divisible() {
53 let a = Polynomial::try_from(&[1u8, 0, 1][..]).expect("valid polynomial");
55 let b = Polynomial::try_from(&[1u8, 1][..]).expect("valid polynomial");
56
57 let rem = a.rem(&b).expect("division succeeds");
58
59 assert_eq!(rem.coefficients(), &[0]);
60 }
61
62 #[test]
63 fn rem_by_slice() {
64 let a = Polynomial::try_from(&[1u8, 1, 1][..]).expect("valid polynomial");
65 let b: &[u8] = &[1, 1];
66
67 let rem = a.rem(b).expect("division succeeds");
68 let (_quot, expected_rem) = a.div_rem(b).expect("division succeeds");
69
70 assert_eq!(rem, expected_rem);
71 }
72
73 #[test]
74 fn rem_by_array() {
75 let a = Polynomial::try_from(&[1u8, 1, 1][..]).expect("valid polynomial");
76
77 let rem = a.rem([1u8, 1]).expect("division succeeds");
78 let (_quot, expected_rem) = a.div_rem([1u8, 1]).expect("division succeeds");
79
80 assert_eq!(rem, expected_rem);
81 }
82
83 #[test]
84 fn rem_by_zero() {
85 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
86 let zero = Polynomial::default();
87
88 let result = a.rem(&zero);
89
90 assert_eq!(result, Err(PolynomialDivError::ZeroDivisor));
91 }
92
93 #[test]
94 fn rem_ref_lhs() {
95 let a = Polynomial::try_from(&[1u8, 1, 1][..]).expect("valid polynomial");
96 let b = Polynomial::try_from(&[1u8, 1][..]).expect("valid polynomial");
97
98 let rem = (&a).rem(&b).expect("division succeeds");
99 let (_quot, expected_rem) = a.div_rem(b).expect("division succeeds");
100
101 assert_eq!(rem, expected_rem);
102 }
103
104 #[test]
105 fn rem_smaller_than_divisor() {
106 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
108 let b = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
109
110 let rem = a.rem(&b).expect("division succeeds");
111
112 assert_eq!(rem.coefficients(), &[1, 2]);
113 }
114
115 #[test]
116 fn div_rem_identity() {
117 let a = Polynomial::try_from(&[3u8, 5, 7, 11][..]).expect("valid polynomial");
119 let b = Polynomial::try_from(&[2u8, 4][..]).expect("valid polynomial");
120
121 let quot = (&a).div(&b).expect("division succeeds");
122 let rem = (&a).rem(&b).expect("division succeeds");
123
124 let product = quot.mul(&b).expect("multiplication succeeds");
125 let reconstructed = (product + rem).expect("addition succeeds");
126
127 assert_eq!(reconstructed, a);
128 }
129}