Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
shifted_eq_polynomial.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
13
14#include <array>
15#include <cstddef>
16#include <span>
17#include <vector>
18
19namespace bb {
20
21template <typename Curve, size_t log_num_monomials> class ShiftedEqPolynomial {
22 public:
23 using FF = typename Curve::ScalarField;
25
26 static constexpr size_t poly_length = 1UL << log_num_monomials;
27
28 static void add_scaled(Polynomial& result, const Polynomial& eq, const FF& scaling_factor)
29 requires(!Curve::is_stdlib_type)
30 {
31 BB_ASSERT_LTE(eq.size(), poly_length);
34 poly_length - 1,
35 [&](size_t idx) { result.at(idx + 1) += scaling_factor * eq[idx]; },
37 }
38
39 static FF evaluate_from_eq(const Polynomial& eq, const Polynomial& witness)
40 requires(!Curve::is_stdlib_type)
41 {
42 BB_ASSERT_LTE(eq.size(), poly_length);
43 BB_ASSERT_LTE(witness.size(), poly_length);
44 constexpr size_t ALLOW_ONE_PAST_READ = 1;
45 const auto partials = parallel_for_heuristic(
47 FF::zero(),
48 [&](size_t idx, FF& partial) { partial += eq[idx] * witness.get(idx + 1, ALLOW_ONE_PAST_READ); },
50
51 FF result = FF::zero();
52 for (const auto& partial : partials) {
53 result += partial;
54 }
55 return result;
56 }
57
58 static FF evaluate_folded(std::span<const FF> point, std::span<const FF> ipa_round_challenges_inv)
59 {
60 BB_ASSERT_EQ(point.size(), log_num_monomials);
61 BB_ASSERT_EQ(ipa_round_challenges_inv.size(), log_num_monomials);
62
63 std::array<FF, log_num_monomials> lower_prefix_products;
64 std::array<FF, log_num_monomials> upper_suffix_products;
65 compute_prefix_suffix_products(point, ipa_round_challenges_inv, lower_prefix_products, upper_suffix_products);
66
67 // Per lowest-set-bit term: left * right, with left = prefix * (1 - point), right = fold_factor * suffix.
70 for (size_t lowest_set_bit = 0; lowest_set_bit < log_num_monomials; ++lowest_set_bit) {
71 left_products[lowest_set_bit] = lower_prefix_products[lowest_set_bit] * (FF::one() - point[lowest_set_bit]);
72 right_products[lowest_set_bit] =
73 fold_factor(ipa_round_challenges_inv, lowest_set_bit) * upper_suffix_products[lowest_set_bit];
74 }
75
76 FF result = FF::zero();
77 for (size_t idx = 0; idx < log_num_monomials; ++idx) {
78 result += left_products[idx] * right_products[idx];
79 }
80 return result;
81 }
82
91 static FF evaluate_eq_folded(std::span<const FF> point, std::span<const FF> ipa_round_challenges_inv)
92 {
93 BB_ASSERT_EQ(point.size(), log_num_monomials);
94 BB_ASSERT_EQ(ipa_round_challenges_inv.size(), log_num_monomials);
95
96 FF result = FF::one();
97 for (size_t coordinate_idx = 0; coordinate_idx < log_num_monomials; ++coordinate_idx) {
98 result *= evaluate_eq_factor(point[coordinate_idx], fold_factor(ipa_round_challenges_inv, coordinate_idx));
99 }
100 return result;
101 }
102
103 private:
104 static FF fold_factor(std::span<const FF> ipa_round_challenges_inv, const size_t coordinate_idx)
105 {
106 return ipa_round_challenges_inv[log_num_monomials - 1 - coordinate_idx];
107 }
108
109 // The eq / shifted-eq per-variable factor is the gate-separator pow_β factor (1 - coordinate) + coordinate * fold.
110 static FF evaluate_eq_factor(const FF& coordinate, const FF& fold)
111 {
112 return GateSeparatorPolynomial<FF>::univariate_factor(coordinate, fold);
113 }
114
116 std::span<const FF> ipa_round_challenges_inv,
117 std::array<FF, log_num_monomials>& lower_prefix_products,
118 std::array<FF, log_num_monomials>& upper_suffix_products)
119 {
120 FF lower_prefix = FF::one();
121 for (size_t coordinate_idx = 0; coordinate_idx < log_num_monomials; ++coordinate_idx) {
122 lower_prefix_products[coordinate_idx] = lower_prefix;
123 lower_prefix *= point[coordinate_idx];
124 }
125
126 FF upper_suffix = FF::one();
127 for (size_t reverse_idx = 0; reverse_idx < log_num_monomials; ++reverse_idx) {
128 const size_t coordinate_idx = log_num_monomials - 1 - reverse_idx;
129 upper_suffix_products[coordinate_idx] = upper_suffix;
130 const FF s_i = fold_factor(ipa_round_challenges_inv, coordinate_idx);
131 upper_suffix *= evaluate_eq_factor(point[coordinate_idx], s_i);
132 }
133 }
134};
135
136} // namespace bb
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define BB_ASSERT_LTE(left, right,...)
Definition assert.hpp:158
static FF evaluate_folded(std::span< const FF > point, std::span< const FF > ipa_round_challenges_inv)
typename Curve::ScalarField FF
static FF fold_factor(std::span< const FF > ipa_round_challenges_inv, const size_t coordinate_idx)
static FF evaluate_eq_factor(const FF &coordinate, const FF &fold)
static void compute_prefix_suffix_products(std::span< const FF > point, std::span< const FF > ipa_round_challenges_inv, std::array< FF, log_num_monomials > &lower_prefix_products, std::array< FF, log_num_monomials > &upper_suffix_products)
static constexpr size_t poly_length
static FF evaluate_eq_folded(std::span< const FF > point, std::span< const FF > ipa_round_challenges_inv)
Fold the unshifted eq tensor eq(point, .) against the IPA s-vector.
static FF evaluate_from_eq(const Polynomial &eq, const Polynomial &witness)
static void add_scaled(Polynomial &result, const Polynomial &eq, const FF &scaling_factor)
static constexpr bool is_stdlib_type
Definition grumpkin.hpp:67
constexpr size_t FF_ADDITION_COST
Definition thread.hpp:132
constexpr size_t FF_MULTIPLICATION_COST
Definition thread.hpp:134
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
void parallel_for_heuristic(size_t num_points, const std::function< void(size_t, size_t, size_t)> &func, size_t heuristic_cost)
Split a loop into several loops running in parallel based on operations in 1 iteration.
Definition thread.cpp:172
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static FF univariate_factor(const FF &challenge, const FF &beta)
The pow_β per-variable factor at .
VectorField result