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