@@ -25,16 +25,55 @@ class GoblinRecursiveVerifierTests : public testing::Test {
25
25
using RecursiveCommitment = GoblinRecursiveVerifier::MergeVerifier::Commitment;
26
26
using MergeCommitments = MergeVerifier::InputCommitments;
27
27
using RecursiveMergeCommitments = GoblinRecursiveVerifier::MergeVerifier::InputCommitments;
28
-
28
+ using FF = TranslatorFlavor::FF;
29
+ using BF = TranslatorFlavor::BF;
29
30
static void SetUpTestSuite () { bb::srs::init_file_crs_factory (bb::srs::bb_crs_path ()); }
30
31
32
+ // Compute the size of a Translator commitment (in bb::fr's)
33
+ static constexpr size_t comm_frs = bb::field_conversion::calc_num_bn254_frs<Commitment>(); // 4
34
+ static constexpr size_t eval_frs = bb::field_conversion::calc_num_bn254_frs<FF>(); // 1
35
+
36
+ // The `op` wire commitment is currently the second element of the proof, following the
37
+ // `accumulated_result` which is a BN254 BaseField element.
38
+ static constexpr size_t offset = bb::field_conversion::calc_num_bn254_frs<BF>();
39
+
31
40
struct ProverOutput {
32
41
GoblinProof proof;
33
42
Goblin::VerificationKey verifier_input;
34
43
MergeCommitments merge_commitments;
35
44
RecursiveMergeCommitments recursive_merge_commitments;
36
45
};
46
+ // TODO(https://github.com/AztecProtocol/barretenberg/issues/1298):
47
+ // Better recursion testing - create more flexible proof tampering tests.
48
+ // Modify the `op` commitment which a part of the Merge protocol.
49
+ static void tamper_with_op_commitment (HonkProof& translator_proof)
50
+ {
51
+
52
+ // Extract `op` fields and convert them to a Commitment object
53
+ auto element_frs = std::span{ translator_proof }.subspan (offset, comm_frs);
54
+ auto op_commitment = NativeTranscriptParams::template deserialize<Commitment>(element_frs);
55
+ // Modify the commitment
56
+ op_commitment = op_commitment * FF (2 );
57
+ // Serialize the tampered commitment into the proof (overwriting the valid one).
58
+ auto op_commitment_reserialized = bb::NativeTranscriptParams::serialize (op_commitment);
59
+ std::copy (op_commitment_reserialized.begin (),
60
+ op_commitment_reserialized.end (),
61
+ translator_proof.begin () + static_cast <std::ptrdiff_t >(offset));
62
+ };
63
+
64
+ // Translator proof ends with [..., Libra:quotient_eval, Shplonk:Q, KZG:W]. We invalidate the proof by multiplying
65
+ // the eval by 2 (it leads to a Libra consistency check failure).
66
+ static void tamper_with_libra_eval (HonkProof& translator_proof)
67
+ {
68
+ // Proof tail size
69
+ static constexpr size_t tail_size = 2 * comm_frs + eval_frs; // 2*4 + 1 = 9
70
+
71
+ // Index of the target field (one fr) from the beginning
72
+ const size_t idx = translator_proof.size () - tail_size;
37
73
74
+ // Tamper: multiply by 2 (or tweak however you like)
75
+ translator_proof[idx] = translator_proof[idx] + translator_proof[idx];
76
+ };
38
77
/* *
39
78
* @brief Create a goblin proof and the VM verification keys needed by the goblin recursive verifier
40
79
*
@@ -208,13 +247,7 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorFailure)
208
247
// Tamper with the Translator proof preamble
209
248
{
210
249
GoblinProof tampered_proof = proof;
211
- for (auto & val : tampered_proof.translator_proof ) {
212
- if (val > 0 ) { // tamper by finding the first non-zero value and incrementing it by 1
213
- val += 1 ;
214
- break ;
215
- }
216
- }
217
-
250
+ tamper_with_op_commitment (tampered_proof.translator_proof );
218
251
Builder builder;
219
252
220
253
RecursiveMergeCommitments recursive_merge_commitments;
@@ -232,18 +265,10 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorFailure)
232
265
verifier.verify (tampered_proof, recursive_merge_commitments, MergeSettings::APPEND);
233
266
EXPECT_FALSE (CircuitChecker::check (builder));
234
267
}
235
- // Tamper with the Translator proof non- preamble values
268
+ // Tamper with the Translator proof non - preamble values
236
269
{
237
270
auto tampered_proof = proof;
238
- int seek = 10 ;
239
- for (auto & val : tampered_proof.translator_proof ) {
240
- if (val > 0 ) { // tamper by finding the tenth non-zero value and incrementing it by 1
241
- if (--seek == 0 ) {
242
- val += 1 ;
243
- break ;
244
- }
245
- }
246
- }
271
+ tamper_with_libra_eval (tampered_proof.translator_proof );
247
272
248
273
Builder builder;
249
274
@@ -296,9 +321,6 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorMergeConsistencyFailure)
296
321
{
297
322
298
323
{
299
- using Commitment = TranslatorFlavor::Commitment;
300
- using FF = TranslatorFlavor::FF;
301
- using BF = TranslatorFlavor::BF;
302
324
303
325
Builder builder;
304
326
@@ -310,27 +332,6 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorMergeConsistencyFailure)
310
332
// Check natively that the proof is correct.
311
333
EXPECT_TRUE (Goblin::verify (proof, merge_commitments, verifier_transcript, MergeSettings::APPEND));
312
334
313
- // TODO(https://github.com/AztecProtocol/barretenberg/issues/1298):
314
- // Better recursion testing - create more flexible proof tampering tests.
315
- // Modify the `op` commitment which a part of the Merge protocol.
316
- auto tamper_with_op_commitment = [](HonkProof& translator_proof) {
317
- // Compute the size of a Translator commitment (in bb::fr's)
318
- static constexpr size_t num_frs_comm = bb::field_conversion::calc_num_bn254_frs<Commitment>();
319
- // The `op` wire commitment is currently the second element of the proof, following the
320
- // `accumulated_result` which is a BN254 BaseField element.
321
- static constexpr size_t offset = bb::field_conversion::calc_num_bn254_frs<BF>();
322
- // Extract `op` fields and convert them to a Commitment object
323
- auto element_frs = std::span{ translator_proof }.subspan (offset, num_frs_comm);
324
- auto op_commitment = NativeTranscriptParams::template deserialize<Commitment>(element_frs);
325
- // Modify the commitment
326
- op_commitment = op_commitment * FF (2 );
327
- // Serialize the tampered commitment into the proof (overwriting the valid one).
328
- auto op_commitment_reserialized = bb::NativeTranscriptParams::serialize (op_commitment);
329
- std::copy (op_commitment_reserialized.begin (),
330
- op_commitment_reserialized.end (),
331
- translator_proof.begin () + static_cast <std::ptrdiff_t >(offset));
332
- };
333
-
334
335
tamper_with_op_commitment (proof.translator_proof );
335
336
// Construct and check the Goblin Recursive Verifier circuit
336
337
0 commit comments