Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
polynomial_arithmetic.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Nishat], commit: 94f596f8b3bbbc216f9ad7dc33253256141156b2 }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
10
12
13template <typename T>
14concept SupportsFFT = T::Params::has_high_2adicity;
15
16template <typename Fr> struct LagrangeEvaluations {
20};
22
23template <typename Fr> Fr evaluate(const Fr* coeffs, const Fr& z, const size_t n);
24template <typename Fr> Fr evaluate(std::span<const Fr> coeffs, const Fr& z, const size_t n)
25{
26 BB_ASSERT_LTE(n, coeffs.size());
27 return evaluate(coeffs.data(), z, n);
28};
29template <typename Fr> Fr evaluate(std::span<const Fr> coeffs, const Fr& z)
30{
31 return evaluate(coeffs, z, coeffs.size());
32};
33template <typename Fr> Fr evaluate(const std::vector<Fr*> coeffs, const Fr& z, const size_t large_n);
34
35template <typename Fr>
36 requires SupportsFFT<Fr>
38 Fr* coeffs, Fr* target, const EvaluationDomain<Fr>& domain, const Fr&, const std::vector<Fr*>& root_table);
39template <typename Fr>
40 requires SupportsFFT<Fr>
41void ifft(Fr* coeffs, Fr* target, const EvaluationDomain<Fr>& domain);
42
43// This function computes sum of all scalars in a given array.
44template <typename Fr> Fr compute_sum(const Fr* src, const size_t n);
45
46// This function computes the polynomial (x - a)(x - b)(x - c)... given n distinct roots (a, b, c, ...).
47template <typename Fr> void compute_linear_polynomial_product(const Fr* roots, Fr* dest, const size_t n);
48
49// This function interpolates from points {(z_1, f(z_1)), (z_2, f(z_2)), ...}
50// using a single scalar inversion and Lagrange polynomial interpolation.
51// `src` contains {f(z_1), f(z_2), ...}
52template <typename Fr>
53void compute_efficient_interpolation(const Fr* src, Fr* dest, const Fr* evaluation_points, const size_t n);
54
58template <typename Fr> void factor_roots(std::span<Fr> polynomial, const Fr& root)
59{
60 const size_t size = polynomial.size();
61 if (root.is_zero()) {
62 // if one of the roots is 0 after having divided by all other roots,
63 // then p(X) = a₁⋅X + ⋯ + aₙ₋₁⋅Xⁿ⁻¹
64 // so we shift the array of coefficients to the left
65 // and the result is p(X) = a₁ + ⋯ + aₙ₋₁⋅Xⁿ⁻² and we subtract 1 from the size.
66 std::copy_n(polynomial.begin() + 1, size - 1, polynomial.begin());
67 } else {
68 // assume
69 // • r != 0
70 // • (X−r) | p(X)
71 // • q(X) = ∑ᵢⁿ⁻² bᵢ⋅Xⁱ
72 // • p(X) = ∑ᵢⁿ⁻¹ aᵢ⋅Xⁱ = (X-r)⋅q(X)
73 //
74 // p(X) 0 1 2 ... n-2 n-1
75 // a₀ a₁ a₂ aₙ₋₂ aₙ₋₁
76 //
77 // q(X) 0 1 2 ... n-2 n-1
78 // b₀ b₁ b₂ bₙ₋₂ 0
79 //
80 // (X-r)⋅q(X) 0 1 2 ... n-2 n-1
81 // -r⋅b₀ b₀-r⋅b₁ b₁-r⋅b₂ bₙ₋₃−r⋅bₙ₋₂ bₙ₋₂
82 //
83 // b₀ = a₀⋅(−r)⁻¹
84 // b₁ = (a₁ - b₀)⋅(−r)⁻¹
85 // b₂ = (a₂ - b₁)⋅(−r)⁻¹
86 // ⋮
87 // bᵢ = (aᵢ − bᵢ₋₁)⋅(−r)⁻¹
88 // ⋮
89 // bₙ₋₂ = (aₙ₋₂ − bₙ₋₃)⋅(−r)⁻¹
90 // bₙ₋₁ = 0
91
92 // For the simple case of one root we compute (−r)⁻¹ and
93 Fr root_inverse = (-root).invert();
94 // set b₋₁ = 0
95 Fr temp = 0;
96 // We start multiplying lower coefficient by the inverse and subtracting those from highter coefficients
97 // Since (x - r) should divide the polynomial cleanly, we can guide division with lower coefficients
98 for (size_t i = 0; i < size - 1; ++i) {
99 // at the start of the loop, temp = bᵢ₋₁
100 // and we can compute bᵢ = (aᵢ − bᵢ₋₁)⋅(−r)⁻¹
101 temp = (polynomial[i] - temp);
102 temp *= root_inverse;
103 polynomial[i] = temp;
104 }
105 }
106 polynomial[size - 1] = Fr::zero();
107}
108
109} // namespace bb::polynomial_arithmetic
#define BB_ASSERT_LTE(left, right,...)
Definition assert.hpp:158
void ifft(Fr *coeffs, Fr *target, const EvaluationDomain< Fr > &domain)
void compute_linear_polynomial_product(const Fr *roots, Fr *dest, const size_t n)
Fr evaluate(const Fr *coeffs, const Fr &z, const size_t n)
void factor_roots(std::span< Fr > polynomial, const Fr &root)
Divides p(X) by (X-r) in-place.
void fft_inner_parallel(Fr *coeffs, Fr *target, const EvaluationDomain< Fr > &domain, const Fr &, const std::vector< Fr * > &root_table)
void compute_efficient_interpolation(const Fr *src, Fr *dest, const Fr *evaluation_points, const size_t n)
Fr compute_sum(const Fr *src, const size_t n)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
BB_INLINE constexpr bool is_zero() const noexcept
static constexpr field zero()