@@ -10,6 +10,18 @@ using Fr = typename G1::Fr;
1010
1111namespace {
1212auto & 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
1527TEST (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)
7184TEST (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