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 transcript_Pinfinity = View(in.transcript_base_infinity);
89 const auto transcript_Px_inverse = View(in.transcript_base_x_inverse);
90 const auto transcript_Py_inverse = View(in.transcript_base_y_inverse);
91 const auto transcript_add_x_equal = View(in.transcript_add_x_equal);
92 const auto transcript_add_y_equal = View(in.transcript_add_y_equal);
93 const auto transcript_add_lambda = View(in.transcript_add_lambda);
94 const auto transcript_msm_infinity = View(in.transcript_msm_infinity);
95
96 const auto is_not_first_row = (-lagrange_first + 1);
97 const auto is_not_last_row = (-lagrange_last + 1);
98 const auto is_not_first_or_last_row = (-lagrange_first + -lagrange_last + 1);
99 const auto is_not_infinity = (-transcript_Pinfinity + 1);
111 std::get<0>(accumulator) += (z1 * z1_zero) * scaling_factor; // if z1_zero = 1, z1 must be 0. degree 2
112 std::get<1>(accumulator) += (z2 * z2_zero) * scaling_factor; // degree 2
113
119 auto tmp = q_add + q_add;
120 tmp += q_mul;
121 tmp += tmp;
122 tmp += q_eq;
123 tmp += tmp;
124 tmp += q_reset_accumulator;
125 std::get<2>(accumulator) += (tmp - op) * scaling_factor; // degree 1
126
134 Accumulator pc_delta = pc - pc_shift;
135 auto num_muls_in_row = ((-z1_zero + 1) + (-z2_zero + 1)) * (-transcript_Pinfinity + 1);
136 // note that the value of `pc` in the first row is 0 because `pc` is shiftable. It is the second row where it starts
137 // out at its maximum value.
138 std::get<3>(accumulator) += is_not_first_row * (pc_delta - q_mul * num_muls_in_row) * scaling_factor; // degree 4
139
156 // `msm_transition_check` is a _syntactic_ check that we could be in a transition.
157 // `msm_count_total` is the total number of (short) multiplications, _including_ the multiplications to be processed
158 // in this row.
159 auto msm_transition_check = q_mul * (-q_mul_shift + 1); // degree 2
160 auto msm_count_total = msm_count + num_muls_in_row; // degree 2
161
162 // `msm_count_at_transition_check` witnesses the claim that if `msm_count_zero_at_transition == 1`, then
163 // `msm_count_total == 0` and if `msm_count_zero_at_transition == 0` and we are at a syntactic transition, then
164 // `msm_count_total is invertible`. The way it does this is `msm_count_at_transition_inverse` is supposed to vanish
165 // *except* possibly at a syntactic transition.
166 auto msm_count_zero_at_transition_check = msm_count_zero_at_transition * msm_count_total;
167 msm_count_zero_at_transition_check +=
168 (msm_count_total * msm_count_at_transition_inverse - 1) * (-msm_count_zero_at_transition + 1); // degree 4
169 // forces `msm_count_zero_at_transition` to have the following property at a syntactic transition: if
170 // `msm_count_zero_at_transition == 1`, then `msm_count_total == 0`. else if `msm_count_zero_at_transition == 0`,
171 // then `msm_count_total != 0` and is in fact the inverse of `msm_count_at_transition_inverse` (which is a witness
172 // column).
173 std::get<4>(accumulator) += msm_transition_check * msm_count_zero_at_transition_check * scaling_factor; // degree 6
174
182 std::get<5>(accumulator) +=
183 (msm_transition - msm_transition_check * (-msm_count_zero_at_transition + 1)) * scaling_factor; // degree 3
184
193 std::get<6>(accumulator) += ((-q_mul + 1) * msm_count) * scaling_factor; // degree 2
194
200 auto msm_count_delta = msm_count_shift - msm_count;
201 std::get<7>(accumulator) += is_not_first_row * (-msm_transition + 1) * (msm_count_delta - q_mul * num_muls_in_row) *
202 scaling_factor; // degree 5
203
210 auto opcode_exclusion_relation = q_mul * (q_add + q_eq + q_reset_accumulator);
211 opcode_exclusion_relation += q_add * (q_mul + q_eq + q_reset_accumulator);
212 std::get<8>(accumulator) += opcode_exclusion_relation * scaling_factor; // degree 2
213
221 auto both_infinity = transcript_Pinfinity * is_accumulator_empty; // degree 2
222 auto both_not_infinity = (-transcript_Pinfinity + 1) * (-is_accumulator_empty + 1); // degree 2
223 auto infinity_exclusion_check =
224 transcript_Pinfinity + is_accumulator_empty - both_infinity - both_infinity; // degree 2
225 auto eq_x_diff = transcript_Px - transcript_accumulator_x; // degree 1
226 auto eq_y_diff = transcript_Py - transcript_accumulator_y; // degree 1
227 auto eq_x_diff_relation = q_eq * (eq_x_diff * both_not_infinity + infinity_exclusion_check); // degree 4
228 auto eq_y_diff_relation = q_eq * (eq_y_diff * both_not_infinity + infinity_exclusion_check); // degree 4
229 std::get<9>(accumulator) += eq_x_diff_relation * scaling_factor; // degree 4
230 std::get<10>(accumulator) += eq_y_diff_relation * scaling_factor; // degree 4
231
241 std::get<11>(accumulator) += lagrange_second * (-is_accumulator_empty + 1) * scaling_factor; // degree 2
242 std::get<12>(accumulator) += (lagrange_second * msm_count + lagrange_last * pc) * scaling_factor; // degree 2
243
250 const auto validate_on_curve = q_add + q_mul + q_eq;
251 const auto on_curve_check =
252 transcript_Py * transcript_Py - transcript_Px * transcript_Px * transcript_Px - get_curve_b();
253 std::get<13>(accumulator) += validate_on_curve * on_curve_check * is_not_infinity * scaling_factor; // degree 5
254
259 {
260 // in the following, LHS is the new elliptic curve point and RHS is the accumulator. LHS can either be the
261 // 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.
262 Accumulator transcript_lambda_relation(0);
263 auto is_double = transcript_add_x_equal * transcript_add_y_equal; // degree 2
264 // `is_add == 1` iff the op_code is `add` and the x-value of the point-to-add and the accumulator are _not_
265 // equal. this ensures that it is not a double and that the result is not the point-at-infinity.
266 auto is_add = -transcript_add_x_equal + 1; // degree 1
267 // `add_result_is_infinity == 1` iff the op_code is `add`, the x-value of the point-to-add and the accumulator
268 // are equal, and the y-values are unequal. then the result of the accumulation is of course the
269 // point-at-infinity.
270 auto add_result_is_infinity = transcript_add_x_equal * (-transcript_add_y_equal + 1); // degree 2
271 auto rhs_x = transcript_accumulator_x; // degree 1
272 auto rhs_y = transcript_accumulator_y; // degree 1
273 auto out_x = transcript_accumulator_x_shift; // degree 1
274 auto out_y = transcript_accumulator_y_shift; // degree 1
275 auto lambda = transcript_add_lambda; // degree 1
276 // note that `msm_transition` and `q_add` are mutually exclusive booleans. (they can also both be off.)
277 // therefore `(lhs_x, lhs_y)` is either the point in the `add` VM instruction _or_ the output of the
278 // just-completed MSM.
279 auto lhs_x = transcript_Px * q_add + transcript_msm_x * msm_transition; // degree 2
280 auto lhs_y = transcript_Py * q_add + transcript_msm_y * msm_transition; // degree 2
281 // `lhs_infinity == 1` iff the point being added to the accumulator is the point-at-infinity.
282 auto lhs_infinity = transcript_Pinfinity * q_add + transcript_msm_infinity * msm_transition; // degree 2
283 auto rhs_infinity = is_accumulator_empty; // degree 1
284 // `result_is_lhs == 1` iff the output of the operation is the LHS and is _not_ the point-at-infinity.
285 // `result_is_rhs == 1` iff the output of the operation is the RHS and is _not_ the point-at-infinity.
286 auto result_is_lhs = rhs_infinity * (-lhs_infinity + 1); // degree 2
287 auto result_is_rhs = (-rhs_infinity + 1) * lhs_infinity; // degree 2
288 // `result_infinity_from_inputs` checks if both the LHS && RHS are the point-at-infinity. this means that the
289 // result is the point-at-infinity from "pure-thought" reasons from the inputs.
290 auto result_infinity_from_inputs = lhs_infinity * rhs_infinity; // degree 2
291 // `result_infinity_from_operation` tests if the operation is non-trivial and the output is the
292 // point-at-infinity. note we are using that our EC has no non-trivial rational 2-torsion.
293 auto result_infinity_from_operation = transcript_add_x_equal * (-transcript_add_y_equal + 1); // degree 2
294 // `result_infinity_from_inputs` and `result_infinity_from_operation` are mutually exclusive (i.e., cannot both
295 // be 1), so we can perform an OR by adding. (they are mutually exclusive because if
296 // `result_infinity_from_inputs` then `transcript_add_y_equal == 1`.)
297 auto result_is_infinity = result_infinity_from_inputs + result_infinity_from_operation; // degree 2
298 auto any_add_is_active = q_add + msm_transition; // degree 1
299
300 // Valdiate `transcript_add_lambda` is well formed if we are adding MSM output into accumulator
301 {
302 Accumulator transcript_msm_lambda_relation(0);
303 auto msm_x = transcript_msm_x;
304 auto msm_y = transcript_msm_y;
305 // Group operation is point addition
306 {
307 auto lambda_denominator = (rhs_x - msm_x);
308 auto lambda_numerator = (rhs_y - msm_y);
309 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
310 transcript_msm_lambda_relation += lambda_relation * is_add; // degree 3
311 }
312 // Group operation is point doubling
313 {
314 auto lambda_denominator = msm_y + msm_y;
315 auto lambda_numerator = msm_x * msm_x * 3;
316 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
317 transcript_msm_lambda_relation += lambda_relation * is_double; // degree 4
318 }
319 auto transcript_add_or_dbl_from_msm_output_is_valid =
320 (-transcript_msm_infinity + 1) * (-is_accumulator_empty + 1); // degree 2
321 // zero-out the value of `transcript_msm_lambda_relation` if output of MSM is point-at-infinity or the
322 // accumulator is point-at-infinity. (this case cannot be handled uniformly and will be handled by the
323 // following logic.)
324 transcript_msm_lambda_relation *= transcript_add_or_dbl_from_msm_output_is_valid; // degree 6
325 // No group operation because of points at infinity
326 {
327 // `lambda_relation_invalid != 0` means that lambda does not enter into our calculation for
328 // point-at-infinity reasons. in this case, `lambda` is constrained to be 0.
329 auto lambda_relation_invalid =
330 (transcript_msm_infinity + is_accumulator_empty + add_result_is_infinity); // degree 2
331 auto lambda_relation = lambda * lambda_relation_invalid; // degree 4
332 transcript_msm_lambda_relation += lambda_relation; // degree 6
333 }
334 // relation is only touched if we are at an msm_transition
335 transcript_lambda_relation = transcript_msm_lambda_relation * msm_transition; // degree 7
336 }
337 // Valdiate `transcript_add_lambda` is well formed if we are adding base point into accumulator
338 // very similar to the above code for adding an MSM output.
339 {
340 Accumulator transcript_add_lambda_relation(0);
341 auto add_x = transcript_Px;
342 auto add_y = transcript_Py;
343 // Group operation is point addition
344 {
345 auto lambda_denominator = (rhs_x - add_x);
346 auto lambda_numerator = (rhs_y - add_y);
347 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
348 transcript_add_lambda_relation += lambda_relation * is_add; // degree 3
349 }
350 // Group operation is point doubling
351 {
352 auto lambda_denominator = add_y + add_y;
353 auto lambda_numerator = add_x * add_x * 3;
354 auto lambda_relation = lambda * lambda_denominator - lambda_numerator; // degree 2
355 transcript_add_lambda_relation += lambda_relation * is_double; // degree 4
356 }
357 auto transcript_add_or_dbl_from_add_output_is_valid =
358 (-transcript_Pinfinity + 1) * (-is_accumulator_empty + 1); // degree 2
359 transcript_add_lambda_relation *= transcript_add_or_dbl_from_add_output_is_valid; // degree 6
360 // No group operation because of points at infinity
361 {
362 // `lambda_relation_invalid != 0` means that lambda does not enter into our calculation for
363 // point-at-infinity reasons. in this case, `lambda` is constrained to be 0.
364 auto lambda_relation_invalid =
365 (transcript_Pinfinity + is_accumulator_empty + add_result_is_infinity); // degree 2
366 auto lambda_relation = lambda * lambda_relation_invalid; // degree 4
367 transcript_add_lambda_relation += lambda_relation; // degree 6
368 }
369 // relation is only touched if we are at an `add` instruction.
370 transcript_lambda_relation += transcript_add_lambda_relation * q_add;
371 std::get<14>(accumulator) += transcript_lambda_relation * scaling_factor; // degree 7
372 }
384 // accumulator is propagated if we are at a `mul` and _not_ at an `msm_transition` OR we are at an `eq` and we
385 // don't reset the accumulator. note that if `msm_transition_check == 1` (i.e., we are at a syntactic
386 // transition) but the total number of muls is 0, then the accumulator should indeed be propagated.
387 auto propagate_transcript_accumulator =
388 (q_mul) * (-msm_transition + 1) + (q_eq * (-q_reset_accumulator + 1)); // degree 2
389 {
390 auto lambda_sqr = lambda * lambda;
391
392 // N.B. these relations rely on the fact that `lambda = 0` if we are not evaluating add/double formula
393 // (i.e. one or both outputs are points at infinity, or produce a point at infinity)
394 // This should be validated by the lambda_relation
395 auto x3 = lambda_sqr - lhs_x - rhs_x; // degree 2
396 auto y3 = lambda * (lhs_x - out_x) - lhs_y; // degree 3
397 x3 += result_is_lhs * (rhs_x + lhs_x + lhs_x); // degree 4
398 x3 += result_is_rhs * (lhs_x + rhs_x + rhs_x); // degree 4
399 x3 += result_is_infinity * (lhs_x + rhs_x); // degree 4
400 y3 += result_is_lhs * (lhs_y + lhs_y); // degree 4
401 y3 += result_is_rhs * (lhs_y + rhs_y); // degree 4
402 y3 += result_is_infinity * lhs_y; // degree 4
403 // internal to the Transcript columns, the point-at-infinity is encoded as `(0, 0)`.
404 // this is implicit in the subsequent computations: e.g. if `result_is_infinity`, then `(x3, y3) == (0, 0)`,
405 // or if `q_reset_accumulator == 1`, then `(out_x, out_y) == (0, 0)`.
406 auto add_point_x_relation = (x3 - out_x) * any_add_is_active; // degree 5
407 add_point_x_relation +=
408 propagate_transcript_accumulator * is_not_last_row * (out_x - transcript_accumulator_x); // degree 4
409 // validate out_x = 0 if q_reset_accumulator = 1
410 add_point_x_relation += (out_x * q_reset_accumulator);
411 auto add_point_y_relation = (y3 - out_y) * any_add_is_active; // degree 5
412 add_point_y_relation +=
413 propagate_transcript_accumulator * is_not_last_row * (out_y - transcript_accumulator_y);
414 // validate out_y = 0 if q_reset_accumulator = 1
415 add_point_y_relation += (out_y * q_reset_accumulator);
416 auto opcode_is_zero =
417 (is_not_first_row) * (-q_add + 1) * (-q_mul + 1) * (-q_reset_accumulator + 1) * (-q_eq + 1); // degree 5
418 add_point_x_relation += (out_x * opcode_is_zero); // degree 6
419 add_point_y_relation += (out_y * opcode_is_zero); // degree 6
420
421 std::get<15>(accumulator) += add_point_x_relation * scaling_factor; // degree 6
422 std::get<16>(accumulator) += add_point_y_relation * scaling_factor; // degree 6
423 }
424
425 // subtract offset generator from msm_accumulator. this might produce a point at infinity
426 {
427 // the fundamental relation is: `(transcript_msm_x, transcript_msm_y) - offset ==
428 // `(transcript_msm_intermediate_x, transcript_msm_intermediate_y)`. in other words, `(transcript_msm_x,
429 // transcript_msm_y)` is the _shifted_ value of the MSM.
430 const auto offset = offset_generator();
431 const auto x1 = offset[0];
432 const auto y1 = -offset[1];
433 const auto x2 = View(in.transcript_msm_x);
434 const auto y2 = View(in.transcript_msm_y);
435 const auto x3 = View(in.transcript_msm_intermediate_x);
436 const auto y3 = View(in.transcript_msm_intermediate_y);
437 const auto transcript_msm_infinity = View(in.transcript_msm_infinity);
438 // cases:
439 // x2 == x1, y2 == y1
440 // x2 != x1
441 const auto x_term = (x3 + x2 + x1) * (x2 - x1) * (x2 - x1) - (y2 - y1) * (y2 - y1); // degree 3
442 const auto y_term = (x1 - x3) * (y2 - y1) - (x2 - x1) * (y1 + y3); // degree 2
443 // If `transcript_msm_infinity == 0`, then `(transcript_msm_intermediate_x, transcript_msm_intermediate_y)`
444 // is the result of subtracting offset generator from `(transcript_msm_x, transcript_msm_y)`. If
445 // `transcript_msm_infinity == 1`, then both `transcript_msm_intermediate_x ==0` and
446 // `transcript_msm_intermediate_y == 0`.
447 //
448 // again, point-at-infinity is represented internally in the Transcript columns by `(0, 0)`.
449 const auto transcript_offset_generator_subtract_x =
450 x_term * (-transcript_msm_infinity + 1) + transcript_msm_infinity * x3; // degree 4
451 const auto transcript_offset_generator_subtract_y =
452 y_term * (-transcript_msm_infinity + 1) + transcript_msm_infinity * y3; // degree 3
453 std::get<17>(accumulator) +=
454 msm_transition * transcript_offset_generator_subtract_x * scaling_factor; // degree 5
455 std::get<18>(accumulator) +=
456 msm_transition * transcript_offset_generator_subtract_y * scaling_factor; // degree 5
457
458 // validate `transcript_msm_infinity` is correct
459 // if `transcript_msm_infinity == 1`, then both `x2 == x1` and `y2 + y1 == 0`. (this is because `(x1, y1)`
460 // is the negative of the offset.)
461 const auto x_diff = x2 - x1;
462 const auto y_sum = y2 + y1;
463 std::get<19>(accumulator) += msm_transition * transcript_msm_infinity * x_diff * scaling_factor; // degree 3
464 std::get<20>(accumulator) += msm_transition * transcript_msm_infinity * y_sum * scaling_factor; // degree 3
465 // if `transcript_msm_infinity == 0`, then `x_diff` must have an inverse
466 const auto transcript_msm_x_inverse = View(in.transcript_msm_x_inverse);
467 const auto inverse_term = (-transcript_msm_infinity + 1) * (x_diff * transcript_msm_x_inverse - 1);
468 std::get<21>(accumulator) += msm_transition * inverse_term * scaling_factor; // degree 3
469 }
470
478 auto accumulator_infinity_preserve_flag = propagate_transcript_accumulator; // degree 1
479 auto accumulator_infinity_preserve = accumulator_infinity_preserve_flag *
480 (is_accumulator_empty - is_accumulator_empty_shift) *
481 is_not_first_or_last_row; // degree 3
482 auto accumulator_infinity_q_reset = q_reset_accumulator * (-is_accumulator_empty_shift + 1); // degree 2
483 auto accumulator_infinity_from_add =
484 any_add_is_active * (result_is_infinity - is_accumulator_empty_shift); // degree 3
485 auto accumulator_infinity_relation =
486 accumulator_infinity_preserve +
487 (accumulator_infinity_q_reset + accumulator_infinity_from_add) * is_not_first_row; // degree 4
488 std::get<22>(accumulator) += accumulator_infinity_relation * scaling_factor; // degree 4
489
495 auto x_diff = lhs_x - rhs_x; // degree 2
496 // recall that transcript_Px_inverse is the claimed inverse of `x_diff`.
497 auto x_product = transcript_Px_inverse * (-transcript_add_x_equal + 1) + transcript_add_x_equal; // degree 2
498 auto x_constant = transcript_add_x_equal - 1; // degree 1
499 auto transcript_add_x_equal_check_relation = (x_diff * x_product + x_constant) * any_add_is_active; // degree 5
500 std::get<23>(accumulator) += transcript_add_x_equal_check_relation * scaling_factor; // degree 5
501
507 auto y_diff = lhs_y - rhs_y;
508 auto y_product = transcript_Py_inverse * (-transcript_add_y_equal + 1) + transcript_add_y_equal;
509 auto y_constant = transcript_add_y_equal - 1;
510 auto transcript_add_y_equal_check_relation = (y_diff * y_product + y_constant) * any_add_is_active;
511 std::get<24>(accumulator) += transcript_add_y_equal_check_relation * scaling_factor; // degree 5
512 }
513}
514} // 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.
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