Skip to content

Commit ba23cfd

Browse files
authored
feat: merge-train/barretenberg (#18823)
BEGIN_COMMIT_OVERRIDE fix: `accumulated_result` fully random (#18736) END_COMMIT_OVERRIDE
2 parents 1c68fb7 + c8c517a commit ba23cfd

File tree

37 files changed

+8842
-3482
lines changed

37 files changed

+8842
-3482
lines changed

barretenberg/cpp/scripts/test_chonk_standalone_vks_havent_changed.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ cd ..
1313
# - Generate a hash for versioning: sha256sum bb-chonk-inputs.tar.gz
1414
# - Upload the compressed results: aws s3 cp bb-chonk-inputs.tar.gz s3://aztec-ci-artifacts/protocol/bb-chonk-inputs-[hash(0:8)].tar.gz
1515
# Note: In case of the "Test suite failed to run ... Unexpected token 'with' " error, need to run: docker pull aztecprotocol/build:3.0
16-
pinned_short_hash="069bd3d2"
16+
pinned_short_hash="b3c2a68c"
1717
pinned_chonk_inputs_url="https://aztec-ci-artifacts.s3.us-east-2.amazonaws.com/protocol/bb-chonk-inputs-${pinned_short_hash}.tar.gz"
1818

1919
function compress_and_upload {

barretenberg/cpp/src/barretenberg/chonk/chonk.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "barretenberg/chonk/chonk.hpp"
88
#include "barretenberg/common/bb_bench.hpp"
99
#include "barretenberg/common/streams.hpp"
10+
#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp"
1011
#include "barretenberg/honk/prover_instance_inspector.hpp"
1112
#include "barretenberg/multilinear_batching/multilinear_batching_prover.hpp"
1213
#include "barretenberg/serialize/msgpack_impl.hpp"
@@ -143,8 +144,6 @@ Chonk::perform_recursive_verification_and_databus_consistency_checks(
143144
vinfo("Recursively verifying accumulation of the tail kernel.");
144145
BB_ASSERT_EQ(stdlib_verification_queue.size(), size_t(1));
145146

146-
hide_op_queue_accumulation_result(circuit);
147-
148147
auto [_first_verified, _second_verified, final_verifier_accumulator] =
149148
folding_verifier.verify_folding_proof(verifier_instance, verifier_inputs.proof);
150149

@@ -253,6 +252,9 @@ void Chonk::complete_kernel_circuit_logic(ClientCircuit& circuit)
253252
// Add randomness at the begining of the tail kernel (whose ecc ops fall at the beginning of the op queue table)
254253
// to ensure the CHONK proof doesn't leak information about the actual content of the op queue
255254
hide_op_queue_content_in_tail(circuit);
255+
256+
// Add the hiding op with random (non-curve) Px, Py values for statistical hiding of accumulated_result.
257+
hide_op_queue_accumulation_result(circuit);
256258
}
257259
circuit.queue_ecc_eq();
258260

@@ -447,23 +449,19 @@ void Chonk::accumulate(ClientCircuit& circuit, const std::shared_ptr<MegaVerific
447449
}
448450

449451
/**
450-
* @brief Add a valid operation with random data to the op queue to prevent information leakage in Translator
451-
* proof.
452+
* @brief Add a hiding op with fully random Px, Py field elements to prevent information leakage in Translator proof.
452453
*
453454
* @details The Translator circuit builder evaluates a batched polynomial (representing the four op queue polynomials
454455
* in UltraOp format) at a random challenge x. This evaluation result (called accumulated_result in translator) is
455456
* included in the translator proof and verified against the equivalent computation performed by ECCVM (in
456-
* verify_translation, establishing equivalence between ECCVM and UltraOp format). To ensure the accumulated_result
457-
* doesn't reveal information about actual ecc operations in the transaction, when the proof is sent to the rollup, we
458-
* add a random yet valid operation to the op queue. This guarantees the batched polynomial over Grumpkin contains at
459-
* least one random coefficient.
457+
* verify_translation, establishing equivalence between ECCVM and UltraOp format).
458+
*
460459
*/
461460
void Chonk::hide_op_queue_accumulation_result(ClientCircuit& circuit)
462461
{
463-
Point random_point = Point::random_element();
464-
FF random_scalar = FF::random_element();
465-
circuit.queue_ecc_mul_accum(random_point, random_scalar);
466-
circuit.queue_ecc_eq();
462+
// Use random Fq field elements as Px and Py.
463+
using Fq = curve::Grumpkin::ScalarField; // Same as BN254::BaseField
464+
circuit.queue_ecc_hiding_op(Fq::random_element(), Fq::random_element());
467465
}
468466

469467
/**

barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ template <class PCS> class ShpleminiRecursionTest : public CommitmentTest<typena
264264
if constexpr (std::is_same_v<Builder, MegaCircuitBuilder>) {
265265
validate_num_eccvm_rows(num_polys, num_shifted, short_scalars, &builder);
266266
if (prove_eccvm) {
267+
// Add hiding op for ECCVM ZK (prepended to ECCVM ops at row 1)
268+
using Fq = curve::Grumpkin::ScalarField;
269+
builder.queue_ecc_hiding_op(Fq::random_element(), Fq::random_element());
267270
builder.op_queue->merge();
268271
using clock = std::chrono::steady_clock;
269272
auto start_total = clock::now();

barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ inline constexpr std::tuple<size_t, size_t, size_t> HONK_RECURSION_CONSTANTS = [
8181
// ========================================
8282

8383
// Gate count for Chonk recursive verification (UltraRollup builder)
84-
inline constexpr size_t CHONK_RECURSION_GATES = 2494057;
84+
inline constexpr size_t CHONK_RECURSION_GATES = 2495208;
8585

8686
// ========================================
8787
// Hypernova Recursion Constants
@@ -103,11 +103,11 @@ inline constexpr size_t INNER_KERNEL_ULTRA_OPS = 179;
103103
// Tail kernel gate counts (verifies HN_TAIL proof)
104104
inline constexpr size_t TAIL_KERNEL_GATE_COUNT = 33968;
105105
inline constexpr size_t TAIL_KERNEL_ECC_ROWS = 914 + MSM_ROWS_OFFSET;
106-
inline constexpr size_t TAIL_KERNEL_ULTRA_OPS = 95;
106+
inline constexpr size_t TAIL_KERNEL_ULTRA_OPS = 96;
107107

108108
// Hiding kernel gate counts (verifies HN_FINAL proof)
109109
inline constexpr size_t HIDING_KERNEL_GATE_COUNT = 37212;
110-
inline constexpr size_t HIDING_KERNEL_ECC_ROWS = 1405 + MSM_ROWS_OFFSET;
111-
inline constexpr size_t HIDING_KERNEL_ULTRA_OPS = 126;
110+
inline constexpr size_t HIDING_KERNEL_ECC_ROWS = 1341 + MSM_ROWS_OFFSET;
111+
inline constexpr size_t HIDING_KERNEL_ULTRA_OPS = 124;
112112

113113
} // namespace acir_format

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ TEST(MockVerifierInputsTest, MockMergeProofSize)
5050
*/
5151
TEST(MockVerifierInputsTest, MockPreIpaProofSize)
5252
{
53-
size_t CURRENT_ECCVM_PROOF_SIZE = 606;
53+
size_t CURRENT_ECCVM_PROOF_SIZE = 608;
5454
EXPECT_EQ(ECCVMFlavor::PROOF_LENGTH_WITHOUT_PUB_INPUTS, CURRENT_ECCVM_PROOF_SIZE)
5555
<< "The length of the Pre-IPA proof changed.";
5656

@@ -244,7 +244,7 @@ TEST(MockVerifierInputsTest, MockChonkProofSize)
244244

245245
// If this value changes, we need to update the corresponding constants in noir and in yarn-project. Also, we need
246246
// to update the Prover.toml file for rollup-tx-private to reflect the new length of the Chonk proof.
247-
size_t CURRENT_CHONK_PROOF_SIZE_WITHOUT_PUB_INPUTS = 1905;
247+
size_t CURRENT_CHONK_PROOF_SIZE_WITHOUT_PUB_INPUTS = 1907;
248248
HonkProof chonk_proof = create_mock_chonk_proof<Builder>();
249249
EXPECT_EQ(chonk_proof.size(), Chonk::Proof::PROOF_LENGTH());
250250
EXPECT_EQ(chonk_proof.size(),

barretenberg/cpp/src/barretenberg/eccvm/eccvm.test.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,20 @@ class ECCVMTests : public ::testing::Test {
2929
};
3030
namespace {
3131
auto& engine = numeric::get_debug_randomness();
32+
33+
/**
34+
* @brief Add a hiding op to the op_queue for testing.
35+
* @details The ECCVM relation constraints expect q_eq = 1 at row 1 (lagrange_second).
36+
* In production (Chonk flow), a hiding op with random Px, Py is prepended for statistical hiding.
37+
* For tests, we also use random values to match production behavior.
38+
*/
39+
void add_hiding_op_for_test(const std::shared_ptr<ECCOpQueue>& op_queue)
40+
{
41+
using Fq = curve::BN254::BaseField;
42+
// Prepend a hiding op with random coordinates - provides statistical hiding
43+
op_queue->append_hiding_op(Fq::random_element(), Fq::random_element());
3244
}
45+
} // namespace
3346

3447
/**
3548
* @brief Adds operations in BN254 to the op_queue and then constructs and ECCVM circuit from the op_queue.
@@ -65,6 +78,7 @@ ECCVMCircuitBuilder generate_circuit(numeric::RNG* engine = nullptr)
6578
op_queue->mul_accumulate(b, x);
6679
op_queue->mul_accumulate(c, x);
6780
op_queue->merge();
81+
add_hiding_op_for_test(op_queue);
6882
ECCVMCircuitBuilder builder{ op_queue };
6983
return builder;
7084
}
@@ -91,6 +105,7 @@ ECCVMCircuitBuilder generate_zero_circuit([[maybe_unused]] numeric::RNG* engine
91105
}
92106
}
93107
op_queue->merge();
108+
add_hiding_op_for_test(op_queue);
94109

95110
ECCVMCircuitBuilder builder{ op_queue };
96111
return builder;
@@ -186,6 +201,7 @@ TEST_F(ECCVMTests, ScalarEdgeCase)
186201
op_queue->mul_accumulate(a, Fr(uint256_t(1) << 128));
187202
op_queue->eq_and_reset();
188203
op_queue->merge();
204+
add_hiding_op_for_test(op_queue);
189205
ECCVMCircuitBuilder builder{ op_queue };
190206

191207
std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();

barretenberg/cpp/src/barretenberg/eccvm/eccvm_circuit_builder.test.cpp

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@ using Fr = typename G1::Fr;
1010

1111
namespace {
1212
auto& engine = numeric::get_debug_randomness();
13+
14+
/**
15+
* @brief Add a hiding op with random Px, Py to the op_queue for testing.
16+
* @details The ECCVM relation constraints expect q_eq = 1 at row 1 (lagrange_second).
17+
* This mirrors production behavior where random field elements are used for statistical hiding.
18+
*/
19+
void add_hiding_op_for_test(const std::shared_ptr<ECCOpQueue>& op_queue)
20+
{
21+
using Fq = curve::BN254::BaseField;
22+
// Prepend an eq op with random coordinates - same as production
23+
op_queue->append_hiding_op(Fq::random_element(), Fq::random_element());
24+
}
1325
} // namespace
1426

1527
TEST(ECCVMCircuitBuilderTests, BaseCase)
@@ -63,6 +75,7 @@ TEST(ECCVMCircuitBuilderTests, BaseCase)
6375
op_queue->add_accumulate(a);
6476
op_queue->eq_and_reset();
6577
op_queue->merge();
78+
add_hiding_op_for_test(op_queue);
6679
ECCVMCircuitBuilder circuit{ op_queue };
6780
bool result = ECCVMTraceChecker::check(circuit);
6881
EXPECT_EQ(result, true);
@@ -71,6 +84,7 @@ TEST(ECCVMCircuitBuilderTests, BaseCase)
7184
TEST(ECCVMCircuitBuilderTests, NoOp)
7285
{
7386
std::shared_ptr<ECCOpQueue> op_queue = std::make_shared<ECCOpQueue>();
87+
add_hiding_op_for_test(op_queue);
7488

7589
ECCVMCircuitBuilder circuit{ op_queue };
7690
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -86,6 +100,7 @@ TEST(ECCVMCircuitBuilderTests, Add)
86100

87101
op_queue->add_accumulate(a);
88102
op_queue->merge();
103+
add_hiding_op_for_test(op_queue);
89104

90105
ECCVMCircuitBuilder circuit{ op_queue };
91106
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -102,6 +117,7 @@ TEST(ECCVMCircuitBuilderTests, Mul)
102117

103118
op_queue->mul_accumulate(a, x);
104119
op_queue->merge();
120+
add_hiding_op_for_test(op_queue);
105121

106122
ECCVMCircuitBuilder circuit{ op_queue };
107123
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -121,6 +137,7 @@ TEST(ECCVMCircuitBuilderTests, MulInfinity)
121137
op_queue->mul_accumulate(a, x);
122138
op_queue->eq_and_reset();
123139
op_queue->merge();
140+
add_hiding_op_for_test(op_queue);
124141

125142
ECCVMCircuitBuilder circuit{ op_queue };
126143
bool result = ECCVMTraceChecker::check(circuit);
@@ -139,6 +156,7 @@ TEST(ECCVMCircuitBuilderTests, MulOverIdenticalInputs)
139156
op_queue->mul_accumulate(a, x);
140157
op_queue->eq_and_reset();
141158
op_queue->merge();
159+
add_hiding_op_for_test(op_queue);
142160

143161
ECCVMCircuitBuilder circuit{ op_queue };
144162
bool result = ECCVMTraceChecker::check(circuit);
@@ -157,6 +175,7 @@ TEST(ECCVMCircuitBuilderTests, MSMProducesInfinity)
157175
op_queue->mul_accumulate(a, -x);
158176
op_queue->eq_and_reset();
159177
op_queue->merge();
178+
add_hiding_op_for_test(op_queue);
160179

161180
ECCVMCircuitBuilder circuit{ op_queue };
162181
bool result = ECCVMTraceChecker::check(circuit);
@@ -179,6 +198,7 @@ TEST(ECCVMCircuitBuilderTests, MSMOverPointAtInfinity)
179198
op_queue->mul_accumulate(point_at_infinity, x);
180199
op_queue->eq_and_reset();
181200
op_queue->merge();
201+
add_hiding_op_for_test(op_queue);
182202

183203
ECCVMCircuitBuilder circuit{ op_queue };
184204
bool result = ECCVMTraceChecker::check(circuit);
@@ -243,6 +263,7 @@ TEST(ECCVMCircuitBuilderTests, ShortMul)
243263
op_queue->mul_accumulate(a, x);
244264
op_queue->eq_and_reset();
245265
op_queue->merge();
266+
add_hiding_op_for_test(op_queue);
246267

247268
ECCVMCircuitBuilder circuit{ op_queue };
248269
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -261,6 +282,7 @@ TEST(ECCVMCircuitBuilderTests, EqFails)
261282
// Tamper with the eq op such that the expected value is incorect
262283
op_queue->add_erroneous_equality_op_for_testing();
263284
op_queue->merge();
285+
add_hiding_op_for_test(op_queue);
264286

265287
ECCVMCircuitBuilder circuit{ op_queue };
266288
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -273,6 +295,7 @@ TEST(ECCVMCircuitBuilderTests, EmptyRow)
273295

274296
op_queue->empty_row_for_testing();
275297
op_queue->merge();
298+
add_hiding_op_for_test(op_queue);
276299

277300
ECCVMCircuitBuilder circuit{ op_queue };
278301
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -291,6 +314,7 @@ TEST(ECCVMCircuitBuilderTests, EmptyRowBetweenOps)
291314
op_queue->empty_row_for_testing();
292315
op_queue->eq_and_reset();
293316
op_queue->merge();
317+
add_hiding_op_for_test(op_queue);
294318

295319
ECCVMCircuitBuilder circuit{ op_queue };
296320
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -308,6 +332,7 @@ TEST(ECCVMCircuitBuilderTests, EndWithEq)
308332
op_queue->mul_accumulate(a, x);
309333
op_queue->eq_and_reset();
310334
op_queue->merge();
335+
add_hiding_op_for_test(op_queue);
311336

312337
ECCVMCircuitBuilder circuit{ op_queue };
313338
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -326,6 +351,7 @@ TEST(ECCVMCircuitBuilderTests, EndWithAdd)
326351
op_queue->eq_and_reset();
327352
op_queue->add_accumulate(a);
328353
op_queue->merge();
354+
add_hiding_op_for_test(op_queue);
329355

330356
ECCVMCircuitBuilder circuit{ op_queue };
331357
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -344,6 +370,7 @@ TEST(ECCVMCircuitBuilderTests, EndWithMul)
344370
op_queue->eq_and_reset();
345371
op_queue->mul_accumulate(a, x);
346372
op_queue->merge();
373+
add_hiding_op_for_test(op_queue);
347374

348375
ECCVMCircuitBuilder circuit{ op_queue };
349376
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -364,6 +391,7 @@ TEST(ECCVMCircuitBuilderTests, EndWithNoop)
364391

365392
op_queue->empty_row_for_testing();
366393
op_queue->merge();
394+
add_hiding_op_for_test(op_queue);
367395

368396
ECCVMCircuitBuilder circuit{ op_queue };
369397
bool result = ECCVMTraceChecker::check(circuit, &engine);
@@ -394,6 +422,7 @@ TEST(ECCVMCircuitBuilderTests, MSM)
394422
std::shared_ptr<ECCOpQueue> op_queue = std::make_shared<ECCOpQueue>();
395423

396424
compute_msms(j, op_queue);
425+
add_hiding_op_for_test(op_queue);
397426
ECCVMCircuitBuilder circuit{ op_queue };
398427
bool result = ECCVMTraceChecker::check(circuit);
399428
EXPECT_EQ(result, true);
@@ -404,6 +433,7 @@ TEST(ECCVMCircuitBuilderTests, MSM)
404433
for (size_t j = 1; j < 9; ++j) {
405434
compute_msms(j, op_queue);
406435
}
436+
add_hiding_op_for_test(op_queue);
407437
ECCVMCircuitBuilder circuit{ op_queue };
408438
bool result = ECCVMTraceChecker::check(circuit, &engine);
409439
EXPECT_EQ(result, true);
@@ -420,6 +450,7 @@ TEST(ECCVMCircuitBuilderTests, EqAgainstPointAtInfinity)
420450
op_queue->add_accumulate(a);
421451
op_queue->eq_and_reset();
422452
op_queue->merge();
453+
add_hiding_op_for_test(op_queue);
423454

424455
ECCVMCircuitBuilder circuit{ op_queue };
425456
bool result = ECCVMTraceChecker::check(circuit);
@@ -439,6 +470,7 @@ TEST(ECCVMCircuitBuilderTests, AddPointAtInfinity)
439470
op_queue->add_accumulate(b);
440471
op_queue->eq_and_reset();
441472
op_queue->merge();
473+
add_hiding_op_for_test(op_queue);
442474

443475
ECCVMCircuitBuilder circuit{ op_queue };
444476
bool result = ECCVMTraceChecker::check(circuit);
@@ -456,6 +488,7 @@ TEST(ECCVMCircuitBuilderTests, AddProducesPointAtInfinity)
456488
op_queue->add_accumulate(-a);
457489
op_queue->eq_and_reset();
458490
op_queue->merge();
491+
add_hiding_op_for_test(op_queue);
459492

460493
ECCVMCircuitBuilder circuit{ op_queue };
461494
bool result = ECCVMTraceChecker::check(circuit);
@@ -473,6 +506,7 @@ TEST(ECCVMCircuitBuilderTests, AddProducesDouble)
473506
op_queue->add_accumulate(a);
474507
op_queue->eq_and_reset();
475508
op_queue->merge();
509+
add_hiding_op_for_test(op_queue);
476510

477511
ECCVMCircuitBuilder circuit{ op_queue };
478512
bool result = ECCVMTraceChecker::check(circuit);
@@ -510,15 +544,17 @@ TEST(ECCVMCircuitBuilderTests, InfinityFailure)
510544
op_queue->mul_accumulate(P1, Fr(0));
511545
}
512546
op_queue->merge();
547+
add_hiding_op_for_test(op_queue);
513548

514549
auto eccvm_builder = ECCVMCircuitBuilder(op_queue);
515550

551+
// Note: With the hiding op at index 0, the mul op is at index 1, so we check row 2
516552
auto transcript_rows = ECCVMTranscriptBuilder::compute_rows(op_queue->get_eccvm_ops(), 1);
517553

518-
// check that the corresponding op is mul
519-
bool row_op_code_correct = transcript_rows[1].opcode == 4;
554+
// check that the corresponding op is mul (now at row 2 due to hiding op at row 1)
555+
bool row_op_code_correct = transcript_rows[2].opcode == 4;
520556
// row.base_x populate the transcript polynomial transcript_Px in ECCVM Flavor
521-
bool failure = Fr(transcript_rows[1].base_x) == Fr(0);
557+
bool failure = Fr(transcript_rows[2].base_x) == Fr(0);
522558

523559
bool circuit_checked = ECCVMTraceChecker::check(eccvm_builder);
524560

@@ -541,6 +577,7 @@ TEST(ECCVMCircuitBuilderTests, ScalarEdgeCase)
541577
op_queue->mul_accumulate(a, two_to_the_128);
542578

543579
op_queue->merge();
580+
add_hiding_op_for_test(op_queue);
544581

545582
ECCVMCircuitBuilder circuit{ op_queue };
546583
bool result = ECCVMTraceChecker::check(circuit, &engine);

0 commit comments

Comments
 (0)