13#include <gtest/gtest.h>
21template <
typename Flavor>
class ProtogalaxyTests :
public testing::Test {
53 if constexpr (IsMegaFlavor<Flavor>) {
66 get<0>(keys).emplace_back(decider_proving_key);
67 get<1>(keys).emplace_back(decider_verification_keys);
75 for (
size_t idx = 0; idx < num_keys; idx++) {
79 construct_keys(keys,
builder, trace_settings);
89 FoldingProver folding_prover(proving_keys,
95 auto [prover_accumulator, folding_proof] = folding_prover.prove();
96 auto verifier_accumulator = folding_verifier.verify_folding_proof(folding_proof);
97 return { prover_accumulator, verifier_accumulator };
104 DeciderProver decider_prover(prover_accumulator);
105 DeciderVerifier decider_verifier(verifier_accumulator);
106 decider_prover.construct_proof();
107 HonkProof decider_proof = decider_prover.export_proof();
108 auto decider_output = decider_verifier.verify_proof(decider_proof);
109 bool result = decider_output.check();
119 static void test_full_honk_evaluations_valid_circuit()
128 for (
auto& alpha : decider_pk->alphas) {
129 alpha = FF::random_element();
131 PGInternal pg_internal;
132 auto full_honk_evals = pg_internal.compute_row_evaluations(
133 decider_pk->polynomials, decider_pk->alphas, decider_pk->relation_parameters);
136 for (
const auto& eval : full_honk_evals.coeffs()) {
137 EXPECT_EQ(eval,
FF(0));
146 static void test_pertubator_coefficients()
149 std::vector<FF> deltas = {
FF(2),
FF(4),
FF(8) };
150 std::vector<FF> full_honk_evaluations = {
FF(1),
FF(1),
FF(1),
FF(1),
FF(1),
FF(1),
FF(1),
FF(1) };
151 Polynomial honk_evaluations_poly(full_honk_evaluations.size());
152 for (
auto [poly_val, val] :
zip_view(honk_evaluations_poly.coeffs(), full_honk_evaluations)) {
156 std::vector<FF> expected_values = {
FF(648),
FF(936),
FF(432),
FF(64) };
157 EXPECT_EQ(perturbator.size(), 4);
158 for (
size_t i = 0; i < perturbator.size(); i++) {
159 EXPECT_EQ(perturbator[i], expected_values[i]);
168 static void test_pertubator_polynomial()
171 const size_t log_size(3);
172 const size_t size(1 << log_size);
175 for (
auto& poly : full_polynomials.get_all()) {
180 SubrelationSeparators alphas;
181 for (
auto& alpha : alphas) {
182 alpha = FF::random_element();
185 PGInternal pg_internal;
186 auto full_honk_evals = pg_internal.compute_row_evaluations(full_polynomials, alphas, relation_parameters);
187 std::vector<FF>
betas(log_size);
188 for (
size_t idx = 0; idx < log_size; idx++) {
189 betas[idx] = FF::random_element();
196 auto target_sum =
FF(0);
197 for (
size_t i = 0; i < size; i++) {
198 target_sum += full_honk_evals[i] * gate_separators[i];
202 accumulator->polynomials =
std::move(full_polynomials);
203 accumulator->set_dyadic_size(1 << log_size);
204 accumulator->gate_challenges =
betas;
205 accumulator->target_sum = target_sum;
206 accumulator->relation_parameters = relation_parameters;
207 accumulator->alphas = alphas;
209 std::vector<FF> deltas(log_size);
210 for (
size_t idx = 0; idx < log_size; idx++) {
211 deltas[idx] = FF::random_element();
213 auto perturbator = pg_internal.compute_perturbator(accumulator, deltas);
216 EXPECT_EQ(perturbator[0], target_sum);
224 static void test_combiner_quotient()
226 auto perturbator_evaluation =
FF(2);
227 auto combiner =
bb::Univariate<FF, 12>(
std::array<FF, 12>{ 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 });
233 (
FF(22) - (
FF(1) -
FF(2)) * perturbator_evaluation) / (
FF(2) *
FF(2 - 1)),
234 (
FF(23) - (
FF(1) -
FF(3)) * perturbator_evaluation) / (
FF(3) *
FF(3 - 1)),
235 (
FF(24) - (
FF(1) -
FF(4)) * perturbator_evaluation) / (
FF(4) *
FF(4 - 1)),
236 (
FF(25) - (
FF(1) -
FF(5)) * perturbator_evaluation) / (
FF(5) *
FF(5 - 1)),
237 (
FF(26) - (
FF(1) -
FF(6)) * perturbator_evaluation) / (
FF(6) *
FF(6 - 1)),
238 (
FF(27) - (
FF(1) -
FF(7)) * perturbator_evaluation) / (
FF(7) *
FF(7 - 1)),
239 (
FF(28) - (
FF(1) -
FF(8)) * perturbator_evaluation) / (
FF(8) *
FF(8 - 1)),
240 (
FF(29) - (
FF(1) -
FF(9)) * perturbator_evaluation) / (
FF(9) *
FF(9 - 1)),
241 (
FF(30) - (
FF(1) -
FF(10)) * perturbator_evaluation) / (
FF(10) *
FF(10 - 1)),
242 (
FF(31) - (
FF(1) -
FF(11)) * perturbator_evaluation) / (
FF(11) *
FF(11 - 1)),
245 for (
size_t idx = 2; idx < 7; idx++) {
246 EXPECT_EQ(combiner_quotient.
value_at(idx), expected_evals.value_at(idx));
255 static void test_compute_extended_relation_parameters()
260 pk_1->relation_parameters.eta = 1;
263 builder2.add_variable(3);
266 pk_2->relation_parameters.eta = 3;
268 DeciderProvingKeys pks{ { pk_1, pk_2 } };
269 auto relation_parameters_no_optimistic_skipping = PGInternal::template compute_extended_relation_parameters<
271 auto relation_parameters = PGInternal::template compute_extended_relation_parameters<
274 bb::Univariate<FF, 11> expected_eta{ { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21 } };
275 EXPECT_EQ(relation_parameters_no_optimistic_skipping.eta, expected_eta);
278 for (
size_t i = 0; i < 11; i++) {
279 EXPECT_EQ(relation_parameters.eta.evaluations[i], expected_eta.evaluations[i]);
287 static void test_compute_and_extend_alphas()
292 pk_1->alphas.fill(2);
295 builder2.add_variable(3);
298 pk_2->alphas.fill(4);
300 DeciderProvingKeys pks{ { pk_1, pk_2 } };
303 bb::Univariate<FF, 12> expected_alphas{ { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24 } };
304 for (
const auto& alpha : alphas) {
305 EXPECT_EQ(alpha, expected_alphas);
314 static void test_protogalaxy_inhomogeneous()
316 auto check_fold_and_decide = [](
Builder& circuit_1,
Builder& circuit_2) {
319 construct_keys(keys, circuit_1);
320 construct_keys(keys, circuit_2);
323 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(keys), get<1>(keys));
324 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
327 decide_and_verify(prover_accumulator, verifier_accumulator,
true);
335 construct_circuit(builder1);
336 construct_circuit(builder2);
341 check_fold_and_decide(builder1, builder2);
353 construct_circuit(builder1);
354 construct_circuit(builder2);
356 check_fold_and_decide(builder1, builder2);
364 construct_circuit(builder1);
365 construct_circuit(builder2);
371 check_fold_and_decide(builder1, builder2);
379 static void test_protogalaxy_bad_lookup_failure()
384 construct_circuit(builder1);
385 construct_circuit(builder2);
392 for (
auto& wire_3_witness_idx : builder1.blocks.lookup.w_o()) {
393 if (wire_3_witness_idx != builder1.zero_idx) {
394 wire_3_witness_idx = builder1.zero_idx;
401 construct_keys(keys, builder1);
402 construct_keys(keys, builder2);
405 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(keys), get<1>(keys));
408 EXPECT_FALSE(check_accumulator_target_sum_manual(prover_accumulator));
409 decide_and_verify(prover_accumulator, verifier_accumulator,
false);
416 static void test_full_protogalaxy()
418 TupleOfKeys insts = construct_keys(2);
419 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(insts), get<1>(insts));
420 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
422 TupleOfKeys insts_2 = construct_keys(1);
423 auto [prover_accumulator_2, verifier_accumulator_2] =
424 fold_and_verify({ prover_accumulator, get<0>(insts_2)[0] }, { verifier_accumulator, get<1>(insts_2)[0] });
425 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator_2));
427 decide_and_verify(prover_accumulator_2, verifier_accumulator_2,
true);
434 static void test_full_protogalaxy_structured_trace()
436 TraceSettings trace_settings{ SMALL_TEST_STRUCTURE_FOR_OVERFLOWS };
437 TupleOfKeys keys_1 = construct_keys(2, trace_settings);
439 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(keys_1), get<1>(keys_1));
440 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
442 TupleOfKeys keys_2 = construct_keys(1, trace_settings);
444 auto [prover_accumulator_2, verifier_accumulator_2] =
445 fold_and_verify({ prover_accumulator, get<0>(keys_2)[0] }, { verifier_accumulator, get<1>(keys_2)[0] });
446 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator_2));
447 info(prover_accumulator_2->dyadic_size());
448 decide_and_verify(prover_accumulator_2, verifier_accumulator_2,
true);
458 static void test_fold_with_virtual_size_expansion()
460 uint32_t overflow_capacity = 0;
461 TraceSettings trace_settings{ SMALL_TEST_STRUCTURE_FOR_OVERFLOWS, overflow_capacity };
468 const std::vector<size_t> log2_num_gates = { 14, 18 };
469 for (
size_t i = 0; i < 2; ++i) {
479 decider_pks.push_back(decider_proving_key);
480 decider_vks.push_back(decider_verification_key);
484 EXPECT_TRUE(decider_pks[0]->dyadic_size() < decider_pks[1]->dyadic_size());
487 const auto [prover_accumulator, verifier_accumulator] =
488 fold_and_verify(decider_pks, decider_vks, trace_usage_tracker);
489 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
490 decide_and_verify(prover_accumulator, verifier_accumulator,
true);
499 static void test_full_protogalaxy_structured_trace_inhomogeneous_circuits()
507 construct_circuit(builder1);
508 construct_circuit(builder2);
509 construct_circuit(builder3);
518 construct_keys(keys_1, builder1, trace_settings);
519 construct_keys(keys_1, builder2, trace_settings);
522 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(keys_1), get<1>(keys_1));
523 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
527 construct_keys(keys_2, builder3, trace_settings);
530 auto [prover_accumulator_2, verifier_accumulator_2] =
531 fold_and_verify({ prover_accumulator, get<0>(keys_2)[0] }, { verifier_accumulator, get<1>(keys_2)[0] });
532 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator_2));
533 info(prover_accumulator_2->dyadic_size());
536 decide_and_verify(prover_accumulator_2, verifier_accumulator_2,
true);
543 static void test_tampered_commitment()
545 TupleOfKeys insts = construct_keys(2);
546 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(insts), get<1>(insts));
547 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
550 verifier_accumulator->witness_commitments.w_l = Projective(Affine::random_element());
552 TupleOfKeys insts_2 = construct_keys(1);
553 auto [prover_accumulator_2, verifier_accumulator_2] =
554 fold_and_verify({ prover_accumulator, get<0>(insts_2)[0] }, { verifier_accumulator, get<1>(insts_2)[0] });
555 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator_2));
557 decide_and_verify(prover_accumulator_2, verifier_accumulator_2,
false);
565 static void test_tampered_accumulator_polynomial()
567 TupleOfKeys insts = construct_keys(2);
568 auto [prover_accumulator, verifier_accumulator] = fold_and_verify(get<0>(insts), get<1>(insts));
569 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
572 prover_accumulator->polynomials.w_l.at(1) = FF::random_element();
573 EXPECT_FALSE(check_accumulator_target_sum_manual(prover_accumulator));
575 TupleOfKeys insts_2 = construct_keys(1);
576 auto [prover_accumulator_2, verifier_accumulator_2] =
577 fold_and_verify({ prover_accumulator, get<0>(insts_2)[0] }, { verifier_accumulator, get<1>(insts_2)[0] });
579 EXPECT_EQ(prover_accumulator_2->target_sum == verifier_accumulator_2->target_sum,
false);
580 decide_and_verify(prover_accumulator_2, verifier_accumulator_2,
false);
583 template <
size_t k>
static void test_fold_k_key_pairs()
585 constexpr size_t total_insts = k + 1;
586 TupleOfKeys insts = construct_keys(total_insts);
593 auto [prover_accumulator, folding_proof] = folding_prover.prove();
594 auto verifier_accumulator = folding_verifier.verify_folding_proof(folding_proof);
595 EXPECT_TRUE(check_accumulator_target_sum_manual(prover_accumulator));
596 decide_and_verify(prover_accumulator, verifier_accumulator,
true);
606 TestFixture::test_pertubator_coefficients();
611 TestFixture::test_full_honk_evaluations_valid_circuit();
616 TestFixture::test_pertubator_polynomial();
621 TestFixture::test_combiner_quotient();
626 TestFixture::test_compute_extended_relation_parameters();
631 TestFixture::test_compute_and_extend_alphas();
636 TestFixture::test_protogalaxy_inhomogeneous();
641 TestFixture::test_full_protogalaxy();
646 TestFixture::test_full_protogalaxy_structured_trace();
651 TestFixture::test_fold_with_virtual_size_expansion();
654TYPED_TEST(ProtogalaxyTests, FullProtogalaxyStructuredTraceInhomogeneous)
656 TestFixture::test_full_protogalaxy_structured_trace_inhomogeneous_circuits();
661 TestFixture::test_tampered_commitment();
666 TestFixture::test_tampered_accumulator_polynomial();
671 TestFixture::test_protogalaxy_bad_lookup_failure();
678 TestFixture::template test_fold_k_key_pairs<1>();
CommitmentKey object over a pairing group 𝔾₁.
A DeciderProvingKey is normally constructed from a finalized circuit and it contains all the informat...
The DeciderVerificationKey encapsulates all the necessary information for a Mega Honk Verifier to ver...
A container for the prover polynomials.
The verification key is responsible for storing the commitments to the precomputed (non-witnessk) pol...
static void add_some_ecc_op_gates(MegaBuilder &builder)
Generate a simple test circuit with some ECC op gates and conventional arithmetic gates.
WitnessEntities< Commitment > WitnessCommitments
A container for the witness commitments.
bb::CommitmentKey< Curve > CommitmentKey
std::array< FF, NUM_SUBRELATIONS - 1 > SubrelationSeparators
Curve::Element GroupElement
MegaCircuitBuilder CircuitBuilder
bb::Polynomial< FF > Polynomial
Curve::AffineElement Commitment
static void add_arithmetic_gates_with_public_inputs(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates (with public inputs) to the provided circuit.
static void add_lookup_gates(Builder &builder, size_t num_iterations=1)
Add lookup gates using the uint32 XOR lookup table (table size 4096)
static void add_arithmetic_gates(Builder &builder, const size_t num_gates=4)
Add a specified number of arithmetic gates to the provided circuit.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
bb::RelationParameters< Univariate< FF, DeciderProvingKeys::EXTENDED_LENGTH, 0, NUM_KEYS - 1 > > UnivariateRelationParameters
A purely static class (never add state to this!) consisting of functions used by the Protogalaxy prov...
static Univariate< FF, DeciderPKs::BATCHED_EXTENDED_LENGTH, DeciderPKs::NUM > compute_combiner_quotient(FF perturbator_evaluation, ExtendedUnivariateWithRandomization combiner)
Compute the combiner quotient defined as $K$ polynomial in the paper.
bb::RelationParameters< Univariate< FF, DeciderProvingKeys_::EXTENDED_LENGTH > > UnivariateRelationParametersNoOptimisticSkipping
static UnivariateSubrelationSeparators compute_and_extend_alphas(const DeciderPKs &keys)
Combine the relation batching parameters (alphas) from each decider proving key into a univariate for...
static std::vector< FF > construct_perturbator_coefficients(std::span< const FF > betas, std::span< const FF > deltas, const Polynomial< FF > &full_honk_evaluations)
We construct the coefficients of the perturbator polynomial in O(n) time following the technique in C...
A univariate polynomial represented by its values on {domain_start, domain_start + 1,...
static void complete_proving_key_for_test(const std::shared_ptr< DeciderProvingKey_< Flavor > > &decider_pk)
TEST only method for completing computation of the prover polynomials using random challenges.
typename ECCVMFlavor::ProverPolynomials ProverPolynomials
std::vector< FF > betas
The challenges .
UltraKeccakFlavor::VerificationKey VerificationKey
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
std::vector< fr > HonkProof
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Tracks the cumulative usage of the execution trace across a series of circuits.
void update(const Builder &circuit)
Implementation of the methods for the -polynomials used in Protogalaxy and -polynomials used in Sumch...
Container for parameters used by the grand product (permutation, lookup) Honk relations.
static RelationParameters get_random()
static void add_default_to_public_inputs(Builder &builder)
Adds default public inputs to the builder.