Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_transcript_relation_impl.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8#include <array>
9#include <tuple>
10
14
15namespace bb {
38template <typename FF>
39template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
40void ECCVMTranscriptRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator,
41 const AllEntities& in,
42 const Parameters& /*unused*/,
43 const FF& scaling_factor)
44{
45 using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>;
46 using View = typename Accumulator::View;
47
48 static const auto offset_generator = [&]() {
49 static constexpr auto offset_generator_base = get_precomputed_generators<g1, "ECCVM_OFFSET_GENERATOR", 1>()[0];
50 static bb::g1::affine_element result =
51 bb::g1::affine_element(bb::g1::element(offset_generator_base) * grumpkin::fq(uint256_t(1) << 124));
52 static const FF qx = result.x;
53 static const FF qy = result.y;
54 static const Accumulator ox(qx);
55 static const Accumulator oy(qy);
56 return std::array<Accumulator, 2>{ ox, oy };
57 };
58 const auto z1 = View(in.transcript_z1);
59 const auto z2 = View(in.transcript_z2);
60 const auto z1_zero = View(in.transcript_z1zero);
61 const auto z2_zero = View(in.transcript_z2zero);
62 const auto op = View(in.transcript_op);
63 const auto q_add = View(in.transcript_add);
64 const auto q_mul = View(in.transcript_mul);
65 const auto q_mul_shift = View(in.transcript_mul_shift);
66 const auto q_eq = View(in.transcript_eq);
67 const auto msm_transition = View(in.transcript_msm_transition);
68 const auto msm_count = View(in.transcript_msm_count);
69 const auto msm_count_shift = View(in.transcript_msm_count_shift);
70 const auto pc = View(in.transcript_pc);
71 const auto pc_shift = View(in.transcript_pc_shift);
72 const auto transcript_accumulator_x_shift = View(in.transcript_accumulator_x_shift);
73 const auto transcript_accumulator_y_shift = View(in.transcript_accumulator_y_shift);
74 const auto transcript_accumulator_x = View(in.transcript_accumulator_x);
75 const auto transcript_accumulator_y = View(in.transcript_accumulator_y);
76 const auto msm_count_zero_at_transition = View(in.transcript_msm_count_zero_at_transition);
77 const auto msm_count_at_transition_inverse = View(in.transcript_msm_count_at_transition_inverse);
78 const auto transcript_msm_x = View(in.transcript_msm_intermediate_x);
79 const auto transcript_msm_y = View(in.transcript_msm_intermediate_y);
80 const auto transcript_Px = View(in.transcript_Px);
81 const auto transcript_Py = View(in.transcript_Py);
82 const auto is_accumulator_empty = -View(in.transcript_accumulator_not_empty) + 1;
83 const auto lagrange_first = View(in.lagrange_first);
84 const auto lagrange_last = View(in.lagrange_last);
85 const auto is_accumulator_empty_shift = -View(in.transcript_accumulator_not_empty_shift) + 1;
86 const auto q_reset_accumulator = View(in.transcript_reset_accumulator);
87 const auto lagrange_second = View(in.lagrange_second);
88 const auto lagrange_third = View(in.lagrange_third);
89 const auto transcript_Pinfinity = View(in.transcript_base_infinity);
90 const auto transcript_Px_inverse = View(in.transcript_base_x_inverse);
91 const auto transcript_Py_inverse = View(in.transcript_base_y_inverse);
92 const auto transcript_add_x_equal = View(in.transcript_add_x_equal);
93 const auto transcript_add_y_equal = View(in.transcript_add_y_equal);
94 const auto transcript_add_lambda = View(in.transcript_add_lambda);
95 const auto transcript_msm_infinity = View(in.transcript_msm_infinity);
96
97 const auto is_not_first_row = (-lagrange_first + 1);
98 const auto is_not_last_row = (-lagrange_last + 1);
99 const auto is_not_first_or_last_row = (-lagrange_first + -lagrange_last + 1);
100 const auto is_not_infinity = (-transcript_Pinfinity + 1);
101 // Row 1 (lagrange_second = 1) is the hiding op row - skip on-curve check and eq constraints there
102 const auto is_not_hiding_row = (-lagrange_second + 1);
114 std::get<0>(accumulator) += (z1 * z1_zero) * scaling_factor; // if z1_zero = 1, z1 must be 0. degree 2
115 std::get<1>(accumulator) += (z2 * z2_zero) * scaling_factor; // degree 2
116
122 auto tmp = q_add + q_add;
123 tmp += q_mul;
124 tmp += tmp;
125 tmp += q_eq;
126 tmp += tmp;
127 tmp += q_reset_accumulator;
128 std::get<2>(accumulator) += (tmp - op) * scaling_factor; // degree 1
129
137 Accumulator pc_delta = pc - pc_shift;
138 auto num_muls_in_row = ((-z1_zero + 1) + (-z2_zero + 1)) * (-transcript_Pinfinity + 1);
139 // note that the value of `pc` in the first row is 0 because `pc` is shiftable. It is the second row where it starts
140 // out at its maximum value.
141 std::get<3>(accumulator) += is_not_first_row * (pc_delta - q_mul * num_muls_in_row) * scaling_factor; // degree 4
142
159 // `msm_transition_check` is a _syntactic_ check that we could be in a transition.
160 // `msm_count_total` is the total number of (short) multiplications, _including_ the multiplications to be processed
161 // in this row.
162 auto msm_transition_check = q_mul * (-q_mul_shift + 1); // degree 2
163 auto msm_count_total = msm_count + num_muls_in_row; // degree 2
164
165 // `msm_count_at_transition_check` witnesses the claim that if `msm_count_zero_at_transition == 1`, then
166 // `msm_count_total == 0` and if `msm_count_zero_at_transition == 0` and we are at a syntactic transition, then
167 // `msm_count_total is invertible`. The way it does this is `msm_count_at_transition_inverse` is supposed to vanish
168 // *except* possibly at a syntactic transition.
169 auto msm_count_zero_at_transition_check = msm_count_zero_at_transition * msm_count_total;
170 msm_count_zero_at_transition_check +=
171 (msm_count_total * msm_count_at_transition_inverse - 1) * (-msm_count_zero_at_transition + 1); // degree 4
172 // forces `msm_count_zero_at_transition` to have the following property at a syntactic transition: if
173 // `msm_count_zero_at_transition == 1`, then `msm_count_total == 0`. else if `msm_count_zero_at_transition == 0`,
174 // then `msm_count_total != 0` and is in fact the inverse of `msm_count_at_transition_inverse` (which is a witness
175 // column).
176 std::get<4>(accumulator) += msm_transition_check * msm_count_zero_at_transition_check * scaling_factor; // degree 6
177
185 std::get<5>(accumulator) +=
186 (msm_transition - msm_transition_check * (-msm_count_zero_at_transition + 1)) * scaling_factor; // degree 3
187
196 std::get<6>(accumulator) += ((-q_mul + 1) * msm_count) * scaling_factor; // degree 2
197
203 auto msm_count_delta = msm_count_shift - msm_count;
204 std::get<7>(accumulator) += is_not_first_row * (-msm_transition + 1) * (msm_count_delta - q_mul * num_muls_in_row) *
205 scaling_factor; // degree 5
206
213 auto opcode_exclusion_relation = q_mul * (q_add + q_eq + q_reset_accumulator);
214 opcode_exclusion_relation += q_add * (q_mul + q_eq + q_reset_accumulator);
215 std::get<8>(accumulator) += opcode_exclusion_relation * scaling_factor; // degree 2
216
224 auto both_infinity = transcript_Pinfinity * is_accumulator_empty; // degree 2
225 auto both_not_infinity = (-transcript_Pinfinity + 1) * (-is_accumulator_empty + 1); // degree 2
226 auto infinity_exclusion_check =
227 transcript_Pinfinity + is_accumulator_empty - both_infinity - both_infinity; // degree 2
228 auto eq_x_diff = transcript_Px - transcript_accumulator_x; // degree 1
229 auto eq_y_diff = transcript_Py - transcript_accumulator_y; // degree 1
230 // Gate eq constraints with is_not_hiding_row to skip at row 1 (hiding op row)
231 auto eq_x_diff_relation =
232 q_eq * (eq_x_diff * both_not_infinity + infinity_exclusion_check) * is_not_hiding_row; // degree 5
233 auto eq_y_diff_relation =
234 q_eq * (eq_y_diff * both_not_infinity + infinity_exclusion_check) * is_not_hiding_row; // degree 5
235 std::get<9>(accumulator) += eq_x_diff_relation * scaling_factor; // degree 5
236 std::get<10>(accumulator) += eq_y_diff_relation * scaling_factor; // degree 5
237
248 std::get<11>(accumulator) += lagrange_third * (-is_accumulator_empty + 1) * scaling_factor; // degree 2
249 std::get<12>(accumulator) += (lagrange_third * msm_count + lagrange_last * pc) * scaling_factor; // degree 2
250
258 const auto validate_on_curve = q_add + q_mul + q_eq;
259 const auto on_curve_check =
260 transcript_Py * transcript_Py - transcript_Px * transcript_Px * transcript_Px - get_curve_b();
261 // Gate on-curve check with is_not_hiding_row to skip at row 1 (hiding op row with potentially off-curve Px, Py)
262 std::get<13>(accumulator) +=
263 validate_on_curve * on_curve_check * is_not_infinity * is_not_hiding_row * scaling_factor; // degree 6
264
269 {
270 // in the following, LHS is the new elliptic curve point and RHS is the accumulator. LHS can either be the
271 // explicit point in an `add` op or the result of an MSM at the end of an MSM. RHS is often referred to as A.
272 Accumulator transcript_lambda_relation(0);
273 auto is_double = transcript_add_x_equal * transcript_add_y_equal; // degree 2
274 // `is_add == 1` iff the op_code is `add` and the x-value of the point-to-add and the accumulator are _not_
275 // equal. this ensures that it is not a double and that the result is not the point-at-infinity.
276 auto is_add = -transcript_add_x_equal + 1; // degree 1
277 // `add_result_is_infinity == 1` iff the op_code is `add`, the x-value of the point-to-add and the accumulator
278 // are equal, and the y-values are unequal. then the result of the accumulation is of course the
279 // point-at-infinity.
280 auto add_result_is_infinity = transcript_add_x_equal * (-transcript_add_y_equal + 1); // degree 2
281 auto rhs_x = transcript_accumulator_x; // degree 1
282 auto rhs_y = transcript_accumulator_y; // degree 1
283 auto out_x = transcript_accumulator_x_shift; // degree 1
284 auto out_y = transcript_accumulator_y_shift; // degree 1
285 auto lambda = transcript_add_lambda; // degree 1
286 // note that `msm_transition` and `q_add` are mutually exclusive booleans. (they can also both be off.)
287 // therefore `(lhs_x, lhs_y)` is either the point in the `add` VM instruction _or_ the output of the
288 // just-completed MSM.
289 auto lhs_x = transcript_Px * q_add + transcript_msm_x * msm_transition; // degree 2
290 auto lhs_y = transcript_Py * q_add + transcript_msm_y * msm_transition; // degree 2
291 // `lhs_infinity == 1` iff the point being added to the accumulator is the point-at-infinity.
292 auto lhs_infinity = transcript_Pinfinity * q_add + transcript_msm_infinity * msm_transition; // degree 2
293 auto rhs_infinity = is_accumulator_empty; // degree 1
294 // `result_is_lhs == 1` iff the output of the operation is the LHS and is _not_ the point-at-infinity.
295 // `result_is_rhs == 1` iff the output of the operation is the RHS and is _not_ the point-at-infinity.
296 auto result_is_lhs = rhs_infinity * (-lhs_infinity + 1); // degree 2
297 auto result_is_rhs = (-rhs_infinity + 1) * lhs_infinity; // degree 2
298 // `result_infinity_from_inputs` checks if both the LHS && RHS are the point-at-infinity. this means that the
299 // result is the point-at-infinity from "pure-thought" reasons from the inputs.
300 auto result_infinity_from_inputs = lhs_infinity * rhs_infinity; // degree 2
301 // `result_infinity_from_operation` tests if the operation is non-trivial and the output is the
302 // point-at-infinity. note we are using that our EC has no non-trivial rational 2-torsion.
303 auto result_infinity_from_operation = transcript_add_x_equal * (-transcript_add_y_equal + 1); // degree 2
304 // `result_infinity_from_inputs` and `result_infinity_from_operation` are mutually exclusive (i.e., cannot both
305 // be 1), so we can perform an OR by adding. (they are mutually exclusive because if
306 // `result_infinity_from_inputs` then `transcript_add_y_equal == 1`.)
307 auto result_is_infinity = result_infinity_from_inputs + result_infinity_from_operation; // degree 2
308 auto any_add_is_active = q_add + msm_transition; // degree 1
309
310 // Valdiate `transcript_add_lambda` is well formed if we are adding MSM output into accumulator
311 {
312 Accumulator transcript_msm_lambda_relation(0);
313 auto msm_x = transcript_msm_x;
314 auto msm_y = transcript_msm_y;
315 // Group operation is point addition
316 {
317 auto lambda_denominator = (rhs_x - msm_x);
318 auto lambda_numerator = (rhs_y - msm_y);
319 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
320 transcript_msm_lambda_relation += lambda_relation * is_add; // degree 3
321 }
322 // Group operation is point doubling
323 {
324 auto lambda_denominator = msm_y + msm_y;
325 auto lambda_numerator = msm_x * msm_x * 3;
326 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
327 transcript_msm_lambda_relation += lambda_relation * is_double; // degree 4
328 }
329 auto transcript_add_or_dbl_from_msm_output_is_valid =
330 (-transcript_msm_infinity + 1) * (-is_accumulator_empty + 1); // degree 2
331 // zero-out the value of `transcript_msm_lambda_relation` if output of MSM is point-at-infinity or the
332 // accumulator is point-at-infinity. (this case cannot be handled uniformly and will be handled by the
333 // following logic.)
334 transcript_msm_lambda_relation *= transcript_add_or_dbl_from_msm_output_is_valid; // degree 6
335 // No group operation because of points at infinity
336 {
337 // `lambda_relation_invalid != 0` means that lambda does not enter into our calculation for
338 // point-at-infinity reasons. in this case, `lambda` is constrained to be 0.
339 auto lambda_relation_invalid =
340 (transcript_msm_infinity + is_accumulator_empty + add_result_is_infinity); // degree 2
341 auto lambda_relation = lambda * lambda_relation_invalid; // degree 4
342 transcript_msm_lambda_relation += lambda_relation; // degree 6
343 }
344 // relation is only touched if we are at an msm_transition
345 transcript_lambda_relation = transcript_msm_lambda_relation * msm_transition; // degree 7
346 }
347 // Valdiate `transcript_add_lambda` is well formed if we are adding base point into accumulator
348 // very similar to the above code for adding an MSM output.
349 {
350 Accumulator transcript_add_lambda_relation(0);
351 auto add_x = transcript_Px;
352 auto add_y = transcript_Py;
353 // Group operation is point addition
354 {
355 auto lambda_denominator = (rhs_x - add_x);
356 auto lambda_numerator = (rhs_y - add_y);
357 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
358 transcript_add_lambda_relation += lambda_relation * is_add; // degree 3
359 }
360 // Group operation is point doubling
361 {
362 auto lambda_denominator = add_y + add_y;
363 auto lambda_numerator = add_x * add_x * 3;
364 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
365 transcript_add_lambda_relation += lambda_relation * is_double; // degree 4
366 }
367 auto transcript_add_or_dbl_from_add_output_is_valid =
368 (-transcript_Pinfinity + 1) * (-is_accumulator_empty + 1); // degree 2
369 transcript_add_lambda_relation *= transcript_add_or_dbl_from_add_output_is_valid; // degree 6
370 // No group operation because of points at infinity
371 {
372 // `lambda_relation_invalid != 0` means that lambda does not enter into our calculation for
373 // point-at-infinity reasons. in this case, `lambda` is constrained to be 0.
374 auto lambda_relation_invalid =
375 (transcript_Pinfinity + is_accumulator_empty + add_result_is_infinity); // degree 2
376 auto lambda_relation = lambda * lambda_relation_invalid; // degree 4
377 transcript_add_lambda_relation += lambda_relation; // degree 6
378 }
379 // relation is only touched if we are at an `add` instruction.
380 transcript_lambda_relation += transcript_add_lambda_relation * q_add;
381 std::get<14>(accumulator) += transcript_lambda_relation * scaling_factor; // degree 7
382 }
394 // accumulator is propagated if we are at a `mul` and _not_ at an `msm_transition` OR we are at an `eq` and we
395 // don't reset the accumulator. note that if `msm_transition_check == 1` (i.e., we are at a syntactic
396 // transition) but the total number of muls is 0, then the accumulator should indeed be propagated.
397 auto propagate_transcript_accumulator =
398 (q_mul) * (-msm_transition + 1) + (q_eq * (-q_reset_accumulator + 1)); // degree 2
399 {
400 auto lambda_sqr = lambda * lambda;
401
402 // N.B. these relations rely on the fact that `lambda = 0` if we are not evaluating add/double formula
403 // (i.e. one or both outputs are points at infinity, or produce a point at infinity)
404 // This should be validated by the lambda_relation
405 auto x3 = lambda_sqr - lhs_x - rhs_x; // degree 2
406 auto y3 = lambda * (lhs_x - out_x) - lhs_y; // degree 3
407 x3 += result_is_lhs * (rhs_x + lhs_x + lhs_x); // degree 4
408 x3 += result_is_rhs * (lhs_x + rhs_x + rhs_x); // degree 4
409 x3 += result_is_infinity * (lhs_x + rhs_x); // degree 4
410 y3 += result_is_lhs * (lhs_y + lhs_y); // degree 4
411 y3 += result_is_rhs * (lhs_y + rhs_y); // degree 4
412 y3 += result_is_infinity * lhs_y; // degree 4
413 // internal to the Transcript columns, the point-at-infinity is encoded as `(0, 0)`.
414 // this is implicit in the subsequent computations: e.g. if `result_is_infinity`, then `(x3, y3) == (0, 0)`,
415 // or if `q_reset_accumulator == 1`, then `(out_x, out_y) == (0, 0)`.
416 auto add_point_x_relation = (x3 - out_x) * any_add_is_active; // degree 5
417 add_point_x_relation +=
418 propagate_transcript_accumulator * is_not_last_row * (out_x - transcript_accumulator_x); // degree 4
419 // validate out_x = 0 if q_reset_accumulator = 1
420 add_point_x_relation += (out_x * q_reset_accumulator);
421 auto add_point_y_relation = (y3 - out_y) * any_add_is_active; // degree 5
422 add_point_y_relation +=
423 propagate_transcript_accumulator * is_not_last_row * (out_y - transcript_accumulator_y);
424 // validate out_y = 0 if q_reset_accumulator = 1
425 add_point_y_relation += (out_y * q_reset_accumulator);
426 auto opcode_is_zero =
427 (is_not_first_row) * (-q_add + 1) * (-q_mul + 1) * (-q_reset_accumulator + 1) * (-q_eq + 1); // degree 5
428 add_point_x_relation += (out_x * opcode_is_zero); // degree 6
429 add_point_y_relation += (out_y * opcode_is_zero); // degree 6
430
431 std::get<15>(accumulator) += add_point_x_relation * scaling_factor; // degree 6
432 std::get<16>(accumulator) += add_point_y_relation * scaling_factor; // degree 6
433 }
434
435 // subtract offset generator from msm_accumulator. this might produce a point at infinity
436 {
437 // the fundamental relation is: `(transcript_msm_x, transcript_msm_y) - offset ==
438 // `(transcript_msm_intermediate_x, transcript_msm_intermediate_y)`. in other words, `(transcript_msm_x,
439 // transcript_msm_y)` is the _shifted_ value of the MSM.
440 const auto offset = offset_generator();
441 const auto x1 = offset[0];
442 const auto y1 = -offset[1];
443 const auto x2 = View(in.transcript_msm_x);
444 const auto y2 = View(in.transcript_msm_y);
445 const auto x3 = View(in.transcript_msm_intermediate_x);
446 const auto y3 = View(in.transcript_msm_intermediate_y);
447 const auto transcript_msm_infinity = View(in.transcript_msm_infinity);
448 // cases:
449 // x2 == x1, y2 == y1
450 // x2 != x1
451 const auto x_term = (x3 + x2 + x1) * (x2 - x1) * (x2 - x1) - (y2 - y1) * (y2 - y1); // degree 3
452 const auto y_term = (x1 - x3) * (y2 - y1) - (x2 - x1) * (y1 + y3); // degree 2
453 // If `transcript_msm_infinity == 0`, then `(transcript_msm_intermediate_x, transcript_msm_intermediate_y)`
454 // is the result of subtracting offset generator from `(transcript_msm_x, transcript_msm_y)`. If
455 // `transcript_msm_infinity == 1`, then both `transcript_msm_intermediate_x ==0` and
456 // `transcript_msm_intermediate_y == 0`.
457 //
458 // again, point-at-infinity is represented internally in the Transcript columns by `(0, 0)`.
459 const auto transcript_offset_generator_subtract_x =
460 x_term * (-transcript_msm_infinity + 1) + transcript_msm_infinity * x3; // degree 4
461 const auto transcript_offset_generator_subtract_y =
462 y_term * (-transcript_msm_infinity + 1) + transcript_msm_infinity * y3; // degree 3
463 std::get<17>(accumulator) +=
464 msm_transition * transcript_offset_generator_subtract_x * scaling_factor; // degree 5
465 std::get<18>(accumulator) +=
466 msm_transition * transcript_offset_generator_subtract_y * scaling_factor; // degree 5
467
468 // validate `transcript_msm_infinity` is correct
469 // if `transcript_msm_infinity == 1`, then both `x2 == x1` and `y2 + y1 == 0`. (this is because `(x1, y1)`
470 // is the negative of the offset.)
471 const auto x_diff = x2 - x1;
472 const auto y_sum = y2 + y1;
473 std::get<19>(accumulator) += msm_transition * transcript_msm_infinity * x_diff * scaling_factor; // degree 3
474 std::get<20>(accumulator) += msm_transition * transcript_msm_infinity * y_sum * scaling_factor; // degree 3
475 // if `transcript_msm_infinity == 0`, then `x_diff` must have an inverse
476 const auto transcript_msm_x_inverse = View(in.transcript_msm_x_inverse);
477 const auto inverse_term = (-transcript_msm_infinity + 1) * (x_diff * transcript_msm_x_inverse - 1);
478 std::get<21>(accumulator) += msm_transition * inverse_term * scaling_factor; // degree 3
479 }
480
488 auto accumulator_infinity_preserve_flag = propagate_transcript_accumulator; // degree 1
489 auto accumulator_infinity_preserve = accumulator_infinity_preserve_flag *
490 (is_accumulator_empty - is_accumulator_empty_shift) *
491 is_not_first_or_last_row; // degree 3
492 auto accumulator_infinity_q_reset = q_reset_accumulator * (-is_accumulator_empty_shift + 1); // degree 2
493 auto accumulator_infinity_from_add =
494 any_add_is_active * (result_is_infinity - is_accumulator_empty_shift); // degree 3
495 auto accumulator_infinity_relation =
496 accumulator_infinity_preserve +
497 (accumulator_infinity_q_reset + accumulator_infinity_from_add) * is_not_first_row; // degree 4
498 std::get<22>(accumulator) += accumulator_infinity_relation * scaling_factor; // degree 4
499
505 auto x_diff = lhs_x - rhs_x; // degree 2
506 // recall that transcript_Px_inverse is the claimed inverse of `x_diff`.
507 auto x_product = transcript_Px_inverse * (-transcript_add_x_equal + 1) + transcript_add_x_equal; // degree 2
508 auto x_constant = transcript_add_x_equal - 1; // degree 1
509 auto transcript_add_x_equal_check_relation = (x_diff * x_product + x_constant) * any_add_is_active; // degree 5
510 std::get<23>(accumulator) += transcript_add_x_equal_check_relation * scaling_factor; // degree 5
511
517 auto y_diff = lhs_y - rhs_y;
518 auto y_product = transcript_Py_inverse * (-transcript_add_y_equal + 1) + transcript_add_y_equal;
519 auto y_constant = transcript_add_y_equal - 1;
520 auto transcript_add_y_equal_check_relation = (y_diff * y_product + y_constant) * any_add_is_active;
521 std::get<24>(accumulator) += transcript_add_y_equal_check_relation * scaling_factor; // degree 5
522 }
523
530 std::get<25>(accumulator) += lagrange_second * (-q_eq + 1) * scaling_factor; // degree 2
531 std::get<26>(accumulator) += lagrange_second * (-q_reset_accumulator + 1) * scaling_factor; // degree 2
532}
533} // namespace bb
static void accumulate(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters &, const FF &scaling_factor)
ECCVMTranscriptRelationImpl evaluates the correctness of the ECCVM transcript columns.
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
Definition element.hpp:33
group_elements::affine_element< Fq, Fr, Params > affine_element
Definition group.hpp:42
ssize_t offset
Definition engine.cpp:36
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
group< fq, fr, Bn254G1Params > g1
Definition g1.hpp:33
constexpr std::span< const typename Group::affine_element > get_precomputed_generators()
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13