ps_ecc/polynomial/implementations/mul/
polynomial.rs1use std::ops::Mul;
2
3use crate::{error::PolynomialMulError, Polynomial};
4
5use super::mul_coefficient_slices;
6
7impl Mul<&Polynomial> for &Polynomial {
8 type Output = Result<Polynomial, PolynomialMulError>;
9
10 fn mul(self, rhs: &Polynomial) -> Self::Output {
16 mul_coefficient_slices(self.coefficients(), rhs.coefficients())
17 }
18}
19
20impl Mul<&Self> for Polynomial {
21 type Output = Result<Self, PolynomialMulError>;
22
23 fn mul(self, rhs: &Self) -> Self::Output {
24 (&self).mul(rhs)
25 }
26}
27
28impl Mul<Self> for Polynomial {
29 type Output = Result<Self, PolynomialMulError>;
30
31 fn mul(self, rhs: Self) -> Self::Output {
32 (&self).mul(&rhs)
33 }
34}
35
36impl Mul<Polynomial> for &Polynomial {
37 type Output = Result<Polynomial, PolynomialMulError>;
38
39 fn mul(self, rhs: Polynomial) -> Self::Output {
40 self.mul(&rhs)
41 }
42}
43
44#[cfg(test)]
45#[allow(clippy::expect_used)]
46mod tests {
47 use std::ops::Mul;
48
49 use crate::{error::PolynomialMulError, Polynomial};
50
51 #[test]
52 fn mul_two_polynomials() {
53 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
56 let b = Polynomial::try_from(&[3u8, 4][..]).expect("valid polynomial");
57
58 let result = a.mul(&b).expect("degree fits");
59
60 assert_eq!(result.coefficients(), &[3, 2, 8]);
64 }
65
66 #[test]
67 fn mul_by_zero() {
68 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
69 let zero = Polynomial::default();
70
71 let result = a.mul(&zero).expect("degree fits");
72
73 assert_eq!(result.degree(), 0);
74 assert_eq!(result.coefficients(), &[0]);
75 }
76
77 #[test]
78 fn mul_by_one() {
79 let a = Polynomial::try_from(&[5u8, 10, 15][..]).expect("valid polynomial");
80 let one = Polynomial::try_from(&[1u8][..]).expect("valid polynomial");
81
82 let result = a.mul(&one).expect("degree fits");
83
84 assert_eq!(result.coefficients(), &[5, 10, 15]);
85 }
86
87 #[test]
88 fn mul_by_x() {
89 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
91 let x = Polynomial::try_from(&[0u8, 1][..]).expect("valid polynomial");
92
93 let result = a.mul(&x).expect("degree fits");
94
95 assert_eq!(result.coefficients(), &[0, 1, 2, 3]);
96 }
97
98 #[test]
99 fn mul_degree_overflow() {
100 let mut coeffs = [0u8; 200];
102
103 coeffs[199] = 1; let a = Polynomial::try_from(&coeffs[..]).expect("valid polynomial");
106
107 let result = a.mul(&a);
109
110 assert_eq!(result, Err(PolynomialMulError::DegreeOverflow));
111 }
112
113 #[test]
114 fn mul_with_references() {
115 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
116 let b = Polynomial::try_from(&[3u8, 4][..]).expect("valid polynomial");
117
118 let r1 = (&a).mul(&b).expect("degree fits");
120 let r2 = (&a).mul(b).expect("degree fits");
121 let r3 = a.mul(&b).expect("degree fits");
122 let r4 = a.mul(b).expect("degree fits");
123
124 assert_eq!(r1, r2);
125 assert_eq!(r2, r3);
126 assert_eq!(r3, r4);
127 }
128
129 #[test]
130 fn mul_max_degree_exactly() {
131 let mut coeffs = [0u8; 128];
133
134 coeffs[127] = 1;
135
136 let a = Polynomial::try_from(&coeffs[..]).expect("valid polynomial");
137
138 let result = a.mul(&a).expect("should succeed at boundary");
139
140 assert_eq!(result.degree(), 254);
141 }
142
143 #[test]
144 fn mul_is_commutative() {
145 let a = Polynomial::try_from(&[1u8, 2, 3, 4][..]).expect("valid polynomial");
146 let b = Polynomial::try_from(&[5u8, 6, 7][..]).expect("valid polynomial");
147
148 let ab = (&a).mul(&b).expect("degree fits");
149 let ba = (&b).mul(&a).expect("degree fits");
150
151 assert_eq!(ab, ba);
152 }
153}