Skip to content

Commit cd529f9

Browse files
authored
fix: set gate challenges in initial accumulator (#16613)
Fixes the bug exploiting the initial gate_challenges being 0 demonstrated here: https://github.com/AztecProtocol/aztec-packages/pull/16593/files. Closes AztecProtocol/barretenberg#1531. Sets the gate challenges in the initial accumulator with a challenge rather than being all 0s. Also makes gate challenges generate from 1 challenge to reduce the amount of hashing. Adds some functionality to transcript to aid this.
1 parent 772076e commit cd529f9

19 files changed

+93
-88
lines changed

barretenberg/cpp/scripts/test_civc_standalone_vks_havent_changed.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ cd ..
1111
# - Generate a hash for versioning: sha256sum bb-civc-inputs.tar.gz
1212
# - Upload the compressed results: aws s3 cp bb-civc-inputs.tar.gz s3://aztec-ci-artifacts/protocol/bb-civc-inputs-[hash(0:8)].tar.gz
1313
# Note: In case of the "Test suite failed to run ... Unexpected token 'with' " error, need to run: docker pull aztecprotocol/build:3.0
14-
pinned_short_hash="197c2f73"
14+
pinned_short_hash="8657fa15"
1515
pinned_civc_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-civc-inputs-${pinned_short_hash}.tar.gz"
1616

1717
function compress_and_upload {

barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,11 @@ ClientIVC::perform_recursive_verification_and_databus_consistency_checks(
128128

129129
output_stdlib_verifier_accumulator = verifier_instance;
130130
output_stdlib_verifier_accumulator->target_sum = StdlibFF::from_witness_index(&circuit, circuit.zero_idx);
131-
output_stdlib_verifier_accumulator->gate_challenges.assign(
132-
CONST_PG_LOG_N, StdlibFF::from_witness_index(&circuit, circuit.zero_idx));
133131

132+
// Get the gate challenges for sumcheck/combiner computation
133+
output_stdlib_verifier_accumulator->gate_challenges =
134+
accumulation_recursive_transcript->template get_powers_of_challenge<StdlibFF>("gate_challenge",
135+
CONST_PG_LOG_N);
134136
// T_prev = 0 in the first recursive verification
135137
merge_commitments.T_prev_commitments = stdlib::recursion::honk::empty_ecc_op_tables(circuit);
136138

@@ -373,7 +375,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVer
373375
BB_ASSERT_LT(
374376
num_circuits_accumulated, num_circuits, "ClientIVC: Attempting to accumulate more circuits than expected.");
375377

376-
ASSERT(precomputed_vk != nullptr, "ClientIVC::acumulate - VK expected for the provided circuit");
378+
ASSERT(precomputed_vk != nullptr, "ClientIVC::accumulate - VK expected for the provided circuit");
377379

378380
// Construct the proving key for circuit
379381
std::shared_ptr<DeciderProvingKey> proving_key = std::make_shared<DeciderProvingKey>(circuit, trace_settings);
@@ -412,6 +414,10 @@ void ClientIVC::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVer
412414
MegaOinkProver oink_prover{ proving_key, honk_vk, prover_accumulation_transcript };
413415
vinfo("computing oink proof...");
414416
oink_prover.prove();
417+
proving_key->target_sum = 0;
418+
// Get the gate challenges for sumcheck/combiner computation
419+
proving_key->gate_challenges =
420+
prover_accumulation_transcript->template get_powers_of_challenge<FF>("gate_challenge", CONST_PG_LOG_N);
415421
HonkProof oink_proof = oink_prover.export_proof();
416422
vinfo("oink proof constructed");
417423

@@ -706,7 +712,10 @@ void ClientIVC::update_native_verifier_accumulator(const VerifierInputs& queue_e
706712
OinkVerifier<Flavor> oink_verifier{ decider_vk, verifier_transcript };
707713
oink_verifier.verify();
708714
native_verifier_accum = decider_vk;
709-
native_verifier_accum->gate_challenges = std::vector<FF>(CONST_PG_LOG_N, 0);
715+
native_verifier_accum->target_sum = 0;
716+
// Get the gate challenges for sumcheck/combiner computation
717+
native_verifier_accum->gate_challenges =
718+
verifier_transcript->template get_powers_of_challenge<FF>("gate_challenge", CONST_PG_LOG_N);
710719
} else {
711720
if (queue_entry.is_kernel) {
712721
// Fiat-Shamir the verifier accumulator

barretenberg/cpp/src/barretenberg/dsl/acir_format/mock_verifier_inputs.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,8 @@ template <typename Flavor> std::shared_ptr<DeciderVerificationKey_<Flavor>> crea
453453
0, 0); // metadata does not need to be accurate
454454
decider_verification_key->vk = vk;
455455
decider_verification_key->is_complete = true;
456-
decider_verification_key->gate_challenges = std::vector<FF>(static_cast<size_t>(CONST_PG_LOG_N), 0);
456+
decider_verification_key->gate_challenges =
457+
std::vector<FF>(static_cast<size_t>(CONST_PG_LOG_N), FF::random_element());
457458

458459
for (auto& commitment : decider_verification_key->witness_commitments.get_all()) {
459460
commitment = curve::BN254::AffineElement::one(); // arbitrary mock commitment

barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy.test.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,10 @@ template <typename Flavor> class ProtogalaxyTests : public testing::Test {
206206
accumulator->relation_parameters = relation_parameters;
207207
accumulator->alphas = alphas;
208208

209-
auto deltas = compute_round_challenge_pows(log_size, FF::random_element());
209+
std::vector<FF> deltas(log_size);
210+
for (size_t idx = 0; idx < log_size; idx++) {
211+
deltas[idx] = FF::random_element();
212+
}
210213
auto perturbator = pg_internal.compute_perturbator(accumulator, deltas);
211214

212215
// Ensure the constant coefficient of the perturbator is equal to the target sum as indicated by the paper

barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ void ProtogalaxyProver_<Flavor, NUM_KEYS>::run_oink_prover_on_each_incomplete_ke
3535
auto& verifier_accum = vks_to_fold[0];
3636
if (!key->is_complete) {
3737
run_oink_prover_on_one_incomplete_key(key, verifier_accum, domain_separator);
38+
// Get the gate challenges for sumcheck/combiner computation
39+
key->gate_challenges =
40+
transcript->template get_powers_of_challenge<FF>(domain_separator + "_gate_challenge", CONST_PG_LOG_N);
3841
}
3942

4043
idx++;
@@ -54,10 +57,9 @@ std::tuple<std::vector<typename Flavor::FF>, Polynomial<typename Flavor::FF>> Pr
5457
{
5558
PROFILE_THIS_NAME("ProtogalaxyProver_::perturbator_round");
5659

57-
const FF delta = transcript->template get_challenge<FF>("delta");
58-
const std::vector<FF> deltas = compute_round_challenge_pows(CONST_PG_LOG_N, delta);
60+
const std::vector<FF> deltas = transcript->template get_powers_of_challenge<FF>("delta", CONST_PG_LOG_N);
5961
// An honest prover with valid initial key computes that the perturbator is 0 in the first round
60-
const Polynomial<FF> perturbator = accumulator->is_accumulator
62+
const Polynomial<FF> perturbator = accumulator->from_first_instance
6163
? pg_internal.compute_perturbator(accumulator, deltas)
6264
: Polynomial<FF>(CONST_PG_LOG_N + 1);
6365
// Prover doesn't send the constant coefficient of F because this is supposed to be equal to the target sum of
@@ -122,7 +124,7 @@ void ProtogalaxyProver_<Flavor, NUM_KEYS>::update_target_sum_and_fold(
122124

123125
std::shared_ptr<DeciderPK> accumulator = keys[0];
124126
std::shared_ptr<DeciderPK> incoming = keys[1];
125-
accumulator->is_accumulator = true;
127+
accumulator->from_first_instance = true;
126128

127129
// At this point the virtual sizes of the polynomials should already agree
128130
BB_ASSERT_EQ(accumulator->polynomials.w_l.virtual_size(), incoming->polynomials.w_l.virtual_size());

barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ void ProtogalaxyVerifier_<DeciderVerificationKeys>::run_oink_verifier_on_each_in
2222
if (!key->is_complete) {
2323
OinkVerifier<Flavor> oink_verifier{ key, transcript, domain_separator + '_' };
2424
oink_verifier.verify();
25-
key->gate_challenges = std::vector<FF>(CONST_PG_LOG_N, 0);
25+
key->target_sum = 0;
26+
// Get the gate challenges for sumcheck/combiner computation
27+
key->gate_challenges =
28+
transcript->template get_powers_of_challenge<FF>(domain_separator + "_gate_challenge", CONST_PG_LOG_N);
2629
}
2730

2831
key = keys_to_fold[1];
@@ -76,8 +79,8 @@ std::shared_ptr<typename DeciderVerificationKeys::DeciderVK> ProtogalaxyVerifier
7679
run_oink_verifier_on_each_incomplete_key(proof);
7780

7881
// Perturbator round
79-
const FF delta = transcript->template get_challenge<FF>("delta");
80-
const std::vector<FF> deltas = compute_round_challenge_pows(CONST_PG_LOG_N, delta);
82+
const std::vector<FF> deltas = transcript->template get_powers_of_challenge<FF>("delta", CONST_PG_LOG_N);
83+
8184
std::vector<FF> perturbator_coeffs(CONST_PG_LOG_N + 1, 0);
8285
for (size_t idx = 1; idx <= CONST_PG_LOG_N; idx++) {
8386
perturbator_coeffs[idx] = transcript->template receive_from_prover<FF>("perturbator_" + std::to_string(idx));

barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.hpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ std::vector<FF> update_gate_challenges(const FF& perturbator_challenge,
1717
const std::vector<FF>& gate_challenges,
1818
const std::vector<FF>& init_challenges)
1919
{
20+
BB_ASSERT_EQ(
21+
gate_challenges.size(), init_challenges.size(), "gate_challenges and init_challenges must have same size");
2022
const size_t num_challenges = gate_challenges.size();
2123
std::vector<FF> next_gate_challenges(num_challenges);
2224

@@ -25,19 +27,6 @@ std::vector<FF> update_gate_challenges(const FF& perturbator_challenge,
2527
}
2628
return next_gate_challenges;
2729
}
28-
/**
29-
* @brief Given δ, compute the vector [δ, δ^2,..., δ^num_powers].
30-
* @details This is Step 2 of the protocol as written in the paper.
31-
*/
32-
template <typename FF> std::vector<FF> compute_round_challenge_pows(const size_t num_powers, const FF& round_challenge)
33-
{
34-
std::vector<FF> pows(num_powers);
35-
pows[0] = round_challenge;
36-
for (size_t i = 1; i < num_powers; i++) {
37-
pows[i] = pows[i - 1].sqr();
38-
}
39-
return pows;
40-
}
4130

4231
/**
4332
* @brief Evaluates the perturbator at a given scalar, in a sequential manner for the recursive setting.

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_
7070

7171
VerifierCommitments commitments{ key->vk_and_hash->vk, key->witness_commitments };
7272
static constexpr size_t VIRTUAL_LOG_N = Flavor::NativeFlavor::VIRTUAL_LOG_N;
73-
auto gate_challenges = std::vector<FF>(VIRTUAL_LOG_N);
74-
for (size_t idx = 0; idx < VIRTUAL_LOG_N; idx++) {
75-
gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
76-
}
73+
// Get the gate challenges for sumcheck computation
74+
key->gate_challenges = transcript->template get_powers_of_challenge<FF>("Sumcheck:gate_challenge", VIRTUAL_LOG_N);
7775

7876
// Execute Sumcheck Verifier and extract multivariate opening point u = (u_0, ..., u_{d-1}) and purported
7977
// multivariate evaluations at u
@@ -95,7 +93,7 @@ UltraRecursiveVerifier_<Flavor>::Output UltraRecursiveVerifier_<Flavor>::verify_
9593
libra_commitments[0] = transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
9694
}
9795
SumcheckOutput<Flavor> sumcheck_output =
98-
sumcheck.verify(key->relation_parameters, gate_challenges, padding_indicator_array);
96+
sumcheck.verify(key->relation_parameters, key->gate_challenges, padding_indicator_array);
9997

10098
// For MegaZKFlavor: the sumcheck output contains claimed evaluations of the Libra polynomials
10199
if constexpr (Flavor::HasZK) {

barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ template <typename RecursiveFlavor> class RecursiveVerifierTest : public testing
291291
}
292292
// Check the size of the recursive verifier
293293
if constexpr (std::same_as<RecursiveFlavor, MegaZKRecursiveFlavor_<UltraCircuitBuilder>>) {
294-
uint32_t NUM_GATES_EXPECTED = 799269;
294+
uint32_t NUM_GATES_EXPECTED = 797234;
295295
ASSERT_EQ(static_cast<uint32_t>(outer_circuit.get_num_finalized_gates()), NUM_GATES_EXPECTED)
296296
<< "MegaZKHonk Recursive verifier changed in Ultra gate count! Update this value if you "
297297
"are sure this is expected.";

barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ void ProtogalaxyRecursiveVerifier_<DeciderVerificationKeys>::run_oink_verifier_o
2424
if (!key->is_complete) {
2525
OinkRecursiveVerifier_<Flavor> oink_verifier{ builder, key, transcript, domain_separator + '_' };
2626
oink_verifier.verify();
27-
key->gate_challenges = std::vector<FF>(CONST_PG_LOG_N, 0);
27+
key->target_sum = FF::from_witness(builder, builder->zero_idx);
28+
// Get the gate challenges for sumcheck/combiner computation
29+
key->gate_challenges =
30+
transcript->template get_powers_of_challenge<FF>(domain_separator + "_gate_challenge", CONST_PG_LOG_N);
2831
}
2932

3033
key = keys_to_fold[1];
@@ -48,8 +51,7 @@ std::shared_ptr<typename DeciderVerificationKeys::DeciderVK> ProtogalaxyRecursiv
4851
const std::shared_ptr<DeciderVK>& accumulator = keys_to_fold[0];
4952

5053
// Perturbator round
51-
const FF delta = transcript->template get_challenge<FF>("delta");
52-
const std::vector<FF> deltas = compute_round_challenge_pows(CONST_PG_LOG_N, delta);
54+
const std::vector<FF> deltas = transcript->template get_powers_of_challenge<FF>("delta", CONST_PG_LOG_N);
5355
std::vector<FF> perturbator_coeffs(CONST_PG_LOG_N + 1, 0);
5456
for (size_t idx = 1; idx <= CONST_PG_LOG_N; idx++) {
5557
perturbator_coeffs[idx] = transcript->template receive_from_prover<FF>("perturbator_" + std::to_string(idx));

0 commit comments

Comments
 (0)