1use crate::utils;
2use anyhow::{Context, Result, anyhow};
3use starkom_bluesky::ThreeAdicField;
4use starkom_ff::PrimeField;
5use std::any::{Any, TypeId};
6use std::collections::BTreeMap;
7use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8use std::sync::{Mutex, OnceLock};
9
10fn make_lagrange0<F: PrimeField>(n: usize) -> Polynomial<F> {
14 let mut coefficients = vec![F::ZERO; n + 1];
15 coefficients[0] = -F::ONE;
16 coefficients[n] = F::ONE;
17 let zero = Polynomial { coefficients };
18 let (quotient, remainder) = zero.horner(F::ONE);
19 assert_eq!(remainder, F::ZERO);
20 quotient * F::try_from(n).unwrap().invert().into_option().unwrap()
21}
22
23#[derive(Debug, Default, Clone, PartialEq, Eq)]
26pub struct Polynomial<F: PrimeField> {
27 coefficients: Vec<F>,
28}
29
30impl<F: PrimeField> Polynomial<F> {
31 pub fn with_coefficients(coefficients: Vec<F>) -> Self {
34 Self { coefficients }
35 }
36
37 pub fn constant(y: F) -> Self {
39 Self {
40 coefficients: vec![y],
41 }
42 }
43
44 pub fn interpolate(points: &[(F, F)]) -> Result<Self> {
50 let k = points.len();
51 let x = points.iter().map(|(x, _)| *x).collect::<Vec<F>>();
52 let l = Self::from_roots(x.as_slice(), F::ONE).context("duplicate X-coordinates")?;
53 let w = {
54 let one = F::ONE;
55 let mut weights = vec![one; k];
56 for i in 0..k {
57 for j in 0..k {
58 if i != j {
59 weights[i] *= x[i] - x[j];
60 }
61 }
62 weights[i] = weights[i]
63 .invert()
64 .into_option()
65 .context("duplicate X-coordinates")?;
66 }
67 weights
68 };
69 let mut result = Self {
70 coefficients: Vec::with_capacity(points.len()),
71 };
72 for i in 0..k {
73 let (basis, remainder) = l.horner(x[i]);
74 assert_eq!(remainder, F::ZERO);
75 let (_, y) = points[i];
76 result += basis * w[i] * y;
77 }
78 Ok(result)
79 }
80
81 pub fn from_roots(roots: &[F], blinding_factor: F) -> Result<Self> {
91 let mut roots = roots.to_vec();
92 roots.sort();
93 for i in 1..roots.len() {
94 if roots[i] == roots[i - 1] {
95 return Err(anyhow!("duplicate roots"));
96 }
97 }
98 let n = roots.len() + 1;
99 let mut coefficients = vec![F::ZERO; n];
100 coefficients[0] = blinding_factor;
101 for i in 1..n {
102 for j in (0..i).rev() {
103 let c = coefficients[j];
104 coefficients[j + 1] -= c * roots[i - 1];
105 }
106 }
107 coefficients.reverse();
108 Ok(Self { coefficients })
109 }
110
111 fn fft2(data: &mut [F], omega: F) {
118 let n = data.len();
119 assert!(n.is_power_of_two());
120
121 let log_n = n.trailing_zeros();
122 assert!(log_n as usize <= F::S);
123
124 for i in 0..n {
125 let (j, _) = i.reverse_bits().overflowing_shr(usize::BITS - log_n);
126 if i < j {
127 data.swap(i, j);
128 }
129 }
130
131 let mut m = 1;
132 for _ in 0..log_n {
133 let step = m * 2;
134 let wm = omega.pow_small(n / step);
135 let mut w = F::ONE;
136 for k in 0..m {
137 for j in (k..n).step_by(step) {
138 let t = w * data[j + m];
139 let u = data[j];
140 data[j] = u + t;
141 data[j + m] = u - t;
142 }
143 w *= wm;
144 }
145 m = step;
146 }
147 }
148
149 fn ifft2(data: &mut [F], omega: F) {
156 Self::fft2(data, omega.invert().into_option().unwrap());
157 let n_inv = F::try_from(data.len()).unwrap().invert().unwrap();
158 for v in data.iter_mut() {
159 *v *= n_inv;
160 }
161 }
162
163 fn two_adic_root_of_unity(n: usize) -> F {
165 assert!(n.is_power_of_two());
166 let k = n.trailing_zeros() as usize;
167 assert!(k <= F::S);
168 let exponent = 1u64 << (F::S - k);
169 F::ROOT_OF_UNITY.pow_u64(exponent)
170 }
171
172 pub fn encode2(mut values: Vec<F>) -> Self {
191 assert!(!values.is_empty());
192 let n = values.len().next_power_of_two();
193 assert!(n.trailing_zeros() as usize <= F::S);
194 values.resize(n, F::ZERO);
195 let omega = Self::two_adic_root_of_unity(values.len());
196 Self::ifft2(values.as_mut_slice(), omega);
197 let mut polynomial = Polynomial {
198 coefficients: values,
199 };
200 polynomial.trim();
201 polynomial
202 }
203
204 pub fn decode2(self) -> Vec<F> {
216 let mut data = self.coefficients;
217 let n = data.len().next_power_of_two();
218 data.resize(n, F::ZERO);
219 let omega = Self::two_adic_root_of_unity(n);
220 Self::fft2(&mut data, omega);
221 data
222 }
223
224 pub fn len(&self) -> usize {
226 self.coefficients.len()
227 }
228
229 pub fn coefficients(&self) -> &[F] {
231 self.coefficients.as_slice()
232 }
233
234 fn degree_bound_of(coefficients: &[F]) -> usize {
235 for (i, &coefficient) in coefficients.iter().enumerate().rev() {
236 if coefficient != F::ZERO {
237 return i + 1;
238 }
239 }
240 0
241 }
242
243 pub fn degree_bound(&self) -> usize {
250 Self::degree_bound_of(self.coefficients.as_slice())
251 }
252
253 pub fn trim(&mut self) {
261 if let Some(i) = self
262 .coefficients
263 .iter()
264 .rposition(|value| *value != F::ZERO)
265 {
266 self.coefficients.truncate(i + 1);
267 } else {
268 self.coefficients.clear();
269 }
270 }
271
272 pub fn pad(&mut self, min_degree_bound: usize) {
275 let new_length = std::cmp::max(min_degree_bound, self.coefficients.len());
276 self.coefficients.resize(new_length, F::ZERO);
277 }
278
279 pub fn take(self) -> Vec<F> {
284 return self.coefficients;
285 }
286
287 pub fn multiply(mut self, mut other: Self) -> Self {
290 self.trim();
291 other.trim();
292
293 let mut lhs = self.coefficients;
294 let mut rhs = other.coefficients;
295
296 if lhs.is_empty() || rhs.is_empty() {
297 return Polynomial {
298 coefficients: vec![],
299 };
300 }
301 if lhs.len() == 1 {
302 return Polynomial { coefficients: rhs } * lhs[0];
303 }
304 if rhs.len() == 1 {
305 return Polynomial { coefficients: lhs } * rhs[0];
306 }
307
308 let n = (lhs.len() + rhs.len() - 1).next_power_of_two();
309
310 lhs.resize(n, F::ZERO);
311 rhs.resize(n, F::ZERO);
312
313 let omega = Self::two_adic_root_of_unity(n);
314 Self::fft2(lhs.as_mut_slice(), omega);
315 Self::fft2(rhs.as_mut_slice(), omega);
316
317 for i in 0..n {
318 lhs[i] *= rhs[i];
319 }
320
321 Self::ifft2(lhs.as_mut_slice(), omega);
322
323 let mut result = Polynomial { coefficients: lhs };
324 result.trim();
325 result
326 }
327
328 fn multiply_many_impl(polynomials: &mut [Self]) -> Self {
330 match polynomials.len() {
331 0 => Polynomial {
332 coefficients: vec![],
333 },
334 1 => std::mem::take(&mut polynomials[0]),
335 2 => {
336 let lhs = std::mem::take(&mut polynomials[0]);
337 let rhs = std::mem::take(&mut polynomials[1]);
338 lhs.multiply(rhs)
339 }
340 n => {
341 let (left, right) = polynomials.split_at_mut(n / 2);
342 let left = Self::multiply_many_impl(left);
343 let right = Self::multiply_many_impl(right);
344 left.multiply(right)
345 }
346 }
347 }
348
349 pub fn multiply_many<const N: usize>(mut polynomials: [Self; N]) -> Self {
355 assert!(N > 0);
356 Self::multiply_many_impl(&mut polynomials)
357 }
358
359 pub fn multiply_values2(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
368 let n = lhs.len();
369 assert!(n.is_power_of_two());
370 assert!(n.trailing_zeros() as usize + 1 <= F::S);
371 assert_eq!(rhs.len(), n);
372 let omega = Self::two_adic_root_of_unity(n);
373 Self::ifft2(&mut lhs, omega);
374 Self::ifft2(&mut rhs, omega);
375 let lhs_len = Self::degree_bound_of(lhs.as_slice());
376 let rhs_len = Self::degree_bound_of(rhs.as_slice());
377 let m = (lhs_len + rhs_len - 1).next_power_of_two();
378 lhs.resize(m, F::ZERO);
379 rhs.resize(m, F::ZERO);
380 let omega = Self::two_adic_root_of_unity(m);
381 Self::fft2(&mut lhs, omega);
382 Self::fft2(&mut rhs, omega);
383 for i in 0..m {
384 lhs[i] *= rhs[i];
385 }
386 lhs
387 }
388
389 pub fn horner(&self, z: F) -> (Self, F) {
394 if self.coefficients.is_empty() {
395 return (Polynomial::default(), F::ZERO);
396 }
397 let n = self.len() - 1;
398 let mut coefficients = vec![F::ZERO; n];
399 if n < 1 {
400 return (Polynomial { coefficients }, self.coefficients[0]);
401 }
402 coefficients[n - 1] = self.coefficients[n];
403 for i in (1..n).rev() {
404 coefficients[i - 1] = self.coefficients[i] + z * coefficients[i];
405 }
406 let remainder = self.coefficients[0] + z * coefficients[0];
407 (Polynomial { coefficients }, remainder)
408 }
409
410 pub fn divide_by_zero(&self, n: usize) -> Result<Self> {
423 let mut data = self.coefficients.clone();
424 if data.len() < n {
425 data.resize(n, F::ZERO);
426 }
427
428 let degree = data.len() - n;
429 let mut quotient = vec![F::ZERO; degree];
430
431 let neg_one = F::ZERO - F::ONE;
432 for i in 0..degree {
433 let c = data[i] * neg_one;
434 quotient[i] = c;
435 data[i] += c;
436 data[i + n] -= c;
437 }
438
439 let remainder = &data[degree..];
440 if remainder.iter().any(|c| *c != F::ZERO) {
441 return Err(anyhow!("non-zero remainder in division by (x^n - 1)"));
442 }
443
444 if let Some(i) = quotient.iter().rposition(|c| *c != F::ZERO) {
445 quotient.truncate(i + 1);
446 }
447 Ok(Polynomial {
448 coefficients: quotient,
449 })
450 }
451
452 pub fn evaluate(&self, x: F) -> F {
460 let mut y = F::ZERO;
461 for coefficient in self.coefficients.iter().rev() {
462 y = y * x + *coefficient;
463 }
464 y
465 }
466
467 pub fn shift_domain(self) -> Self {
475 let mut coefficients = self.coefficients;
476 let mut shift_pow = F::ONE;
477 for c in coefficients.iter_mut() {
478 *c *= shift_pow;
479 shift_pow *= F::MULTIPLICATIVE_GENERATOR;
480 }
481 Self { coefficients }
482 }
483
484 pub fn domain_element2(index: usize, domain_size: usize) -> F {
494 let omega = Self::two_adic_root_of_unity(domain_size.next_power_of_two());
495 omega.pow_small(index)
496 }
497
498 pub fn coset_element2(index: usize, domain_size: usize) -> F {
505 F::MULTIPLICATIVE_GENERATOR * Self::domain_element2(index, domain_size)
506 }
507
508 pub fn evaluate_on_two_adic_domain(&self, index: usize, domain_size: usize) -> F {
512 self.evaluate(Self::domain_element2(index, domain_size))
513 }
514
515 pub fn evaluate_on_two_adic_coset(&self, index: usize, domain_size: usize) -> F {
519 self.evaluate(Self::coset_element2(index, domain_size))
520 }
521
522 pub fn lde2(self, m: usize) -> Vec<F> {
532 assert!(m.is_power_of_two());
533 assert!(m.trailing_zeros() as usize <= F::S);
534 assert!(self.coefficients.len() < m);
535 let mut data = self.coefficients;
536 data.resize(m, F::ZERO);
537 let omega = Self::two_adic_root_of_unity(m);
538 Self::fft2(&mut data, omega);
539 data
540 }
541
542 pub fn fold2(self, alpha: F) -> Self {
546 let coefficients = self.coefficients();
547 let m = (coefficients.len() + 1) / 2;
548 let new_coefficients = (0..m)
549 .map(|i| {
550 coefficients[2 * i]
551 + alpha * coefficients.get(2 * i + 1).copied().unwrap_or(F::ZERO)
552 })
553 .collect();
554 Self::with_coefficients(new_coefficients)
555 }
556}
557
558impl<F: PrimeField + ThreeAdicField> Polynomial<F> {
559 fn fft3(data: &mut [F], omega: F) {
566 let n = data.len();
567 assert!(utils::is_power_of_three(n));
568
569 let log_n = utils::ilog3(n);
570
571 for i in 0..n {
572 let mut j = 0;
573 let mut tmp = i;
574 for _ in 0..log_n {
575 j = j * 3 + tmp % 3;
576 tmp /= 3;
577 }
578 if i < j {
579 data.swap(i, j);
580 }
581 }
582
583 let omega3 = omega.pow_small(n / 3);
584 let omega3_sq = omega3 * omega3;
585
586 let mut m = 1;
587 for _ in 0..log_n {
588 let step = m * 3;
589 let wm = omega.pow_small(n / step);
590 let mut w = F::ONE;
591 let mut w2 = F::ONE;
592 for k in 0..m {
593 for j in (k..n).step_by(step) {
594 let t0 = data[j];
595 let t1 = w * data[j + m];
596 let t2 = w2 * data[j + 2 * m];
597 data[j] = t0 + t1 + t2;
598 data[j + m] = t0 + omega3 * t1 + omega3_sq * t2;
599 data[j + 2 * m] = t0 + omega3_sq * t1 + omega3 * t2;
600 }
601 w *= wm;
602 w2 = w * w;
603 }
604 m = step;
605 }
606 }
607
608 fn ifft3(data: &mut [F], omega: F) {
615 Self::fft3(data, omega.invert().into_option().unwrap());
616 let n_inv = F::try_from(data.len()).unwrap().invert().unwrap();
617 for v in data.iter_mut() {
618 *v *= n_inv;
619 }
620 }
621
622 fn three_adic_root_of_unity(n: usize) -> F {
624 assert!(utils::is_power_of_three(n));
625 let k = utils::ilog3(n) as u32;
626 assert!(k <= F::T);
627 let exponent = 3u64.pow(F::T - k);
628 F::THREE_ADIC_ROOT_OF_UNITY.pow_u64(exponent)
629 }
630
631 pub fn encode3(mut values: Vec<F>) -> Self {
650 assert!(!values.is_empty());
651 let n = utils::next_power_of_three(values.len());
652 assert!(utils::ilog3(n) <= F::T as usize);
653 values.resize(n, F::ZERO);
654 let omega = Self::three_adic_root_of_unity(values.len());
655 Self::ifft3(values.as_mut_slice(), omega);
656 let mut polynomial = Polynomial {
657 coefficients: values,
658 };
659 polynomial.trim();
660 polynomial
661 }
662
663 pub fn decode3(self) -> Vec<F> {
675 let mut data = self.coefficients;
676 let n = utils::next_power_of_three(data.len());
677 data.resize(n, F::ZERO);
678 let omega = Self::three_adic_root_of_unity(n);
679 Self::fft3(&mut data, omega);
680 data
681 }
682
683 pub fn domain_element3(index: usize, domain_size: usize) -> F {
693 let omega = Self::three_adic_root_of_unity(utils::next_power_of_three(domain_size));
694 omega.pow_small(index)
695 }
696
697 pub fn coset_element3(index: usize, domain_size: usize) -> F {
704 F::MULTIPLICATIVE_GENERATOR * Self::domain_element3(index, domain_size)
705 }
706
707 pub fn evaluate_on_three_adic_domain(&self, index: usize, domain_size: usize) -> F {
711 self.evaluate(Self::domain_element3(index, domain_size))
712 }
713
714 pub fn evaluate_on_three_adic_coset(&self, index: usize, domain_size: usize) -> F {
718 self.evaluate(Self::coset_element3(index, domain_size))
719 }
720
721 pub fn lde3(self, m: usize) -> Vec<F> {
732 assert!(utils::is_power_of_three(m));
733 assert!(utils::ilog3(m) as u32 <= F::T);
734 assert!(self.coefficients.len() < m);
735 let mut data = self.coefficients;
736 data.resize(m, F::ZERO);
737 let omega = Self::three_adic_root_of_unity(m);
738 Self::fft3(&mut data, omega);
739 data
740 }
741
742 pub fn fold3(self, alpha: F) -> Self {
746 let coefficients = self.coefficients();
747 let m = (coefficients.len() + 2) / 3;
748 let alpha_square = alpha * alpha;
749 let new_coefficients = (0..m)
750 .map(|i| {
751 coefficients[3 * i]
752 + alpha * coefficients.get(3 * i + 1).copied().unwrap_or(F::ZERO)
753 + alpha_square * coefficients.get(3 * i + 2).copied().unwrap_or(F::ZERO)
754 })
755 .collect();
756 Self::with_coefficients(new_coefficients)
757 }
758
759 pub fn multiply_values3(mut lhs: Vec<F>, mut rhs: Vec<F>) -> Vec<F> {
768 let n = lhs.len();
769 assert!(utils::is_power_of_three(n));
770 assert!(utils::ilog3(n) as u32 + 1 <= F::T);
771 assert_eq!(rhs.len(), n);
772 let omega = Self::three_adic_root_of_unity(n);
773 Self::ifft3(&mut lhs, omega);
774 Self::ifft3(&mut rhs, omega);
775 let lhs_len = Self::degree_bound_of(lhs.as_slice());
776 let rhs_len = Self::degree_bound_of(rhs.as_slice());
777 let m = utils::next_power_of_three(lhs_len + rhs_len - 1);
778 lhs.resize(m, F::ZERO);
779 rhs.resize(m, F::ZERO);
780 let omega = Self::three_adic_root_of_unity(m);
781 Self::fft3(&mut lhs, omega);
782 Self::fft3(&mut rhs, omega);
783 for i in 0..m {
784 lhs[i] *= rhs[i];
785 }
786 lhs
787 }
788
789 pub fn lagrange0(n: usize) -> &'static Self {
805 assert!(n.is_power_of_two());
806 let k = n.trailing_zeros() as usize;
807 assert!(k <= F::S);
808
809 static CACHE: OnceLock<Mutex<BTreeMap<(TypeId, usize), &'static (dyn Any + Send + Sync)>>> =
810 OnceLock::new();
811 let cache = CACHE.get_or_init(|| Mutex::new(BTreeMap::new()));
812
813 let polynomial = {
814 let mut map = cache.lock().unwrap();
815 *map.entry((TypeId::of::<F>(), k)).or_insert_with(|| {
816 Box::leak(Box::new(make_lagrange0::<F>(1 << k))) as &'static (dyn Any + Send + Sync)
817 })
818 };
819
820 polynomial.downcast_ref::<Polynomial<F>>().unwrap()
821 }
822}
823
824impl<F: PrimeField> Neg for Polynomial<F> {
825 type Output = Self;
826
827 fn neg(mut self) -> Self::Output {
828 for coefficient in &mut self.coefficients {
829 *coefficient = -*coefficient;
830 }
831 self
832 }
833}
834
835impl<F: PrimeField> Add<Polynomial<F>> for Polynomial<F> {
836 type Output = Self;
837
838 fn add(mut self, rhs: Self) -> Self::Output {
839 if rhs.len() > self.len() {
840 return rhs + self;
841 }
842 for i in 0..rhs.len() {
843 self.coefficients[i] += rhs.coefficients[i];
844 }
845 self
846 }
847}
848
849impl<F: PrimeField> AddAssign<Polynomial<F>> for Polynomial<F> {
850 fn add_assign(&mut self, mut rhs: Self) {
851 if rhs.len() > self.len() {
852 for i in 0..self.len() {
853 rhs.coefficients[i] += self.coefficients[i];
854 }
855 self.coefficients = rhs.coefficients;
856 } else {
857 for i in 0..rhs.len() {
858 self.coefficients[i] += rhs.coefficients[i];
859 }
860 }
861 }
862}
863
864impl<F: PrimeField> Add<F> for Polynomial<F> {
865 type Output = Self;
866
867 fn add(mut self, rhs: F) -> Self::Output {
868 if self.coefficients.is_empty() {
869 self.coefficients.push(rhs);
870 } else {
871 self.coefficients[0] += rhs;
872 }
873 self
874 }
875}
876
877impl<F: PrimeField> AddAssign<F> for Polynomial<F> {
878 fn add_assign(&mut self, rhs: F) {
879 if self.coefficients.is_empty() {
880 self.coefficients.push(rhs);
881 } else {
882 self.coefficients[0] += rhs;
883 }
884 }
885}
886
887impl<F: PrimeField> Sub<Polynomial<F>> for Polynomial<F> {
888 type Output = Self;
889
890 fn sub(mut self, rhs: Self) -> Self::Output {
891 if rhs.len() > self.len() {
892 return -(rhs - self);
893 }
894 for i in 0..rhs.len() {
895 self.coefficients[i] -= rhs.coefficients[i];
896 }
897 self
898 }
899}
900
901impl<F: PrimeField> SubAssign<Polynomial<F>> for Polynomial<F> {
902 fn sub_assign(&mut self, mut rhs: Self) {
903 if rhs.len() > self.len() {
904 for i in 0..self.len() {
905 rhs.coefficients[i] -= self.coefficients[i];
906 }
907 self.coefficients = rhs.coefficients;
908 for i in 0..self.len() {
909 self.coefficients[i] = -self.coefficients[i];
910 }
911 } else {
912 for i in 0..rhs.len() {
913 self.coefficients[i] -= rhs.coefficients[i];
914 }
915 }
916 }
917}
918
919impl<F: PrimeField> Sub<F> for Polynomial<F> {
920 type Output = Self;
921
922 fn sub(mut self, rhs: F) -> Self::Output {
923 if self.coefficients.is_empty() {
924 self.coefficients.push(-rhs);
925 } else {
926 self.coefficients[0] -= rhs;
927 }
928 self
929 }
930}
931
932impl<F: PrimeField> SubAssign<F> for Polynomial<F> {
933 fn sub_assign(&mut self, rhs: F) {
934 if self.coefficients.is_empty() {
935 self.coefficients.push(-rhs);
936 } else {
937 self.coefficients[0] -= rhs;
938 }
939 }
940}
941
942impl<F: PrimeField> Mul<F> for Polynomial<F> {
943 type Output = Self;
944
945 fn mul(mut self, rhs: F) -> Self::Output {
946 for i in 0..self.len() {
947 self.coefficients[i] *= rhs;
948 }
949 self
950 }
951}
952
953impl<F: PrimeField> MulAssign<F> for Polynomial<F> {
954 fn mul_assign(&mut self, rhs: F) {
955 for i in 0..self.len() {
956 self.coefficients[i] *= rhs;
957 }
958 }
959}
960
961impl<F: PrimeField> Mul<Polynomial<F>> for Polynomial<F> {
962 type Output = Self;
963
964 fn mul(self, rhs: Self) -> Self::Output {
965 self.multiply(rhs)
966 }
967}
968
969impl<F: PrimeField> MulAssign<Polynomial<F>> for Polynomial<F> {
970 fn mul_assign(&mut self, rhs: Self) {
971 *self = std::mem::take(self).multiply(rhs);
972 }
973}
974
975#[cfg(test)]
976mod tests {
977 use starkom_bluesky::{Scalar, from_const};
978 use starkom_ff::Field;
979
980 type Polynomial = super::Polynomial<Scalar>;
981
982 #[inline(always)]
983 fn get_random_scalar() -> Scalar {
984 Scalar::random_default()
985 }
986
987 fn from_roots(roots: &[Scalar]) -> Polynomial {
988 Polynomial::from_roots(roots, get_random_scalar()).unwrap()
989 }
990
991 #[test]
992 fn test_constant() {
993 let p = Polynomial::constant(from_const(42));
994 assert_eq!(p.evaluate(from_const(12)), from_const(42));
995 assert_eq!(p.evaluate(from_const(34)), from_const(42));
996 assert_eq!(p.evaluate(from_const(42)), from_const(42));
997 }
998
999 #[test]
1000 fn test_zero() {
1001 let p = Polynomial::with_coefficients(vec![]);
1002 assert_eq!(p, Polynomial::default());
1003 assert_eq!(p.len(), 0);
1004 assert_eq!(p.degree_bound(), 0);
1005 assert_eq!(p.evaluate(from_const(42)), from_const(0));
1006 }
1007
1008 #[test]
1009 fn test_with_coefficients() {
1010 let p = Polynomial::with_coefficients(vec![from_const(12), from_const(34), from_const(56)]);
1011 assert_eq!(p.len(), 3);
1012 assert_eq!(p.degree_bound(), 3);
1013 assert_eq!(
1014 p.take(),
1015 vec![from_const(12), from_const(34), from_const(56)]
1016 );
1017 }
1018
1019 #[test]
1020 fn test_low_degree() {
1021 let p = Polynomial::with_coefficients(vec![
1022 from_const(12),
1023 from_const(34),
1024 from_const(56),
1025 from_const(0),
1026 from_const(0),
1027 ]);
1028 assert_eq!(p.len(), 5);
1029 assert_eq!(p.degree_bound(), 3);
1030 }
1031
1032 #[test]
1033 fn test_skip_degree() {
1034 let p = Polynomial::with_coefficients(vec![
1035 from_const(0),
1036 from_const(0),
1037 from_const(12),
1038 from_const(34),
1039 from_const(56),
1040 ]);
1041 assert_eq!(p.len(), 5);
1042 assert_eq!(p.degree_bound(), 5);
1043 }
1044
1045 #[test]
1046 fn test_trim_degree() {
1047 let mut p = Polynomial::with_coefficients(vec![
1048 from_const(12),
1049 from_const(34),
1050 from_const(56),
1051 from_const(0),
1052 from_const(0),
1053 ]);
1054 p.trim();
1055 assert_eq!(p.len(), 3);
1056 assert_eq!(p.degree_bound(), 3);
1057 }
1058
1059 #[test]
1060 fn test_no_trim() {
1061 let mut p = Polynomial::with_coefficients(vec![
1062 from_const(0),
1063 from_const(0),
1064 from_const(12),
1065 from_const(34),
1066 from_const(56),
1067 ]);
1068 p.trim();
1069 assert_eq!(p.len(), 5);
1070 assert_eq!(p.degree_bound(), 5);
1071 }
1072
1073 #[test]
1074 fn test_trim_all_zero() {
1075 let mut p =
1076 Polynomial::with_coefficients(vec![from_const(0), from_const(0), from_const(0)]);
1077 p.trim();
1078 assert_eq!(p.len(), p.degree_bound());
1079 assert_eq!(p, Polynomial::default());
1080 }
1081
1082 #[test]
1083 fn test_pad_extends() {
1084 let mut p = Polynomial::with_coefficients(vec![from_const(12), from_const(34)]);
1085 p.pad(5);
1086 assert_eq!(p.len(), 5);
1087 assert_eq!(
1088 p.take(),
1089 vec![
1090 from_const(12),
1091 from_const(34),
1092 from_const(0),
1093 from_const(0),
1094 from_const(0)
1095 ]
1096 );
1097 }
1098
1099 #[test]
1100 fn test_pad_exact() {
1101 let mut p =
1102 Polynomial::with_coefficients(vec![from_const(12), from_const(34), from_const(56)]);
1103 p.pad(3);
1104 assert_eq!(p.len(), 3);
1105 assert_eq!(
1106 p.take(),
1107 vec![from_const(12), from_const(34), from_const(56)]
1108 );
1109 }
1110
1111 #[test]
1112 fn test_pad_no_shrink() {
1113 let mut p = Polynomial::with_coefficients(vec![
1114 from_const(12),
1115 from_const(34),
1116 from_const(56),
1117 from_const(78),
1118 ]);
1119 p.pad(2);
1120 assert_eq!(p.len(), 4);
1121 assert_eq!(
1122 p.take(),
1123 vec![
1124 from_const(12),
1125 from_const(34),
1126 from_const(56),
1127 from_const(78)
1128 ]
1129 );
1130 }
1131
1132 #[test]
1133 fn test_pad_empty() {
1134 let mut p = Polynomial::default();
1135 p.pad(3);
1136 assert_eq!(p.len(), 3);
1137 assert_eq!(p.take(), vec![from_const(0), from_const(0), from_const(0)]);
1138 }
1139
1140 #[test]
1141 fn test_pad_zero_bound() {
1142 let mut p = Polynomial::with_coefficients(vec![from_const(12), from_const(34)]);
1143 p.pad(0);
1144 assert_eq!(p.len(), 2);
1145 assert_eq!(p.take(), vec![from_const(12), from_const(34)]);
1146 }
1147
1148 #[test]
1149 fn test_pad_preserves_evaluation() {
1150 let mut p =
1151 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
1152 let before = p.evaluate(from_const(7));
1153 p.pad(6);
1154 assert_eq!(p.evaluate(from_const(7)), before);
1155 }
1156
1157 #[test]
1158 fn test_no_roots() {
1159 let p = from_roots(&[]);
1160 assert_eq!(p.len(), 1);
1161 assert_eq!(p.degree_bound(), 1);
1162 assert_ne!(p.evaluate(from_const(12)), from_const(0));
1163 assert_ne!(p.evaluate(from_const(34)), from_const(0));
1164 assert_ne!(p.evaluate(from_const(56)), from_const(0));
1165 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1166 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1167 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1168 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1169 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1170 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1171 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1172 }
1173
1174 #[test]
1175 fn test_one_root() {
1176 let p = from_roots(&[from_const(12)]);
1177 assert_eq!(p.len(), 2);
1178 assert_eq!(p.degree_bound(), 2);
1179 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1180 assert_ne!(p.evaluate(from_const(34)), from_const(0));
1181 assert_ne!(p.evaluate(from_const(56)), from_const(0));
1182 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1183 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1184 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1185 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1186 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1187 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1188 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1189 let (q, v) = p.horner(from_const(12));
1190 assert_eq!(q.len(), 1);
1191 assert_eq!(q.degree_bound(), 1);
1192 assert_eq!(v, from_const(0));
1193 let (q, v) = p.horner(from_const(34));
1194 assert_eq!(q.len(), 1);
1195 assert_eq!(q.degree_bound(), 1);
1196 assert_ne!(v, from_const(0));
1197 }
1198
1199 #[test]
1200 fn test_three_roots() {
1201 let p = from_roots(&[from_const(12), from_const(34), from_const(56)]);
1202 assert_eq!(p.len(), 4);
1203 assert_eq!(p.degree_bound(), 4);
1204 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1205 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1206 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1207 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1208 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1209 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1210 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1211 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1212 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1213 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1214 let (q, v) = p.horner(from_const(12));
1215 assert_eq!(q.len(), 3);
1216 assert_eq!(q.degree_bound(), 3);
1217 assert_eq!(v, from_const(0));
1218 let (q, v) = q.horner(from_const(34));
1219 assert_eq!(q.len(), 2);
1220 assert_eq!(q.degree_bound(), 2);
1221 assert_eq!(v, from_const(0));
1222 let (q, v) = q.horner(from_const(56));
1223 assert_eq!(q.len(), 1);
1224 assert_eq!(q.degree_bound(), 1);
1225 assert_eq!(v, from_const(0));
1226 let (q, v) = p.horner(from_const(78));
1227 assert_eq!(q.len(), 3);
1228 assert_eq!(q.degree_bound(), 3);
1229 assert_ne!(v, from_const(0));
1230 let (q, v) = p.horner(from_const(90));
1231 assert_eq!(q.len(), 3);
1232 assert_eq!(q.degree_bound(), 3);
1233 assert_ne!(v, from_const(0));
1234 }
1235
1236 #[test]
1237 fn test_three_roots_reverse_order() {
1238 let p = from_roots(&[from_const(56), from_const(34), from_const(12)]);
1239 assert_eq!(p.len(), 4);
1240 assert_eq!(p.degree_bound(), 4);
1241 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1242 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1243 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1244 assert_ne!(p.evaluate(from_const(78)), from_const(0));
1245 assert_ne!(p.evaluate(from_const(90)), from_const(0));
1246 assert_ne!(p.evaluate(from_const(13)), from_const(0));
1247 assert_ne!(p.evaluate(from_const(57)), from_const(0));
1248 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1249 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1250 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1251 let (q, v) = p.horner(from_const(12));
1252 assert_eq!(q.len(), 3);
1253 assert_eq!(q.degree_bound(), 3);
1254 assert_eq!(v, from_const(0));
1255 let (q, v) = q.horner(from_const(34));
1256 assert_eq!(q.len(), 2);
1257 assert_eq!(q.degree_bound(), 2);
1258 assert_eq!(v, from_const(0));
1259 let (q, v) = q.horner(from_const(56));
1260 assert_eq!(q.len(), 1);
1261 assert_eq!(q.degree_bound(), 1);
1262 assert_eq!(v, from_const(0));
1263 let (q, v) = p.horner(from_const(78));
1264 assert_eq!(q.len(), 3);
1265 assert_eq!(q.degree_bound(), 3);
1266 assert_ne!(v, from_const(0));
1267 let (q, v) = p.horner(from_const(90));
1268 assert_eq!(q.len(), 3);
1269 assert_eq!(q.degree_bound(), 3);
1270 assert_ne!(v, from_const(0));
1271 }
1272
1273 #[test]
1274 fn test_seven_roots() {
1275 let p = from_roots(&[
1276 from_const(12),
1277 from_const(34),
1278 from_const(56),
1279 from_const(78),
1280 from_const(90),
1281 from_const(13),
1282 from_const(57),
1283 ]);
1284 assert_eq!(p.len(), 8);
1285 assert_eq!(p.degree_bound(), 8);
1286 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1287 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1288 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1289 assert_eq!(p.evaluate(from_const(78)), from_const(0));
1290 assert_eq!(p.evaluate(from_const(90)), from_const(0));
1291 assert_eq!(p.evaluate(from_const(13)), from_const(0));
1292 assert_eq!(p.evaluate(from_const(57)), from_const(0));
1293 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1294 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1295 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1296 }
1297
1298 #[test]
1299 fn test_seven_roots_reverse_order() {
1300 let p = from_roots(&[
1301 from_const(57),
1302 from_const(13),
1303 from_const(90),
1304 from_const(78),
1305 from_const(56),
1306 from_const(34),
1307 from_const(12),
1308 ]);
1309 assert_eq!(p.len(), 8);
1310 assert_eq!(p.degree_bound(), 8);
1311 assert_eq!(p.evaluate(from_const(12)), from_const(0));
1312 assert_eq!(p.evaluate(from_const(34)), from_const(0));
1313 assert_eq!(p.evaluate(from_const(56)), from_const(0));
1314 assert_eq!(p.evaluate(from_const(78)), from_const(0));
1315 assert_eq!(p.evaluate(from_const(90)), from_const(0));
1316 assert_eq!(p.evaluate(from_const(13)), from_const(0));
1317 assert_eq!(p.evaluate(from_const(57)), from_const(0));
1318 assert_ne!(p.evaluate(from_const(92)), from_const(0));
1319 assert_ne!(p.evaluate(from_const(46)), from_const(0));
1320 assert_ne!(p.evaluate(from_const(80)), from_const(0));
1321 }
1322
1323 #[test]
1324 fn test_duplicate_roots() {
1325 assert!(
1326 Polynomial::from_roots(
1327 &[
1328 from_const(12),
1329 from_const(34),
1330 from_const(56),
1331 from_const(12),
1332 from_const(90),
1333 from_const(12),
1334 from_const(57),
1335 ],
1336 get_random_scalar()
1337 )
1338 .is_err()
1339 );
1340 }
1341
1342 #[test]
1343 fn test_interpolate_zero_points() {
1344 let p = Polynomial::interpolate(&[]).unwrap();
1345 assert_eq!(p, Polynomial::default());
1346 }
1347
1348 #[test]
1349 fn test_interpolate_one_point1() {
1350 let p = Polynomial::interpolate(&[(from_const(12), from_const(34))]).unwrap();
1351 assert_eq!(p.len(), 1);
1352 assert_eq!(p.degree_bound(), 1);
1353 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1354 }
1355
1356 #[test]
1357 fn test_interpolate_one_point2() {
1358 let p = Polynomial::interpolate(&[(from_const(34), from_const(56))]).unwrap();
1359 assert_eq!(p.len(), 1);
1360 assert_eq!(p.degree_bound(), 1);
1361 assert_eq!(p.evaluate(from_const(34)), from_const(56));
1362 }
1363
1364 #[test]
1365 fn test_interpolate_two_points1() {
1366 let p = Polynomial::interpolate(&[
1367 (from_const(12), from_const(34)),
1368 (from_const(56), from_const(78)),
1369 ])
1370 .unwrap();
1371 assert_eq!(p.len(), 2);
1372 assert_eq!(p.degree_bound(), 2);
1373 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1374 assert_eq!(p.evaluate(from_const(56)), from_const(78));
1375 }
1376
1377 #[test]
1378 fn test_interpolate_two_points2() {
1379 let p = Polynomial::interpolate(&[
1380 (from_const(34), from_const(12)),
1381 (from_const(78), from_const(56)),
1382 ])
1383 .unwrap();
1384 assert_eq!(p.len(), 2);
1385 assert_eq!(p.degree_bound(), 2);
1386 assert_eq!(p.evaluate(from_const(34)), from_const(12));
1387 assert_eq!(p.evaluate(from_const(78)), from_const(56));
1388 }
1389
1390 #[test]
1391 fn test_interpolate_three_points1() {
1392 let p = Polynomial::interpolate(&[
1393 (from_const(12), from_const(34)),
1394 (from_const(56), from_const(78)),
1395 (from_const(90), from_const(12)),
1396 ])
1397 .unwrap();
1398 assert_eq!(p.len(), 3);
1399 assert_eq!(p.degree_bound(), 3);
1400 assert_eq!(p.evaluate(from_const(12)), from_const(34));
1401 assert_eq!(p.evaluate(from_const(56)), from_const(78));
1402 assert_eq!(p.evaluate(from_const(90)), from_const(12));
1403 }
1404
1405 #[test]
1406 fn test_interpolate_three_points2() {
1407 let p = Polynomial::interpolate(&[
1408 (from_const(34), from_const(12)),
1409 (from_const(78), from_const(56)),
1410 (from_const(12), from_const(90)),
1411 ])
1412 .unwrap();
1413 assert_eq!(p.len(), 3);
1414 assert_eq!(p.degree_bound(), 3);
1415 assert_eq!(p.evaluate(from_const(34)), from_const(12));
1416 assert_eq!(p.evaluate(from_const(78)), from_const(56));
1417 assert_eq!(p.evaluate(from_const(12)), from_const(90));
1418 }
1419
1420 #[test]
1421 fn test_duplicate_coordinates() {
1422 assert!(
1423 Polynomial::interpolate(&[
1424 (from_const(12), from_const(34)),
1425 (from_const(56), from_const(78)),
1426 (from_const(12), from_const(90)),
1427 ])
1428 .is_err()
1429 );
1430 }
1431
1432 #[test]
1433 fn test_encode2_one_value_1() {
1434 let p1 = Polynomial::encode2(vec![from_const(42)]);
1435 let p2 = Polynomial::encode2(vec![from_const(42)]);
1436 assert_eq!(p1, p2);
1437 assert_eq!(p1.len(), 1);
1438 assert_eq!(p1.degree_bound(), 1);
1439 assert_eq!(p2.len(), 1);
1440 assert_eq!(p2.degree_bound(), 1);
1441 assert_eq!(
1442 p1.evaluate(Polynomial::domain_element2(0, 1)),
1443 from_const(42)
1444 );
1445 assert_eq!(p1.evaluate_on_two_adic_domain(0, 1), from_const(42));
1446 assert_eq!(
1447 p2.evaluate(Polynomial::domain_element2(0, 1)),
1448 from_const(42)
1449 );
1450 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), from_const(42));
1451 }
1452
1453 #[test]
1454 fn test_encode2_one_value_2() {
1455 let p1 = Polynomial::encode2(vec![from_const(42)]);
1456 let p2 = Polynomial::encode2(vec![from_const(123)]);
1457 assert_eq!(p2.len(), 1);
1458 assert_eq!(p2.degree_bound(), 1);
1459 assert_ne!(p1, p2);
1460 assert_eq!(
1461 p2.evaluate(Polynomial::domain_element2(0, 1)),
1462 from_const(123)
1463 );
1464 assert_eq!(p2.evaluate_on_two_adic_domain(0, 1), from_const(123));
1465 }
1466
1467 #[test]
1468 fn test_encode2_two_values_1() {
1469 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1470 let p2 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1471 assert_eq!(p1, p2);
1472 assert_eq!(p1.len(), 2);
1473 assert_eq!(p1.degree_bound(), 2);
1474 assert_eq!(p2.len(), 2);
1475 assert_eq!(p2.degree_bound(), 2);
1476 assert_eq!(
1477 p1.evaluate(Polynomial::domain_element2(0, 2)),
1478 from_const(12)
1479 );
1480 assert_eq!(p1.evaluate_on_two_adic_domain(0, 2), from_const(12));
1481 assert_eq!(
1482 p1.evaluate(Polynomial::domain_element2(1, 2)),
1483 from_const(34)
1484 );
1485 assert_eq!(p1.evaluate_on_two_adic_domain(1, 2), from_const(34));
1486 assert_eq!(
1487 p2.evaluate(Polynomial::domain_element2(0, 2)),
1488 from_const(12)
1489 );
1490 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), from_const(12));
1491 assert_eq!(
1492 p2.evaluate(Polynomial::domain_element2(1, 2)),
1493 from_const(34)
1494 );
1495 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), from_const(34));
1496 }
1497
1498 #[test]
1499 fn test_encode2_two_values_2() {
1500 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34)]);
1501 let p2 = Polynomial::encode2(vec![from_const(78), from_const(56)]);
1502 assert_eq!(p1.len(), 2);
1503 assert_eq!(p1.degree_bound(), 2);
1504 assert_eq!(p2.len(), 2);
1505 assert_eq!(p2.degree_bound(), 2);
1506 assert_ne!(p1, p2);
1507 assert_eq!(
1508 p2.evaluate(Polynomial::domain_element2(0, 2)),
1509 from_const(78)
1510 );
1511 assert_eq!(p2.evaluate_on_two_adic_domain(0, 2), from_const(78));
1512 assert_eq!(
1513 p2.evaluate(Polynomial::domain_element2(1, 2)),
1514 from_const(56)
1515 );
1516 assert_eq!(p2.evaluate_on_two_adic_domain(1, 2), from_const(56));
1517 }
1518
1519 #[test]
1520 fn test_encode2_three_values_1() {
1521 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1522 let p2 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1523 assert_eq!(p1, p2);
1524 assert_eq!(p1.len(), 4);
1525 assert_eq!(p1.degree_bound(), 4);
1526 assert_eq!(p2.len(), 4);
1527 assert_eq!(p2.degree_bound(), 4);
1528 assert_eq!(
1529 p1.evaluate(Polynomial::domain_element2(0, 3)),
1530 from_const(12)
1531 );
1532 assert_eq!(p1.evaluate_on_two_adic_domain(0, 3), from_const(12));
1533 assert_eq!(
1534 p1.evaluate(Polynomial::domain_element2(0, 4)),
1535 from_const(12)
1536 );
1537 assert_eq!(p1.evaluate_on_two_adic_domain(0, 4), from_const(12));
1538 assert_eq!(
1539 p1.evaluate(Polynomial::domain_element2(1, 3)),
1540 from_const(34)
1541 );
1542 assert_eq!(p1.evaluate_on_two_adic_domain(1, 3), from_const(34));
1543 assert_eq!(
1544 p1.evaluate(Polynomial::domain_element2(1, 4)),
1545 from_const(34)
1546 );
1547 assert_eq!(p1.evaluate_on_two_adic_domain(1, 4), from_const(34));
1548 assert_eq!(
1549 p1.evaluate(Polynomial::domain_element2(2, 3)),
1550 from_const(56)
1551 );
1552 assert_eq!(p1.evaluate_on_two_adic_domain(2, 3), from_const(56));
1553 assert_eq!(
1554 p1.evaluate(Polynomial::domain_element2(2, 4)),
1555 from_const(56)
1556 );
1557 assert_eq!(p1.evaluate_on_two_adic_domain(2, 4), from_const(56));
1558 assert_eq!(
1559 p1.evaluate(Polynomial::domain_element2(3, 4)),
1560 from_const(0)
1561 );
1562 assert_eq!(p1.evaluate_on_two_adic_domain(3, 4), from_const(0));
1563 assert_eq!(
1564 p2.evaluate(Polynomial::domain_element2(0, 3)),
1565 from_const(12)
1566 );
1567 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), from_const(12));
1568 assert_eq!(
1569 p2.evaluate(Polynomial::domain_element2(0, 4)),
1570 from_const(12)
1571 );
1572 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), from_const(12));
1573 assert_eq!(
1574 p2.evaluate(Polynomial::domain_element2(1, 3)),
1575 from_const(34)
1576 );
1577 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), from_const(34));
1578 assert_eq!(
1579 p2.evaluate(Polynomial::domain_element2(1, 4)),
1580 from_const(34)
1581 );
1582 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), from_const(34));
1583 assert_eq!(
1584 p2.evaluate(Polynomial::domain_element2(2, 3)),
1585 from_const(56)
1586 );
1587 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), from_const(56));
1588 assert_eq!(
1589 p2.evaluate(Polynomial::domain_element2(2, 4)),
1590 from_const(56)
1591 );
1592 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), from_const(56));
1593 assert_eq!(
1594 p2.evaluate(Polynomial::domain_element2(3, 4)),
1595 from_const(0)
1596 );
1597 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), from_const(0));
1598 }
1599
1600 #[test]
1601 fn test_encode2_three_values_2() {
1602 let p1 = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1603 let p2 = Polynomial::encode2(vec![from_const(90), from_const(78), from_const(34)]);
1604 assert_eq!(p1.len(), 4);
1605 assert_eq!(p1.degree_bound(), 4);
1606 assert_eq!(p2.len(), 4);
1607 assert_eq!(p2.degree_bound(), 4);
1608 assert_ne!(p1, p2);
1609 assert_eq!(
1610 p2.evaluate(Polynomial::domain_element2(0, 3)),
1611 from_const(90)
1612 );
1613 assert_eq!(p2.evaluate_on_two_adic_domain(0, 3), from_const(90));
1614 assert_eq!(
1615 p2.evaluate(Polynomial::domain_element2(0, 4)),
1616 from_const(90)
1617 );
1618 assert_eq!(p2.evaluate_on_two_adic_domain(0, 4), from_const(90));
1619 assert_eq!(
1620 p2.evaluate(Polynomial::domain_element2(1, 3)),
1621 from_const(78)
1622 );
1623 assert_eq!(p2.evaluate_on_two_adic_domain(1, 3), from_const(78));
1624 assert_eq!(
1625 p2.evaluate(Polynomial::domain_element2(1, 4)),
1626 from_const(78)
1627 );
1628 assert_eq!(p2.evaluate_on_two_adic_domain(1, 4), from_const(78));
1629 assert_eq!(
1630 p2.evaluate(Polynomial::domain_element2(2, 3)),
1631 from_const(34)
1632 );
1633 assert_eq!(p2.evaluate_on_two_adic_domain(2, 3), from_const(34));
1634 assert_eq!(
1635 p2.evaluate(Polynomial::domain_element2(2, 4)),
1636 from_const(34)
1637 );
1638 assert_eq!(p2.evaluate_on_two_adic_domain(2, 4), from_const(34));
1639 assert_eq!(
1640 p2.evaluate(Polynomial::domain_element2(3, 4)),
1641 from_const(0)
1642 );
1643 assert_eq!(p2.evaluate_on_two_adic_domain(3, 4), from_const(0));
1644 }
1645
1646 #[test]
1647 fn test_encode2_four_values() {
1648 let p = Polynomial::encode2(vec![
1649 from_const(12),
1650 from_const(34),
1651 from_const(56),
1652 from_const(78),
1653 ]);
1654 assert_eq!(p.len(), 4);
1655 assert_eq!(p.degree_bound(), 4);
1656 assert_eq!(
1657 p.evaluate(Polynomial::domain_element2(0, 4)),
1658 from_const(12)
1659 );
1660 assert_eq!(p.evaluate_on_two_adic_domain(0, 4), from_const(12));
1661 assert_eq!(
1662 p.evaluate(Polynomial::domain_element2(1, 4)),
1663 from_const(34)
1664 );
1665 assert_eq!(p.evaluate_on_two_adic_domain(1, 4), from_const(34));
1666 assert_eq!(
1667 p.evaluate(Polynomial::domain_element2(2, 4)),
1668 from_const(56)
1669 );
1670 assert_eq!(p.evaluate_on_two_adic_domain(2, 4), from_const(56));
1671 assert_eq!(
1672 p.evaluate(Polynomial::domain_element2(3, 4)),
1673 from_const(78)
1674 );
1675 assert_eq!(p.evaluate_on_two_adic_domain(3, 4), from_const(78));
1676 }
1677
1678 #[test]
1679 fn test_decode2_one_value() {
1680 let values = vec![from_const(42)];
1681 let polynomial = Polynomial::encode2(values.clone());
1682 assert_eq!(polynomial.decode2(), values);
1683 }
1684
1685 #[test]
1686 fn test_decode2_two_values() {
1687 let values = vec![from_const(12), from_const(34)];
1688 let polynomial = Polynomial::encode2(values.clone());
1689 assert_eq!(polynomial.decode2(), values);
1690 }
1691
1692 #[test]
1693 fn test_decode2_three_values() {
1694 let polynomial = Polynomial::encode2(vec![from_const(12), from_const(34), from_const(56)]);
1695 assert_eq!(
1696 polynomial.decode2(),
1697 vec![
1698 from_const(12),
1699 from_const(34),
1700 from_const(56),
1701 from_const(0)
1702 ]
1703 );
1704 }
1705
1706 #[test]
1707 fn test_decode2_four_values() {
1708 let values = vec![
1709 from_const(12),
1710 from_const(34),
1711 from_const(56),
1712 from_const(78),
1713 ];
1714 let polynomial = Polynomial::encode2(values.clone());
1715 assert_eq!(polynomial.decode2(), values);
1716 }
1717
1718 #[test]
1719 fn test_encode3_one_value_1() {
1720 let p1 = Polynomial::encode3(vec![from_const(42)]);
1721 let p2 = Polynomial::encode3(vec![from_const(42)]);
1722 assert_eq!(p1, p2);
1723 assert_eq!(p1.len(), 1);
1724 assert_eq!(p1.degree_bound(), 1);
1725 assert_eq!(p2.len(), 1);
1726 assert_eq!(p2.degree_bound(), 1);
1727 assert_eq!(
1728 p1.evaluate(Polynomial::domain_element3(0, 1)),
1729 from_const(42)
1730 );
1731 assert_eq!(p1.evaluate_on_three_adic_domain(0, 1), from_const(42));
1732 assert_eq!(
1733 p2.evaluate(Polynomial::domain_element3(0, 1)),
1734 from_const(42)
1735 );
1736 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), from_const(42));
1737 }
1738
1739 #[test]
1740 fn test_encode3_one_value_2() {
1741 let p1 = Polynomial::encode3(vec![from_const(42)]);
1742 let p2 = Polynomial::encode3(vec![from_const(123)]);
1743 assert_eq!(p2.len(), 1);
1744 assert_eq!(p2.degree_bound(), 1);
1745 assert_ne!(p1, p2);
1746 assert_eq!(
1747 p2.evaluate(Polynomial::domain_element3(0, 1)),
1748 from_const(123)
1749 );
1750 assert_eq!(p2.evaluate_on_three_adic_domain(0, 1), from_const(123));
1751 }
1752
1753 #[test]
1754 fn test_encode3_two_values_1() {
1755 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1756 let p2 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1757 assert_eq!(p1, p2);
1758 assert_eq!(p1.len(), 3);
1759 assert_eq!(p1.degree_bound(), 3);
1760 assert_eq!(p2.len(), 3);
1761 assert_eq!(p2.degree_bound(), 3);
1762 assert_eq!(
1763 p1.evaluate(Polynomial::domain_element3(0, 2)),
1764 from_const(12)
1765 );
1766 assert_eq!(p1.evaluate_on_three_adic_domain(0, 2), from_const(12));
1767 assert_eq!(
1768 p1.evaluate(Polynomial::domain_element3(0, 3)),
1769 from_const(12)
1770 );
1771 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), from_const(12));
1772 assert_eq!(
1773 p1.evaluate(Polynomial::domain_element3(1, 2)),
1774 from_const(34)
1775 );
1776 assert_eq!(p1.evaluate_on_three_adic_domain(1, 2), from_const(34));
1777 assert_eq!(
1778 p1.evaluate(Polynomial::domain_element3(1, 3)),
1779 from_const(34)
1780 );
1781 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), from_const(34));
1782 assert_eq!(
1783 p1.evaluate(Polynomial::domain_element3(2, 3)),
1784 from_const(0)
1785 );
1786 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), from_const(0));
1787 assert_eq!(
1788 p2.evaluate(Polynomial::domain_element3(0, 2)),
1789 from_const(12)
1790 );
1791 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), from_const(12));
1792 assert_eq!(
1793 p2.evaluate(Polynomial::domain_element3(0, 3)),
1794 from_const(12)
1795 );
1796 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(12));
1797 assert_eq!(
1798 p2.evaluate(Polynomial::domain_element3(1, 2)),
1799 from_const(34)
1800 );
1801 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), from_const(34));
1802 assert_eq!(
1803 p2.evaluate(Polynomial::domain_element3(1, 3)),
1804 from_const(34)
1805 );
1806 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(34));
1807 assert_eq!(
1808 p2.evaluate(Polynomial::domain_element3(2, 3)),
1809 from_const(0)
1810 );
1811 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(0));
1812 }
1813
1814 #[test]
1815 fn test_encode3_two_values_2() {
1816 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34)]);
1817 let p2 = Polynomial::encode3(vec![from_const(78), from_const(56)]);
1818 assert_eq!(p1.len(), 3);
1819 assert_eq!(p1.degree_bound(), 3);
1820 assert_eq!(p2.len(), 3);
1821 assert_eq!(p2.degree_bound(), 3);
1822 assert_ne!(p1, p2);
1823 assert_eq!(
1824 p2.evaluate(Polynomial::domain_element3(0, 2)),
1825 from_const(78)
1826 );
1827 assert_eq!(p2.evaluate_on_three_adic_domain(0, 2), from_const(78));
1828 assert_eq!(
1829 p2.evaluate(Polynomial::domain_element3(1, 2)),
1830 from_const(56)
1831 );
1832 assert_eq!(p2.evaluate_on_three_adic_domain(1, 2), from_const(56));
1833 assert_eq!(
1834 p2.evaluate(Polynomial::domain_element3(2, 3)),
1835 from_const(0)
1836 );
1837 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(0));
1838 }
1839
1840 #[test]
1841 fn test_encode3_three_values_1() {
1842 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1843 let p2 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1844 assert_eq!(p1, p2);
1845 assert_eq!(p1.len(), 3);
1846 assert_eq!(p1.degree_bound(), 3);
1847 assert_eq!(p2.len(), 3);
1848 assert_eq!(p2.degree_bound(), 3);
1849 assert_eq!(
1850 p1.evaluate(Polynomial::domain_element3(0, 3)),
1851 from_const(12)
1852 );
1853 assert_eq!(p1.evaluate_on_three_adic_domain(0, 3), from_const(12));
1854 assert_eq!(
1855 p1.evaluate(Polynomial::domain_element3(1, 3)),
1856 from_const(34)
1857 );
1858 assert_eq!(p1.evaluate_on_three_adic_domain(1, 3), from_const(34));
1859 assert_eq!(
1860 p1.evaluate(Polynomial::domain_element3(2, 3)),
1861 from_const(56)
1862 );
1863 assert_eq!(p1.evaluate_on_three_adic_domain(2, 3), from_const(56));
1864 assert_eq!(
1865 p2.evaluate(Polynomial::domain_element3(0, 3)),
1866 from_const(12)
1867 );
1868 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(12));
1869 assert_eq!(
1870 p2.evaluate(Polynomial::domain_element3(1, 3)),
1871 from_const(34)
1872 );
1873 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(34));
1874 assert_eq!(
1875 p2.evaluate(Polynomial::domain_element3(2, 3)),
1876 from_const(56)
1877 );
1878 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(56));
1879 }
1880
1881 #[test]
1882 fn test_encode3_three_values_2() {
1883 let p1 = Polynomial::encode3(vec![from_const(12), from_const(34), from_const(56)]);
1884 let p2 = Polynomial::encode3(vec![from_const(90), from_const(78), from_const(34)]);
1885 assert_eq!(p1.len(), 3);
1886 assert_eq!(p1.degree_bound(), 3);
1887 assert_eq!(p2.len(), 3);
1888 assert_eq!(p2.degree_bound(), 3);
1889 assert_ne!(p1, p2);
1890 assert_eq!(
1891 p2.evaluate(Polynomial::domain_element3(0, 3)),
1892 from_const(90)
1893 );
1894 assert_eq!(p2.evaluate_on_three_adic_domain(0, 3), from_const(90));
1895 assert_eq!(
1896 p2.evaluate(Polynomial::domain_element3(1, 3)),
1897 from_const(78)
1898 );
1899 assert_eq!(p2.evaluate_on_three_adic_domain(1, 3), from_const(78));
1900 assert_eq!(
1901 p2.evaluate(Polynomial::domain_element3(2, 3)),
1902 from_const(34)
1903 );
1904 assert_eq!(p2.evaluate_on_three_adic_domain(2, 3), from_const(34));
1905 }
1906
1907 #[test]
1908 fn test_encode3_nine_values3() {
1909 let p = Polynomial::encode3(vec![
1910 from_const(12),
1911 from_const(34),
1912 from_const(56),
1913 from_const(78),
1914 from_const(90),
1915 from_const(11),
1916 from_const(22),
1917 from_const(33),
1918 from_const(44),
1919 ]);
1920 assert_eq!(p.len(), 9);
1921 assert_eq!(p.degree_bound(), 9);
1922 assert_eq!(
1923 p.evaluate(Polynomial::domain_element3(0, 9)),
1924 from_const(12)
1925 );
1926 assert_eq!(p.evaluate_on_three_adic_domain(0, 9), from_const(12));
1927 assert_eq!(
1928 p.evaluate(Polynomial::domain_element3(1, 9)),
1929 from_const(34)
1930 );
1931 assert_eq!(p.evaluate_on_three_adic_domain(1, 9), from_const(34));
1932 assert_eq!(
1933 p.evaluate(Polynomial::domain_element3(2, 9)),
1934 from_const(56)
1935 );
1936 assert_eq!(p.evaluate_on_three_adic_domain(2, 9), from_const(56));
1937 assert_eq!(
1938 p.evaluate(Polynomial::domain_element3(3, 9)),
1939 from_const(78)
1940 );
1941 assert_eq!(p.evaluate_on_three_adic_domain(3, 9), from_const(78));
1942 assert_eq!(
1943 p.evaluate(Polynomial::domain_element3(4, 9)),
1944 from_const(90)
1945 );
1946 assert_eq!(p.evaluate_on_three_adic_domain(4, 9), from_const(90));
1947 assert_eq!(
1948 p.evaluate(Polynomial::domain_element3(5, 9)),
1949 from_const(11)
1950 );
1951 assert_eq!(p.evaluate_on_three_adic_domain(5, 9), from_const(11));
1952 assert_eq!(
1953 p.evaluate(Polynomial::domain_element3(6, 9)),
1954 from_const(22)
1955 );
1956 assert_eq!(p.evaluate_on_three_adic_domain(6, 9), from_const(22));
1957 assert_eq!(
1958 p.evaluate(Polynomial::domain_element3(7, 9)),
1959 from_const(33)
1960 );
1961 assert_eq!(p.evaluate_on_three_adic_domain(7, 9), from_const(33));
1962 assert_eq!(
1963 p.evaluate(Polynomial::domain_element3(8, 9)),
1964 from_const(44)
1965 );
1966 assert_eq!(p.evaluate_on_three_adic_domain(8, 9), from_const(44));
1967 }
1968
1969 #[test]
1970 fn test_decode3_one_value() {
1971 let values = vec![from_const(42)];
1972 let polynomial = Polynomial::encode3(values.clone());
1973 assert_eq!(polynomial.decode3(), values);
1974 }
1975
1976 #[test]
1977 fn test_decode3_two_values() {
1978 let values = vec![from_const(12), from_const(34)];
1979 let polynomial = Polynomial::encode3(values.clone());
1980 assert_eq!(
1981 polynomial.decode3(),
1982 vec![from_const(12), from_const(34), from_const(0)]
1983 );
1984 }
1985
1986 #[test]
1987 fn test_decode3_three_values() {
1988 let values = vec![from_const(12), from_const(34), from_const(56)];
1989 let polynomial = Polynomial::encode3(values.clone());
1990 assert_eq!(polynomial.decode3(), values);
1991 }
1992
1993 #[test]
1994 fn test_decode3_nine_values() {
1995 let values = vec![
1996 from_const(12),
1997 from_const(34),
1998 from_const(56),
1999 from_const(78),
2000 from_const(90),
2001 from_const(11),
2002 from_const(22),
2003 from_const(33),
2004 from_const(44),
2005 ];
2006 let polynomial = Polynomial::encode3(values.clone());
2007 assert_eq!(polynomial.decode3(), values);
2008 }
2009
2010 #[test]
2011 fn test_add_same_length() {
2012 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2013 let p2 =
2014 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2015 assert_eq!(
2016 p1 + p2,
2017 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2018 );
2019 }
2020
2021 #[test]
2022 fn test_add_lhs_longer() {
2023 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2024 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2025 assert_eq!(
2026 p1 + p2,
2027 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2028 );
2029 }
2030
2031 #[test]
2032 fn test_add_rhs_longer() {
2033 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2034 let p2 =
2035 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2036 assert_eq!(
2037 p1 + p2,
2038 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2039 );
2040 }
2041
2042 #[test]
2043 fn test_add_commutative() {
2044 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2045 let p2 =
2046 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2047 assert_eq!(p1.clone() + p2.clone(), p2 + p1);
2048 }
2049
2050 #[test]
2051 fn test_add_assign_same_length() {
2052 let mut p1 =
2053 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2054 let p2 =
2055 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2056 p1 += p2;
2057 assert_eq!(
2058 p1,
2059 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(33)])
2060 );
2061 }
2062
2063 #[test]
2064 fn test_add_assign_lhs_longer() {
2065 let mut p1 =
2066 Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2067 let p2 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2068 p1 += p2;
2069 assert_eq!(
2070 p1,
2071 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(3)])
2072 );
2073 }
2074
2075 #[test]
2076 fn test_add_assign_rhs_longer() {
2077 let mut p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2078 let p2 =
2079 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2080 p1 += p2;
2081 assert_eq!(
2082 p1,
2083 Polynomial::with_coefficients(vec![from_const(11), from_const(22), from_const(30)])
2084 );
2085 }
2086
2087 #[test]
2088 fn test_add_assign_consistent_with_add() {
2089 let p1 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2090 let p2 =
2091 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2092 let mut p1_assign = p1.clone();
2093 p1_assign += p2.clone();
2094 assert_eq!(p1_assign, p1 + p2);
2095 }
2096
2097 #[test]
2098 fn test_sub_same_length() {
2099 let p1 =
2100 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2101 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2102 assert_eq!(
2103 p1 - p2,
2104 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2105 );
2106 }
2107
2108 #[test]
2109 fn test_sub_lhs_longer() {
2110 let p1 =
2111 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2112 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2113 assert_eq!(
2114 p1 - p2,
2115 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2116 );
2117 }
2118
2119 #[test]
2120 fn test_sub_rhs_longer() {
2121 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2122 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2123 assert_eq!(
2124 p1 - p2,
2125 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2126 );
2127 }
2128
2129 #[test]
2130 fn test_sub_anticommutative() {
2131 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2132 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2133 assert_eq!(p1.clone() - p2.clone(), -(p2 - p1));
2134 }
2135
2136 #[test]
2137 fn test_sub_assign_same_length() {
2138 let mut p1 =
2139 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2140 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2141 p1 -= p2;
2142 assert_eq!(
2143 p1,
2144 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(27)])
2145 );
2146 }
2147
2148 #[test]
2149 fn test_sub_assign_lhs_longer() {
2150 let mut p1 =
2151 Polynomial::with_coefficients(vec![from_const(10), from_const(20), from_const(30)]);
2152 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2153 p1 -= p2;
2154 assert_eq!(
2155 p1,
2156 Polynomial::with_coefficients(vec![from_const(9), from_const(18), from_const(30)])
2157 );
2158 }
2159
2160 #[test]
2161 fn test_sub_assign_rhs_longer() {
2162 let mut p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2163 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2164 p1 -= p2;
2165 assert_eq!(
2166 p1,
2167 Polynomial::with_coefficients(vec![from_const(9), from_const(18), -from_const(3)])
2168 );
2169 }
2170
2171 #[test]
2172 fn test_sub_assign_consistent_with_sub() {
2173 let p1 = Polynomial::with_coefficients(vec![from_const(10), from_const(20)]);
2174 let p2 = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2175 let mut p1_assign = p1.clone();
2176 p1_assign -= p2.clone();
2177 assert_eq!(p1_assign, p1 - p2);
2178 }
2179
2180 #[test]
2181 fn test_multiply_empty() {
2182 let p1 = Polynomial::default();
2183 let p2 = Polynomial::default();
2184 assert_eq!(p1.multiply(p2), Polynomial::default());
2185 }
2186
2187 #[test]
2188 fn test_multiply_empty_by_non_empty() {
2189 let p1 = Polynomial::default();
2190 let p2 = Polynomial {
2191 coefficients: vec![from_const(12), from_const(34)],
2192 };
2193 assert_eq!(p1.multiply(p2), Polynomial::default());
2194 }
2195
2196 #[test]
2197 fn test_multiply_non_empty_by_empty() {
2198 let p1 = Polynomial {
2199 coefficients: vec![from_const(56), from_const(78)],
2200 };
2201 let p2 = Polynomial::default();
2202 assert_eq!(p1.multiply(p2), Polynomial::default());
2203 }
2204
2205 #[test]
2206 fn test_multiply_constant() {
2207 let p1 = Polynomial {
2208 coefficients: vec![from_const(3)],
2209 };
2210 let p2 = Polynomial {
2211 coefficients: vec![from_const(12), from_const(34), from_const(56)],
2212 };
2213 assert_eq!(
2214 p1.multiply(p2),
2215 Polynomial {
2216 coefficients: vec![from_const(36), from_const(102), from_const(168)]
2217 }
2218 );
2219 }
2220
2221 #[test]
2222 fn test_multiply_by_constant() {
2223 let p1 = Polynomial {
2224 coefficients: vec![from_const(12), from_const(34), from_const(56)],
2225 };
2226 let p2 = Polynomial {
2227 coefficients: vec![from_const(3)],
2228 };
2229 assert_eq!(
2230 p1.multiply(p2),
2231 Polynomial {
2232 coefficients: vec![from_const(36), from_const(102), from_const(168)]
2233 }
2234 );
2235 }
2236
2237 #[test]
2238 fn test_multiply_constant_by_constant() {
2239 let p1 = Polynomial {
2240 coefficients: vec![from_const(12)],
2241 };
2242 let p2 = Polynomial {
2243 coefficients: vec![from_const(34)],
2244 };
2245 assert_eq!(
2246 p1.multiply(p2),
2247 Polynomial {
2248 coefficients: vec![from_const(408)]
2249 }
2250 );
2251 }
2252
2253 #[test]
2254 fn test_multiply_polynomials1() {
2255 let p1 = Polynomial {
2256 coefficients: vec![from_const(1), from_const(2)],
2257 };
2258 let p2 = Polynomial {
2259 coefficients: vec![from_const(3), from_const(4)],
2260 };
2261 let result = Polynomial {
2262 coefficients: vec![from_const(3), from_const(10), from_const(8)],
2263 };
2264 assert_eq!(p1.clone().multiply(p2.clone()), result);
2265 assert_eq!(p2.multiply(p1), result);
2266 }
2267
2268 #[test]
2269 fn test_multiply_polynomials2() {
2270 let p1 = Polynomial {
2271 coefficients: vec![from_const(1), from_const(2)],
2272 };
2273 let p2 = Polynomial {
2274 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2275 };
2276 let result = Polynomial {
2277 coefficients: vec![
2278 from_const(3),
2279 from_const(10),
2280 from_const(13),
2281 from_const(10),
2282 ],
2283 };
2284 assert_eq!(p1.clone().multiply(p2.clone()), result);
2285 assert_eq!(p2.multiply(p1), result);
2286 }
2287
2288 #[test]
2289 fn test_polynomial_mul_op() {
2290 let p1 = Polynomial {
2291 coefficients: vec![from_const(1), from_const(2)],
2292 };
2293 let p2 = Polynomial {
2294 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2295 };
2296 let result = Polynomial {
2297 coefficients: vec![
2298 from_const(3),
2299 from_const(10),
2300 from_const(13),
2301 from_const(10),
2302 ],
2303 };
2304 assert_eq!(p1.clone() * p2.clone(), result);
2305 assert_eq!(p2 * p1, result);
2306 }
2307
2308 #[test]
2309 fn test_polynomial_mul_assign() {
2310 let mut p1 = Polynomial {
2311 coefficients: vec![from_const(1), from_const(2)],
2312 };
2313 let p2 = Polynomial {
2314 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2315 };
2316 p1 *= p2;
2317 assert_eq!(
2318 p1,
2319 Polynomial {
2320 coefficients: vec![
2321 from_const(3),
2322 from_const(10),
2323 from_const(13),
2324 from_const(10)
2325 ],
2326 }
2327 );
2328 }
2329
2330 #[test]
2331 fn test_multiply_one_polynomial() {
2332 let p = Polynomial {
2333 coefficients: vec![from_const(12), from_const(34)],
2334 };
2335 assert_eq!(Polynomial::multiply_many([p.clone()]), p);
2336 }
2337
2338 #[test]
2339 fn test_multiply_two_polynomials() {
2340 let p1 = Polynomial {
2341 coefficients: vec![from_const(1), from_const(2)],
2342 };
2343 let p2 = Polynomial {
2344 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2345 };
2346 let result = Polynomial {
2347 coefficients: vec![
2348 from_const(3),
2349 from_const(10),
2350 from_const(13),
2351 from_const(10),
2352 ],
2353 };
2354 assert_eq!(Polynomial::multiply_many([p1.clone(), p2.clone()]), result);
2355 assert_eq!(Polynomial::multiply_many([p2, p1]), result);
2356 }
2357
2358 #[test]
2359 fn test_multiply_three_polynomials() {
2360 let p1 = Polynomial {
2361 coefficients: vec![from_const(1), from_const(2)],
2362 };
2363 let p2 = Polynomial {
2364 coefficients: vec![from_const(3), from_const(4), from_const(5)],
2365 };
2366 let p3 = Polynomial {
2367 coefficients: vec![from_const(6), from_const(7), from_const(8), from_const(9)],
2368 };
2369 let result = Polynomial {
2370 coefficients: vec![
2371 from_const(18),
2372 from_const(81),
2373 from_const(172),
2374 from_const(258),
2375 from_const(264),
2376 from_const(197),
2377 from_const(90),
2378 ],
2379 };
2380 assert_eq!(
2381 Polynomial::multiply_many([p1.clone(), p2.clone(), p3.clone()]),
2382 result
2383 );
2384 assert_eq!(
2385 Polynomial::multiply_many([p1.clone(), p3.clone(), p2.clone()]),
2386 result
2387 );
2388 assert_eq!(
2389 Polynomial::multiply_many([p2.clone(), p1.clone(), p3.clone()]),
2390 result
2391 );
2392 assert_eq!(
2393 Polynomial::multiply_many([p2.clone(), p3.clone(), p1.clone()]),
2394 result
2395 );
2396 assert_eq!(
2397 Polynomial::multiply_many([p3.clone(), p1.clone(), p2.clone()]),
2398 result
2399 );
2400 assert_eq!(
2401 Polynomial::multiply_many([p3.clone(), p2.clone(), p1.clone()]),
2402 result
2403 );
2404 }
2405
2406 #[test]
2407 fn test_multiply_four_polynomials() {
2408 let p1 = Polynomial {
2409 coefficients: vec![from_const(1), from_const(2)],
2410 };
2411 let p2 = Polynomial {
2412 coefficients: vec![from_const(3), from_const(4)],
2413 };
2414 let p3 = Polynomial {
2415 coefficients: vec![from_const(5), from_const(6)],
2416 };
2417 let p4 = Polynomial {
2418 coefficients: vec![from_const(7), from_const(8)],
2419 };
2420 let result = Polynomial {
2421 coefficients: vec![
2422 from_const(105),
2423 from_const(596),
2424 from_const(1244),
2425 from_const(1136),
2426 from_const(384),
2427 ],
2428 };
2429 assert_eq!(
2430 Polynomial::multiply_many([p1.clone(), p2.clone(), p3.clone(), p4.clone()]),
2431 result
2432 );
2433 assert_eq!(
2434 Polynomial::multiply_many([p1.clone(), p2.clone(), p4.clone(), p3.clone()]),
2435 result
2436 );
2437 assert_eq!(
2438 Polynomial::multiply_many([p1.clone(), p3.clone(), p2.clone(), p4.clone()]),
2439 result
2440 );
2441 assert_eq!(
2442 Polynomial::multiply_many([p1.clone(), p3.clone(), p4.clone(), p2.clone()]),
2443 result
2444 );
2445 }
2447
2448 #[test]
2449 fn test_divide_zero_by_zero() {
2450 let z = Polynomial {
2451 coefficients: vec![
2452 -from_const(1),
2453 from_const(0),
2454 from_const(0),
2455 from_const(0),
2456 from_const(1),
2457 ],
2458 };
2459 assert_eq!(
2460 z.divide_by_zero(4).unwrap(),
2461 Polynomial {
2462 coefficients: vec![from_const(1)]
2463 }
2464 );
2465 }
2466
2467 #[test]
2468 fn test_non_trivial_quotient1() {
2469 let ql = Polynomial::encode2(vec![
2470 from_const(0),
2471 from_const(0),
2472 from_const(1),
2473 from_const(1),
2474 ]);
2475 let qr = Polynomial::encode2(vec![
2476 from_const(0),
2477 from_const(0),
2478 from_const(1),
2479 from_const(1),
2480 ]);
2481 let qo = Polynomial::encode2(vec![-from_const(1); 4]);
2482 let qm = Polynomial::encode2(vec![
2483 from_const(1),
2484 from_const(1),
2485 from_const(0),
2486 from_const(0),
2487 ]);
2488 let qc = Polynomial::encode2(vec![from_const(0); 4]);
2489 let l = Polynomial::encode2(vec![
2490 from_const(3),
2491 from_const(9),
2492 from_const(3),
2493 from_const(30),
2494 ]);
2495 let r = Polynomial::encode2(vec![
2496 from_const(3),
2497 from_const(3),
2498 from_const(27),
2499 from_const(5),
2500 ]);
2501 let o = Polynomial::encode2(vec![
2502 from_const(9),
2503 from_const(27),
2504 from_const(30),
2505 from_const(35),
2506 ]);
2507 let lr = l.clone().multiply(r.clone());
2508 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
2509 let q = p.divide_by_zero(4).unwrap();
2510 assert_eq!(q.len(), 6);
2511 assert_eq!(q.degree_bound(), 6);
2512 }
2513
2514 #[test]
2515 fn test_non_trivial_quotient2() {
2516 let ql = Polynomial::encode2(vec![
2517 from_const(0),
2518 from_const(0),
2519 from_const(1),
2520 from_const(1),
2521 ]);
2522 let qr = Polynomial::encode2(vec![
2523 from_const(0),
2524 from_const(0),
2525 from_const(1),
2526 from_const(5),
2527 ]);
2528 let qo = Polynomial::encode2(vec![-from_const(1); 4]);
2529 let qm = Polynomial::encode2(vec![
2530 from_const(1),
2531 from_const(1),
2532 from_const(0),
2533 from_const(0),
2534 ]);
2535 let qc = Polynomial::encode2(vec![from_const(0); 4]);
2536 let l = Polynomial::encode2(vec![
2537 from_const(3),
2538 from_const(9),
2539 from_const(3),
2540 from_const(30),
2541 ]);
2542 let r = Polynomial::encode2(vec![
2543 from_const(3),
2544 from_const(3),
2545 from_const(27),
2546 from_const(1),
2547 ]);
2548 let o = Polynomial::encode2(vec![
2549 from_const(9),
2550 from_const(27),
2551 from_const(30),
2552 from_const(35),
2553 ]);
2554 let lr = l.clone().multiply(r.clone());
2555 let p = ql.multiply(l) + qr.multiply(r) + qo.multiply(o) + qm.multiply(lr) + qc;
2556 let q = p.divide_by_zero(4).unwrap();
2557 assert_eq!(q.len(), 6);
2558 assert_eq!(q.degree_bound(), 6);
2559 }
2560
2561 #[test]
2562 fn test_shift_domain2() {
2563 let values = vec![
2564 from_const(12),
2565 from_const(34),
2566 from_const(56),
2567 from_const(78),
2568 ];
2569 let p = Polynomial::encode2(values);
2570 let shifted = p.clone().shift_domain();
2571 assert_eq!(
2572 shifted.evaluate_on_two_adic_domain(0, 4),
2573 p.evaluate_on_two_adic_coset(0, 4)
2574 );
2575 assert_eq!(
2576 shifted.evaluate_on_two_adic_domain(1, 4),
2577 p.evaluate_on_two_adic_coset(1, 4)
2578 );
2579 assert_eq!(
2580 shifted.evaluate_on_two_adic_domain(2, 4),
2581 p.evaluate_on_two_adic_coset(2, 4)
2582 );
2583 assert_eq!(
2584 shifted.evaluate_on_two_adic_domain(3, 4),
2585 p.evaluate_on_two_adic_coset(3, 4)
2586 );
2587 }
2588
2589 #[test]
2590 fn test_shift_domain3() {
2591 let values = vec![from_const(12), from_const(34), from_const(56)];
2592 let p = Polynomial::encode3(values);
2593 let shifted = p.clone().shift_domain();
2594 assert_eq!(
2595 shifted.evaluate_on_three_adic_domain(0, 3),
2596 p.evaluate_on_three_adic_coset(0, 3)
2597 );
2598 assert_eq!(
2599 shifted.evaluate_on_three_adic_domain(1, 3),
2600 p.evaluate_on_three_adic_coset(1, 3)
2601 );
2602 assert_eq!(
2603 shifted.evaluate_on_three_adic_domain(2, 3),
2604 p.evaluate_on_three_adic_coset(2, 3)
2605 );
2606 }
2607
2608 #[test]
2609 fn test_lde2_blowup2() {
2610 let values = vec![
2611 from_const(12),
2612 from_const(34),
2613 from_const(56),
2614 from_const(78),
2615 ];
2616 let p = Polynomial::encode2(values);
2617 let lde = p.clone().lde2(8);
2618 assert_eq!(
2619 lde,
2620 vec![
2621 p.evaluate_on_two_adic_domain(0, 8),
2622 p.evaluate_on_two_adic_domain(1, 8),
2623 p.evaluate_on_two_adic_domain(2, 8),
2624 p.evaluate_on_two_adic_domain(3, 8),
2625 p.evaluate_on_two_adic_domain(4, 8),
2626 p.evaluate_on_two_adic_domain(5, 8),
2627 p.evaluate_on_two_adic_domain(6, 8),
2628 p.evaluate_on_two_adic_domain(7, 8),
2629 ]
2630 );
2631 }
2632
2633 #[test]
2634 fn test_lde2_blowup4() {
2635 let values = vec![from_const(1), from_const(2), from_const(3), from_const(4)];
2636 let p = Polynomial::encode2(values);
2637 let lde = p.clone().lde2(16);
2638 assert_eq!(
2639 lde,
2640 vec![
2641 p.evaluate_on_two_adic_domain(0, 16),
2642 p.evaluate_on_two_adic_domain(1, 16),
2643 p.evaluate_on_two_adic_domain(2, 16),
2644 p.evaluate_on_two_adic_domain(3, 16),
2645 p.evaluate_on_two_adic_domain(4, 16),
2646 p.evaluate_on_two_adic_domain(5, 16),
2647 p.evaluate_on_two_adic_domain(6, 16),
2648 p.evaluate_on_two_adic_domain(7, 16),
2649 p.evaluate_on_two_adic_domain(8, 16),
2650 p.evaluate_on_two_adic_domain(9, 16),
2651 p.evaluate_on_two_adic_domain(10, 16),
2652 p.evaluate_on_two_adic_domain(11, 16),
2653 p.evaluate_on_two_adic_domain(12, 16),
2654 p.evaluate_on_two_adic_domain(13, 16),
2655 p.evaluate_on_two_adic_domain(14, 16),
2656 p.evaluate_on_two_adic_domain(15, 16),
2657 ]
2658 );
2659 }
2660
2661 #[test]
2662 fn test_lde2_shorter_polynomial() {
2663 let values = vec![from_const(42), from_const(42)];
2664 let p = Polynomial::encode2(values);
2665 assert_eq!(p.len(), 1);
2666 assert_eq!(p.degree_bound(), 1);
2667 let lde = p.clone().lde2(4);
2668 assert_eq!(
2669 lde,
2670 vec![
2671 p.evaluate_on_two_adic_domain(0, 4),
2672 p.evaluate_on_two_adic_domain(1, 4),
2673 p.evaluate_on_two_adic_domain(2, 4),
2674 p.evaluate_on_two_adic_domain(3, 4),
2675 ]
2676 );
2677 }
2678
2679 #[test]
2680 fn test_lde3_blowup3() {
2681 let values = vec![from_const(12), from_const(34), from_const(56)];
2682 let p = Polynomial::encode3(values);
2683 let lde = p.clone().lde3(9);
2684 assert_eq!(
2685 lde,
2686 vec![
2687 p.evaluate_on_three_adic_domain(0, 9),
2688 p.evaluate_on_three_adic_domain(1, 9),
2689 p.evaluate_on_three_adic_domain(2, 9),
2690 p.evaluate_on_three_adic_domain(3, 9),
2691 p.evaluate_on_three_adic_domain(4, 9),
2692 p.evaluate_on_three_adic_domain(5, 9),
2693 p.evaluate_on_three_adic_domain(6, 9),
2694 p.evaluate_on_three_adic_domain(7, 9),
2695 p.evaluate_on_three_adic_domain(8, 9),
2696 ]
2697 );
2698 }
2699
2700 #[test]
2701 fn test_lde3_blowup9() {
2702 let values = vec![from_const(1), from_const(2), from_const(3)];
2703 let p = Polynomial::encode3(values);
2704 let lde = p.clone().lde3(27);
2705 assert_eq!(
2706 lde,
2707 vec![
2708 p.evaluate_on_three_adic_domain(0, 27),
2709 p.evaluate_on_three_adic_domain(1, 27),
2710 p.evaluate_on_three_adic_domain(2, 27),
2711 p.evaluate_on_three_adic_domain(3, 27),
2712 p.evaluate_on_three_adic_domain(4, 27),
2713 p.evaluate_on_three_adic_domain(5, 27),
2714 p.evaluate_on_three_adic_domain(6, 27),
2715 p.evaluate_on_three_adic_domain(7, 27),
2716 p.evaluate_on_three_adic_domain(8, 27),
2717 p.evaluate_on_three_adic_domain(9, 27),
2718 p.evaluate_on_three_adic_domain(10, 27),
2719 p.evaluate_on_three_adic_domain(11, 27),
2720 p.evaluate_on_three_adic_domain(12, 27),
2721 p.evaluate_on_three_adic_domain(13, 27),
2722 p.evaluate_on_three_adic_domain(14, 27),
2723 p.evaluate_on_three_adic_domain(15, 27),
2724 p.evaluate_on_three_adic_domain(16, 27),
2725 p.evaluate_on_three_adic_domain(17, 27),
2726 p.evaluate_on_three_adic_domain(18, 27),
2727 p.evaluate_on_three_adic_domain(19, 27),
2728 p.evaluate_on_three_adic_domain(20, 27),
2729 p.evaluate_on_three_adic_domain(21, 27),
2730 p.evaluate_on_three_adic_domain(22, 27),
2731 p.evaluate_on_three_adic_domain(23, 27),
2732 p.evaluate_on_three_adic_domain(24, 27),
2733 p.evaluate_on_three_adic_domain(25, 27),
2734 p.evaluate_on_three_adic_domain(26, 27),
2735 ]
2736 );
2737 }
2738
2739 #[test]
2740 fn test_lde3_nine_values_blowup3() {
2741 let values = (1u64..=9).map(Scalar::from).collect();
2742 let p = Polynomial::encode3(values);
2743 let lde = p.clone().lde3(27);
2744 assert_eq!(
2745 lde,
2746 vec![
2747 p.evaluate_on_three_adic_domain(0, 27),
2748 p.evaluate_on_three_adic_domain(1, 27),
2749 p.evaluate_on_three_adic_domain(2, 27),
2750 p.evaluate_on_three_adic_domain(3, 27),
2751 p.evaluate_on_three_adic_domain(4, 27),
2752 p.evaluate_on_three_adic_domain(5, 27),
2753 p.evaluate_on_three_adic_domain(6, 27),
2754 p.evaluate_on_three_adic_domain(7, 27),
2755 p.evaluate_on_three_adic_domain(8, 27),
2756 p.evaluate_on_three_adic_domain(9, 27),
2757 p.evaluate_on_three_adic_domain(10, 27),
2758 p.evaluate_on_three_adic_domain(11, 27),
2759 p.evaluate_on_three_adic_domain(12, 27),
2760 p.evaluate_on_three_adic_domain(13, 27),
2761 p.evaluate_on_three_adic_domain(14, 27),
2762 p.evaluate_on_three_adic_domain(15, 27),
2763 p.evaluate_on_three_adic_domain(16, 27),
2764 p.evaluate_on_three_adic_domain(17, 27),
2765 p.evaluate_on_three_adic_domain(18, 27),
2766 p.evaluate_on_three_adic_domain(19, 27),
2767 p.evaluate_on_three_adic_domain(20, 27),
2768 p.evaluate_on_three_adic_domain(21, 27),
2769 p.evaluate_on_three_adic_domain(22, 27),
2770 p.evaluate_on_three_adic_domain(23, 27),
2771 p.evaluate_on_three_adic_domain(24, 27),
2772 p.evaluate_on_three_adic_domain(25, 27),
2773 p.evaluate_on_three_adic_domain(26, 27),
2774 ]
2775 );
2776 }
2777
2778 #[test]
2779 fn test_lde3_shorter_poly() {
2780 let values = vec![from_const(7), from_const(7), from_const(7)];
2781 let p = Polynomial::encode3(values);
2782 assert_eq!(p.len(), 1);
2783 assert_eq!(p.degree_bound(), 1);
2784 let lde = p.clone().lde3(9);
2785 assert_eq!(
2786 lde,
2787 vec![
2788 p.evaluate_on_three_adic_domain(0, 9),
2789 p.evaluate_on_three_adic_domain(1, 9),
2790 p.evaluate_on_three_adic_domain(2, 9),
2791 p.evaluate_on_three_adic_domain(3, 9),
2792 p.evaluate_on_three_adic_domain(4, 9),
2793 p.evaluate_on_three_adic_domain(5, 9),
2794 p.evaluate_on_three_adic_domain(6, 9),
2795 p.evaluate_on_three_adic_domain(7, 9),
2796 p.evaluate_on_three_adic_domain(8, 9),
2797 ]
2798 );
2799 }
2800
2801 #[test]
2802 fn test_fold2_degree_zero() {
2803 let p = Polynomial::with_coefficients(vec![from_const(5)]);
2804 assert_eq!(p.clone().fold2(from_const(2)).take(), vec![from_const(5)]);
2805 assert_eq!(p.fold2(from_const(3)).take(), vec![from_const(5)]);
2806 }
2807
2808 #[test]
2809 fn test_fold2_degree_one() {
2810 let p = Polynomial::with_coefficients(vec![from_const(2), from_const(3)]);
2811 assert_eq!(p.clone().fold2(from_const(2)).take(), vec![from_const(8)]);
2812 assert_eq!(p.fold2(from_const(3)).take(), vec![from_const(11)]);
2813 }
2814
2815 #[test]
2816 fn test_fold2_degree_two() {
2817 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2818 assert_eq!(
2819 p.clone().fold2(from_const(2)).take(),
2820 vec![from_const(5), from_const(3)],
2821 );
2822 assert_eq!(
2823 p.fold2(from_const(3)).take(),
2824 vec![from_const(7), from_const(3)],
2825 );
2826 }
2827
2828 #[test]
2829 fn test_fold2_degree_three() {
2830 let p = Polynomial::with_coefficients(vec![
2831 from_const(1),
2832 from_const(2),
2833 from_const(3),
2834 from_const(4),
2835 ]);
2836 assert_eq!(
2837 p.clone().fold2(from_const(2)).take(),
2838 vec![from_const(5), from_const(11)],
2839 );
2840 assert_eq!(
2841 p.fold2(from_const(3)).take(),
2842 vec![from_const(7), from_const(15)],
2843 );
2844 }
2845
2846 #[test]
2847 fn test_fold3_degree_zero() {
2848 let p = Polynomial::with_coefficients(vec![from_const(5)]);
2849 assert_eq!(p.clone().fold3(from_const(2)).take(), vec![from_const(5)]);
2850 assert_eq!(p.fold3(from_const(3)).take(), vec![from_const(5)]);
2851 }
2852
2853 #[test]
2854 fn test_fold3_degree_two() {
2855 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
2856 assert_eq!(p.clone().fold3(from_const(2)).take(), vec![from_const(17)]);
2857 assert_eq!(p.fold3(from_const(3)).take(), vec![from_const(34)]);
2858 }
2859
2860 #[test]
2861 fn test_fold3_degree_three() {
2862 let p = Polynomial::with_coefficients(vec![
2863 from_const(1),
2864 from_const(2),
2865 from_const(3),
2866 from_const(4),
2867 ]);
2868 assert_eq!(
2869 p.clone().fold3(from_const(2)).take(),
2870 vec![from_const(17), from_const(4)],
2871 );
2872 assert_eq!(
2873 p.fold3(from_const(3)).take(),
2874 vec![from_const(34), from_const(4)],
2875 );
2876 }
2877
2878 #[test]
2879 fn test_fold3_degree_five() {
2880 let p = Polynomial::with_coefficients(vec![
2881 from_const(1),
2882 from_const(2),
2883 from_const(3),
2884 from_const(4),
2885 from_const(5),
2886 from_const(6),
2887 ]);
2888 assert_eq!(
2889 p.clone().fold3(from_const(2)).take(),
2890 vec![from_const(17), from_const(38)],
2891 );
2892 assert_eq!(
2893 p.fold3(from_const(3)).take(),
2894 vec![from_const(34), from_const(73)],
2895 );
2896 }
2897
2898 #[test]
2899 fn test_multiply_values2_same_constant() {
2900 let lhs = vec![from_const(42), from_const(42)];
2901 let rhs = vec![from_const(42), from_const(42)];
2902 let result = Polynomial::multiply_values2(lhs, rhs);
2903 assert_eq!(result, vec![from_const(1764)]);
2904 }
2905
2906 #[test]
2907 fn test_multiply_values2_different_constants() {
2908 let lhs = vec![from_const(3), from_const(3)];
2909 let rhs = vec![from_const(7), from_const(7)];
2910 let result = Polynomial::multiply_values2(lhs, rhs);
2911 assert_eq!(result, vec![from_const(21)]);
2912 }
2913
2914 #[test]
2915 fn test_multiply_values2_two_linear_polynomials() {
2916 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2917 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
2918 let lhs = vec![
2919 p.evaluate_on_two_adic_domain(0, 2),
2920 p.evaluate_on_two_adic_domain(1, 2),
2921 ];
2922 let rhs = vec![
2923 q.evaluate_on_two_adic_domain(0, 2),
2924 q.evaluate_on_two_adic_domain(1, 2),
2925 ];
2926 let product = p.multiply(q);
2927 let result = Polynomial::multiply_values2(lhs, rhs);
2928 assert_eq!(
2929 result,
2930 vec![
2931 product.evaluate_on_two_adic_domain(0, 4),
2932 product.evaluate_on_two_adic_domain(1, 4),
2933 product.evaluate_on_two_adic_domain(2, 4),
2934 product.evaluate_on_two_adic_domain(3, 4),
2935 ]
2936 );
2937 }
2938
2939 #[test]
2940 fn test_multiply_values2_four_values() {
2941 let p = Polynomial::with_coefficients(vec![
2942 from_const(1),
2943 from_const(2),
2944 from_const(3),
2945 from_const(4),
2946 ]);
2947 let q = Polynomial::with_coefficients(vec![
2948 from_const(5),
2949 from_const(6),
2950 from_const(7),
2951 from_const(8),
2952 ]);
2953 let lhs = vec![
2954 p.evaluate_on_two_adic_domain(0, 4),
2955 p.evaluate_on_two_adic_domain(1, 4),
2956 p.evaluate_on_two_adic_domain(2, 4),
2957 p.evaluate_on_two_adic_domain(3, 4),
2958 ];
2959 let rhs = vec![
2960 q.evaluate_on_two_adic_domain(0, 4),
2961 q.evaluate_on_two_adic_domain(1, 4),
2962 q.evaluate_on_two_adic_domain(2, 4),
2963 q.evaluate_on_two_adic_domain(3, 4),
2964 ];
2965 let product = p.multiply(q);
2966 let result = Polynomial::multiply_values2(lhs, rhs);
2967 assert_eq!(
2968 result,
2969 vec![
2970 product.evaluate_on_two_adic_domain(0, 8),
2971 product.evaluate_on_two_adic_domain(1, 8),
2972 product.evaluate_on_two_adic_domain(2, 8),
2973 product.evaluate_on_two_adic_domain(3, 8),
2974 product.evaluate_on_two_adic_domain(4, 8),
2975 product.evaluate_on_two_adic_domain(5, 8),
2976 product.evaluate_on_two_adic_domain(6, 8),
2977 product.evaluate_on_two_adic_domain(7, 8),
2978 ]
2979 );
2980 }
2981
2982 #[test]
2983 fn test_multiply_values2_commutative() {
2984 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
2985 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
2986 let values_p = vec![
2987 p.evaluate_on_two_adic_domain(0, 2),
2988 p.evaluate_on_two_adic_domain(1, 2),
2989 ];
2990 let values_q = vec![
2991 q.evaluate_on_two_adic_domain(0, 2),
2992 q.evaluate_on_two_adic_domain(1, 2),
2993 ];
2994 let result_pq = Polynomial::multiply_values2(values_p.clone(), values_q.clone());
2995 let result_qp = Polynomial::multiply_values2(values_q, values_p);
2996 assert_eq!(result_pq, result_qp);
2997 }
2998
2999 #[test]
3000 fn test_multiply_values2_round_trip() {
3001 let p = Polynomial::with_coefficients(vec![
3002 from_const(1),
3003 from_const(2),
3004 from_const(3),
3005 from_const(4),
3006 ]);
3007 let q = Polynomial::with_coefficients(vec![
3008 from_const(5),
3009 from_const(6),
3010 from_const(7),
3011 from_const(8),
3012 ]);
3013 let lhs = vec![
3014 p.evaluate_on_two_adic_domain(0, 4),
3015 p.evaluate_on_two_adic_domain(1, 4),
3016 p.evaluate_on_two_adic_domain(2, 4),
3017 p.evaluate_on_two_adic_domain(3, 4),
3018 ];
3019 let rhs = vec![
3020 q.evaluate_on_two_adic_domain(0, 4),
3021 q.evaluate_on_two_adic_domain(1, 4),
3022 q.evaluate_on_two_adic_domain(2, 4),
3023 q.evaluate_on_two_adic_domain(3, 4),
3024 ];
3025 let product = p.clone().multiply(q.clone());
3026 let result = Polynomial::encode2(Polynomial::multiply_values2(lhs, rhs));
3027 assert_eq!(result, product);
3028 }
3029
3030 #[test]
3031 fn test_multiply_values3_same_constant() {
3032 let lhs = vec![from_const(42), from_const(42), from_const(42)];
3033 let rhs = vec![from_const(42), from_const(42), from_const(42)];
3034 let result = Polynomial::multiply_values3(lhs, rhs);
3035 assert_eq!(result, vec![from_const(1764)]);
3036 }
3037
3038 #[test]
3039 fn test_multiply_values3_different_constants() {
3040 let lhs = vec![from_const(3), from_const(3), from_const(3)];
3041 let rhs = vec![from_const(7), from_const(7), from_const(7)];
3042 let result = Polynomial::multiply_values3(lhs, rhs);
3043 assert_eq!(result, vec![from_const(21)]);
3044 }
3045
3046 #[test]
3047 fn test_multiply_values3_two_linear_polynomials() {
3048 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3049 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3050 let lhs = vec![
3051 p.evaluate_on_three_adic_domain(0, 3),
3052 p.evaluate_on_three_adic_domain(1, 3),
3053 p.evaluate_on_three_adic_domain(2, 3),
3054 ];
3055 let rhs = vec![
3056 q.evaluate_on_three_adic_domain(0, 3),
3057 q.evaluate_on_three_adic_domain(1, 3),
3058 q.evaluate_on_three_adic_domain(2, 3),
3059 ];
3060 let product = p.multiply(q);
3061 let result = Polynomial::multiply_values3(lhs, rhs);
3062 assert_eq!(
3063 result,
3064 vec![
3065 product.evaluate_on_three_adic_domain(0, 3),
3066 product.evaluate_on_three_adic_domain(1, 3),
3067 product.evaluate_on_three_adic_domain(2, 3),
3068 ]
3069 );
3070 }
3071
3072 #[test]
3073 fn test_multiply_values3_nine_values() {
3074 let p = Polynomial::with_coefficients(vec![
3075 from_const(1),
3076 from_const(2),
3077 from_const(3),
3078 from_const(4),
3079 from_const(5),
3080 from_const(6),
3081 from_const(7),
3082 from_const(8),
3083 from_const(9),
3084 ]);
3085 let q = Polynomial::with_coefficients(vec![
3086 from_const(10),
3087 from_const(11),
3088 from_const(12),
3089 from_const(13),
3090 from_const(14),
3091 from_const(15),
3092 from_const(16),
3093 from_const(17),
3094 from_const(18),
3095 ]);
3096 let lhs = vec![
3097 p.evaluate_on_three_adic_domain(0, 9),
3098 p.evaluate_on_three_adic_domain(1, 9),
3099 p.evaluate_on_three_adic_domain(2, 9),
3100 p.evaluate_on_three_adic_domain(3, 9),
3101 p.evaluate_on_three_adic_domain(4, 9),
3102 p.evaluate_on_three_adic_domain(5, 9),
3103 p.evaluate_on_three_adic_domain(6, 9),
3104 p.evaluate_on_three_adic_domain(7, 9),
3105 p.evaluate_on_three_adic_domain(8, 9),
3106 ];
3107 let rhs = vec![
3108 q.evaluate_on_three_adic_domain(0, 9),
3109 q.evaluate_on_three_adic_domain(1, 9),
3110 q.evaluate_on_three_adic_domain(2, 9),
3111 q.evaluate_on_three_adic_domain(3, 9),
3112 q.evaluate_on_three_adic_domain(4, 9),
3113 q.evaluate_on_three_adic_domain(5, 9),
3114 q.evaluate_on_three_adic_domain(6, 9),
3115 q.evaluate_on_three_adic_domain(7, 9),
3116 q.evaluate_on_three_adic_domain(8, 9),
3117 ];
3118 let product = p.multiply(q);
3119 let result = Polynomial::multiply_values3(lhs, rhs);
3120 assert_eq!(
3121 result,
3122 vec![
3123 product.evaluate_on_three_adic_domain(0, 27),
3124 product.evaluate_on_three_adic_domain(1, 27),
3125 product.evaluate_on_three_adic_domain(2, 27),
3126 product.evaluate_on_three_adic_domain(3, 27),
3127 product.evaluate_on_three_adic_domain(4, 27),
3128 product.evaluate_on_three_adic_domain(5, 27),
3129 product.evaluate_on_three_adic_domain(6, 27),
3130 product.evaluate_on_three_adic_domain(7, 27),
3131 product.evaluate_on_three_adic_domain(8, 27),
3132 product.evaluate_on_three_adic_domain(9, 27),
3133 product.evaluate_on_three_adic_domain(10, 27),
3134 product.evaluate_on_three_adic_domain(11, 27),
3135 product.evaluate_on_three_adic_domain(12, 27),
3136 product.evaluate_on_three_adic_domain(13, 27),
3137 product.evaluate_on_three_adic_domain(14, 27),
3138 product.evaluate_on_three_adic_domain(15, 27),
3139 product.evaluate_on_three_adic_domain(16, 27),
3140 product.evaluate_on_three_adic_domain(17, 27),
3141 product.evaluate_on_three_adic_domain(18, 27),
3142 product.evaluate_on_three_adic_domain(19, 27),
3143 product.evaluate_on_three_adic_domain(20, 27),
3144 product.evaluate_on_three_adic_domain(21, 27),
3145 product.evaluate_on_three_adic_domain(22, 27),
3146 product.evaluate_on_three_adic_domain(23, 27),
3147 product.evaluate_on_three_adic_domain(24, 27),
3148 product.evaluate_on_three_adic_domain(25, 27),
3149 product.evaluate_on_three_adic_domain(26, 27),
3150 ]
3151 );
3152 }
3153
3154 #[test]
3155 fn test_multiply_values3_commutative() {
3156 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2)]);
3157 let q = Polynomial::with_coefficients(vec![from_const(3), from_const(4)]);
3158 let values_p = vec![
3159 p.evaluate_on_three_adic_domain(0, 3),
3160 p.evaluate_on_three_adic_domain(1, 3),
3161 p.evaluate_on_three_adic_domain(2, 3),
3162 ];
3163 let values_q = vec![
3164 q.evaluate_on_three_adic_domain(0, 3),
3165 q.evaluate_on_three_adic_domain(1, 3),
3166 q.evaluate_on_three_adic_domain(2, 3),
3167 ];
3168 let result_pq = Polynomial::multiply_values3(values_p.clone(), values_q.clone());
3169 let result_qp = Polynomial::multiply_values3(values_q, values_p);
3170 assert_eq!(result_pq, result_qp);
3171 }
3172
3173 #[test]
3174 fn test_multiply_values3_round_trip() {
3175 let p = Polynomial::with_coefficients(vec![from_const(1), from_const(2), from_const(3)]);
3176 let q = Polynomial::with_coefficients(vec![from_const(4), from_const(5), from_const(6)]);
3177 let lhs = vec![
3178 p.evaluate_on_three_adic_domain(0, 3),
3179 p.evaluate_on_three_adic_domain(1, 3),
3180 p.evaluate_on_three_adic_domain(2, 3),
3181 ];
3182 let rhs = vec![
3183 q.evaluate_on_three_adic_domain(0, 3),
3184 q.evaluate_on_three_adic_domain(1, 3),
3185 q.evaluate_on_three_adic_domain(2, 3),
3186 ];
3187 let product = p.clone().multiply(q.clone());
3188 let result = Polynomial::encode3(Polynomial::multiply_values3(lhs, rhs));
3189 assert_eq!(result, product);
3190 }
3191
3192 #[test]
3193 fn test_lagrange0_1() {
3194 let n = 1;
3195 let l0 = Polynomial::lagrange0(n);
3196 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3197 }
3198
3199 #[test]
3200 fn test_lagrange0_2() {
3201 let n = 2;
3202 let omega = Polynomial::domain_element2(1, n);
3203 let l0 = Polynomial::lagrange0(n);
3204 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3205 assert_eq!(l0.evaluate(omega), from_const(0));
3206 }
3207
3208 #[test]
3209 fn test_lagrange0_4() {
3210 let n = 4;
3211 let omega = Polynomial::domain_element2(1, n);
3212 let l0 = Polynomial::lagrange0(n);
3213 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3214 assert_eq!(l0.evaluate(omega), from_const(0));
3215 assert_eq!(l0.evaluate(omega.square()), from_const(0));
3216 assert_eq!(l0.evaluate(omega.cube()), from_const(0));
3217 }
3218
3219 #[test]
3220 fn test_lagrange0_8() {
3221 let n = 8;
3222 let omega = Polynomial::domain_element2(1, n);
3223 let l0 = Polynomial::lagrange0(n);
3224 assert_eq!(l0.evaluate(from_const(1)), from_const(1));
3225 assert_eq!(l0.evaluate(omega), from_const(0));
3226 assert_eq!(l0.evaluate(omega.pow_small(2)), from_const(0));
3227 assert_eq!(l0.evaluate(omega.pow_small(3)), from_const(0));
3228 assert_eq!(l0.evaluate(omega.pow_small(4)), from_const(0));
3229 assert_eq!(l0.evaluate(omega.pow_small(5)), from_const(0));
3230 assert_eq!(l0.evaluate(omega.pow_small(6)), from_const(0));
3231 assert_eq!(l0.evaluate(omega.pow_small(7)), from_const(0));
3232 }
3233}