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