ps_ecc/polynomial/implementations/
add.rs1use std::{
2 borrow::Borrow,
3 ops::{Add, BitXor},
4};
5
6use crate::{error::PolynomialXorError, Polynomial};
7
8impl<B: Borrow<u8>, I: IntoIterator<Item = B>> Add<I> for Polynomial {
9 type Output = Result<Self, PolynomialXorError>;
10
11 fn add(self, rhs: I) -> Self::Output {
19 BitXor::bitxor(self, rhs)
20 }
21}
22
23impl<B: Borrow<u8>, I: IntoIterator<Item = B>> Add<I> for &Polynomial {
24 type Output = Result<Polynomial, PolynomialXorError>;
25
26 fn add(self, rhs: I) -> Self::Output {
27 BitXor::bitxor(*self, rhs)
28 }
29}
30
31#[cfg(test)]
32#[allow(clippy::expect_used)]
33mod tests {
34 use std::ops::Add;
35
36 use crate::{error::PolynomialXorError, Polynomial};
37
38 #[test]
39 fn add_two_polynomials() {
40 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
41 let b = Polynomial::try_from(&[4u8, 5, 6][..]).expect("valid polynomial");
42
43 let result = a.add(b).expect("polynomials are bounded");
44
45 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
46 }
47
48 #[test]
49 fn add_different_degrees() {
50 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
51 let b = Polynomial::try_from(&[3u8, 4, 5, 6][..]).expect("valid polynomial");
52
53 let result = a.add(b).expect("polynomials are bounded");
54
55 assert_eq!(result.coefficients(), &[1 ^ 3, 2 ^ 4, 5, 6]);
56 }
57
58 #[test]
59 fn add_cancels_to_zero() {
60 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
61 let b = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
62
63 let result = a.add(b).expect("polynomials are bounded");
64
65 assert_eq!(result.degree(), 0);
66 assert_eq!(result.coefficients(), &[0]);
67 }
68
69 #[test]
70 fn add_with_references() {
71 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
72 let b = Polynomial::try_from(&[4u8, 5, 6][..]).expect("valid polynomial");
73
74 let result = (&a).add(&b).expect("polynomials are bounded");
75
76 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
77 }
78
79 #[test]
80 fn add_slice_via_iter() {
81 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
82 let slice: &[u8] = &[4, 5, 6];
83
84 let result = a.add(slice.iter()).expect("valid slice");
85
86 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
87 }
88
89 #[test]
90 fn add_slice_different_lengths() {
91 let a = Polynomial::try_from(&[1u8, 2][..]).expect("valid polynomial");
92 let slice: &[u8] = &[3, 4, 5, 6];
93
94 let result = a.add(slice.iter()).expect("valid slice");
95
96 assert_eq!(result.coefficients(), &[1 ^ 3, 2 ^ 4, 5, 6]);
97 }
98
99 #[test]
100 fn add_iterator() {
101 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
102 let iter = [4u8, 5, 6].into_iter();
103
104 let result = a.add(iter).expect("valid iterator");
105
106 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6]);
107 }
108
109 #[test]
110 fn add_vec() {
111 let a = Polynomial::try_from(&[1u8, 2, 3][..]).expect("valid polynomial");
112 let vec = vec![4u8, 5, 6, 7];
113
114 let result = a.add(vec).expect("valid vec");
115
116 assert_eq!(result.coefficients(), &[1 ^ 4, 2 ^ 5, 3 ^ 6, 7]);
117 }
118
119 #[test]
120 fn add_iterator_too_long_returns_error() {
121 let a = Polynomial::default();
122 let iter = std::iter::repeat_n(1u8, 256);
123
124 let result = a.add(iter);
125
126 assert_eq!(result, Err(PolynomialXorError::TooManyCoefficients));
127 }
128}