18template <IsUltraOrMegaHonk Flavor>
20 std::shared_ptr<VerifierInstance>
vk,
21 const std::string& domain_separator)
24 BB_BENCH_NAME(
"ProtogalaxyProver::run_oink_prover_on_one_incomplete_instance");
31 auto key = prover_insts_to_fold[0];
33 if (!
key->is_complete) {
34 run_oink_prover_on_one_incomplete_instance(
key, verifier_insts_to_fold[0], domain_separator);
36 key->gate_challenges =
37 transcript->template get_powers_of_challenge<FF>(domain_separator +
"_gate_challenge", CONST_PG_LOG_N);
41 key = prover_insts_to_fold[1];
43 run_oink_prover_on_one_incomplete_instance(
key, verifier_insts_to_fold[1], domain_separator);
45 accumulator = prover_insts_to_fold[0];
48template <IsUltraOrMegaHonk Flavor>
54 const std::vector<FF> deltas = transcript->template get_powers_of_challenge<FF>(
"delta", CONST_PG_LOG_N);
56 const Polynomial<FF> perturbator = accumulator->is_relaxed_instance
57 ? pg_internal.compute_perturbator(accumulator, deltas)
61 for (
size_t idx = 1; idx <= CONST_PG_LOG_N; idx++) {
62 transcript->send_to_verifier(
"perturbator_" +
std::to_string(idx), perturbator[idx]);
65 return std::make_tuple(deltas, perturbator);
68template <IsUltraOrMegaHonk Flavor>
75 const std::vector<FF>& deltas,
81 const FF perturbator_challenge = transcript->template get_challenge<FF>(
"perturbator_challenge");
84 const std::vector<FF> updated_gate_challenges =
94 PGInternal::template compute_extended_relation_parameters<UnivariateRelationParameters>(instances);
98 auto combiner = pg_internal.compute_combiner(instances, gate_separators, relation_parameters, alphas, accumulators);
100 const FF perturbator_evaluation = perturbator.evaluate(perturbator_challenge);
101 const CombinerQuotient combiner_quotient = PGInternal::compute_combiner_quotient(perturbator_evaluation, combiner);
103 for (
size_t idx = NUM_INSTANCES; idx < BATCHED_EXTENDED_LENGTH; idx++) {
104 transcript->send_to_verifier(
"combiner_quotient_" +
std::to_string(idx), combiner_quotient.
value_at(idx));
107 return std::make_tuple(
108 updated_gate_challenges, alphas, relation_parameters, perturbator_evaluation, combiner_quotient);
114template <IsUltraOrMegaHonk Flavor>
120 const FF& perturbator_evaluation)
122 BB_BENCH_NAME(
"ProtogalaxyProver_::update_target_sum_and_fold");
124 std::shared_ptr<ProverInstance> accumulator = instances[0];
125 std::shared_ptr<ProverInstance> incoming = instances[1];
126 accumulator->is_relaxed_instance =
true;
129 BB_ASSERT_EQ(accumulator->polynomials.w_l.virtual_size(), incoming->polynomials.w_l.virtual_size());
132 const FF combiner_challenge = transcript->template get_challenge<FF>(
"combiner_quotient_challenge");
135 auto [vanishing_polynomial_at_challenge, lagranges] =
136 PGInternal::compute_vanishing_polynomial_and_lagranges(combiner_challenge);
137 accumulator->target_sum = perturbator_evaluation * lagranges[0] +
138 vanishing_polynomial_at_challenge * combiner_quotient.
evaluate(combiner_challenge);
145 bool swap_polys = incoming->get_overflow_size() > accumulator->get_overflow_size();
147 std::swap(accumulator->polynomials, incoming->polynomials);
148 std::swap(lagranges[0], lagranges[1]);
149 accumulator->set_dyadic_size(incoming->dyadic_size());
150 accumulator->set_overflow_size(incoming->get_overflow_size());
157 auto accumulator_polys = accumulator->polynomials.get_unshifted();
158 auto key_polys = incoming->polynomials.get_unshifted();
159 const size_t num_polys = key_polys.size();
163 acc_spans.reserve(num_polys);
164 key_spans.reserve(num_polys);
165 for (
size_t i = 0; i < num_polys; ++i) {
170 parallel_for([&acc_spans, &key_spans, &lagranges, &combiner_challenge, &swap_polys](
const ThreadChunk& chunk) {
171 for (
auto [acc_poly, key_poly] :
zip_view(acc_spans, key_spans)) {
173 acc_poly.start_index,
174 key_poly.start_index,
175 "Folding a smaller polynomial into a larger one. This is only allowed when using structured traces.");
177 acc_poly.end_index(),
178 key_poly.end_index(),
179 "Folding a smaller polynomial into a larger one. This is only allowed when using structured traces.");
180 size_t offset = acc_poly.start_index;
181 for (
size_t idx : chunk.
range(acc_poly.size(),
offset)) {
182 if ((idx < key_poly.start_index) || (idx >= key_poly.end_index())) {
183 acc_poly[idx] *= lagranges[0];
189 acc_poly[idx] = key_poly[idx] + (acc_poly[idx] - key_poly[idx]) * combiner_challenge;
191 acc_poly[idx] = acc_poly[idx] + (key_poly[idx] - acc_poly[idx]) * combiner_challenge;
199 BB_BENCH_NAME(
"ProtogalaxyProver_::update_target_sum_and_fold::update_alphas_and_relation_parameters");
204 for (
size_t i : chunk.
range(NUM_SUBRELATIONS)) {
205 accumulator->alphas[i] = alphas[i].evaluate(combiner_challenge);
209 auto univariate_params_to_fold = univariate_relation_parameters.
get_to_fold();
210 auto accumulator_params_to_fold = accumulator->relation_parameters.get_to_fold();
213 for (
size_t i : chunk.
range(univariate_params_to_fold.size())) {
214 accumulator_params_to_fold[i] = univariate_params_to_fold[i].evaluate(combiner_challenge);
225 size_t max_circuit_size = 0;
226 for (
size_t idx = 0; idx < NUM_INSTANCES; ++idx) {
227 max_circuit_size =
std::max(max_circuit_size, prover_insts_to_fold[idx]->dyadic_size());
229 for (
size_t idx = 0; idx < NUM_INSTANCES; ++idx) {
230 if (prover_insts_to_fold[idx]->dyadic_size() != max_circuit_size) {
231 info(
"ProtogalaxyProver: circuit size mismatch - increasing virtual size of key ",
234 prover_insts_to_fold[idx]->dyadic_size(),
237 prover_insts_to_fold[idx]->polynomials.increase_polynomials_virtual_size(max_circuit_size);
241 run_oink_prover_on_each_incomplete_instance();
242 vinfo(
"oink prover on each incomplete key");
244 std::tie(deltas, perturbator) = perturbator_round(accumulator);
245 vinfo(
"perturbator round");
247 std::tie(accumulator->gate_challenges, alphas, relation_parameters, perturbator_evaluation, combiner_quotient) =
248 combiner_quotient_round(accumulator->gate_challenges, deltas, prover_insts_to_fold);
249 vinfo(
"combiner quotient round");
251 update_target_sum_and_fold(
252 prover_insts_to_fold, combiner_quotient, alphas, relation_parameters, perturbator_evaluation);
#define BB_ASSERT_GTE(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define BB_ASSERT_LTE(left, right,...)
#define BB_BENCH_NAME(name)
Class for all the oink rounds, which are shared between the folding prover and ultra prover.
void prove()
Oink Prover function that runs all the rounds of the verifier.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
std::array< std::shared_ptr< ProverInstance >, NUM_INSTANCES > ProverInstances
BB_PROFILE FoldingResult< Flavor > prove()
Execute the folding prover.
std::tuple< std::vector< FF >, UnivariateSubrelationSeparators, UnivariateRelationParameters, FF, CombinerQuotient > combiner_quotient_round(const std::vector< FF > &gate_challenges, const std::vector< FF > &deltas, const ProverInstances &instances)
Steps 6 - 11 of the paper.
typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates< NUM_INSTANCES > TupleOfTuplesOfUnivariates
void run_oink_prover_on_one_incomplete_instance(std::shared_ptr< ProverInstance >, std::shared_ptr< VerifierInstance >, const std::string &domain_separator)
For each Prover instance derived from a circuit, prior to folding, we need to complete the computatio...
void run_oink_prover_on_each_incomplete_instance()
Create inputs to folding protocol (an Oink interaction).
std::array< Univariate< FF, BATCHED_EXTENDED_LENGTH >, NUM_SUBRELATIONS - 1 > UnivariateSubrelationSeparators
void update_target_sum_and_fold(const ProverInstances &instances, const CombinerQuotient &combiner_quotient, const UnivariateSubrelationSeparators &alphas, const UnivariateRelationParameters &univariate_relation_parameters, const FF &perturbator_evaluation)
Steps 12 - 13 of the paper plus the prover folding work.
Fr evaluate(const Fr &u) const
Evaluate a univariate at a point u not known at compile time and assumed not to be in the domain (els...
constexpr T get_msb(const T in)
Entry point for Barretenberg command-line interface.
std::vector< FF > update_gate_challenges(const FF &perturbator_challenge, const std::vector< FF > &gate_challenges, const std::vector< FF > &init_challenges)
Compute the gate challenges used in the combiner calculation.
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
The result of one iteraton of Protogalaxy proving, containing a new accumulator as well as the proof ...
std::shared_ptr< ProverInstance_< Flavor > > accumulator
Implementation of the methods for the -polynomials used in in Sumcheck.
RefArray< T, NUM_TO_FOLD > get_to_fold()
auto range(size_t size, size_t offset=0) const