1#include "../biggroup/biggroup.hpp"
2#include "../bigfield/bigfield.hpp"
3#include "../bool/bool.hpp"
4#include "../field/field.hpp"
39template <
typename Curve_,
typename ScalarField_,
bool use_bigfield>
struct TestType {
44 element<typename Curve::Builder, typename Curve::BaseField, ScalarField_, typename Curve::GroupNative>;
57 using fq =
typename Curve::BaseFieldNative;
58 using fr =
typename Curve::ScalarFieldNative;
59 using g1 =
typename Curve::GroupNative;
69 info(
"num gates = ",
builder.get_num_finalized_gates_inefficient());
80 return e.get_value().is_point_at_infinity();
82 return e.is_point_at_infinity().get_value();
99 using Fq =
typename element_ct::BaseField;
119 if (even &&
uint256_t(scalar_native).get_bit(0)) {
120 scalar_native -=
fr(1);
130 if (even &&
uint256_t(scalar_native).get_bit(0)) {
131 scalar_native -=
fr(1);
149 scalar_u256 = scalar_u256 >> (256 - num_bits);
151 fr scalar_native(scalar_u256);
171 a.set_origin_tag(submitted_value_origin_tag);
172 b.set_origin_tag(challenge_origin_tag);
175 EXPECT_EQ(
a.get_origin_tag(), submitted_value_origin_tag);
176 EXPECT_EQ(
b.get_origin_tag(), challenge_origin_tag);
179 EXPECT_EQ((
a +
b).get_origin_tag(), first_two_merged_tag);
180 EXPECT_EQ((
a -
b).get_origin_tag(), first_two_merged_tag);
183 EXPECT_EQ(
a.dbl().get_origin_tag(), submitted_value_origin_tag);
184 EXPECT_EQ((-
a).get_origin_tag(), submitted_value_origin_tag);
188 scalar.set_origin_tag(challenge_origin_tag);
189 EXPECT_EQ((
a * scalar).get_origin_tag(), first_two_merged_tag);
193 predicate.set_origin_tag(challenge_origin_tag);
194 EXPECT_EQ(
a.conditional_negate(predicate).get_origin_tag(), first_two_merged_tag);
197 predicate.set_origin_tag(next_challenge_tag);
198 EXPECT_EQ(
a.conditional_select(
b, predicate).get_origin_tag(), first_second_third_merged_tag);
202 auto x = element_ct::BaseField::from_witness(&
builder, input_c.x);
203 auto y = element_ct::BaseField::from_witness(&
builder, input_c.y);
206 x.set_origin_tag(submitted_value_origin_tag);
207 y.set_origin_tag(challenge_origin_tag);
214 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
219 naf_scalar.set_origin_tag(submitted_value_origin_tag);
220 auto naf = element_ct::compute_naf(naf_scalar, 16);
221 for (
const auto& bit : naf) {
222 EXPECT_EQ(bit.get_origin_tag(), submitted_value_origin_tag);
232 auto x_death = element_ct::BaseField::from_witness(&
builder, input_death.x);
233 auto y_normal = element_ct::BaseField::from_witness(&
builder, input_death.y);
234 y_normal.set_origin_tag(constant_tag);
235 element_ct death_point(x_death, y_normal,
false);
237 death_point.x().set_origin_tag(instant_death_tag);
238 EXPECT_THROW(death_point + death_point, std::runtime_error);
269 for (
size_t i = 0; i < 3; ++i) {
274 point.assert_coordinates_in_field();
289 auto x_coord = element_ct::BaseField::from_witness(&
builder, valid_point.x);
290 auto y_coord = element_ct::BaseField::from_witness(&
builder, valid_point.y);
296 x_coord.set_limb_max(3,
uint256_t(1) << 68);
301 point.assert_coordinates_in_field();
312 auto x_coord = element_ct::BaseField::from_witness(&
builder, valid_point.x);
313 auto y_coord = element_ct::BaseField::from_witness(&
builder, valid_point.y);
319 y_coord.set_limb_max(3,
uint256_t(1) << 68);
324 point.assert_coordinates_in_field();
335 size_t num_repetitions = 10;
336 for (
size_t i = 0; i < num_repetitions; ++i) {
340 uint64_t before =
builder.get_num_finalized_gates_inefficient();
342 uint64_t after =
builder.get_num_finalized_gates_inefficient();
344 if (i == num_repetitions - 1) {
345 benchmark_info(Builder::NAME_STRING,
"Biggroup",
"ADD",
"Gate Count", after - before);
350 uint256_t c_x_u256 = c.x().get_value().lo;
351 uint256_t c_y_u256 = c.y().get_value().lo;
353 fq c_x_result(c_x_u256);
354 fq c_y_result(c_y_u256);
356 EXPECT_EQ(c_x_result, c_expected.x);
357 EXPECT_EQ(c_y_result, c_expected.y);
366 size_t num_repetitions = 10;
367 for (
size_t i = 0; i < num_repetitions; ++i) {
378 EXPECT_EQ(
fq(result_x), expected.x);
379 EXPECT_EQ(
fq(result_y), expected.y);
387 size_t num_repetitions = 1;
388 for (
size_t i = 0; i < num_repetitions; ++i) {
391 input_b.self_set_infinity();
411 EXPECT_EQ(c.get_value(), c_expected);
412 EXPECT_EQ(d.get_value(), d_expected);
413 EXPECT_EQ(e.get_value(), e_expected);
414 EXPECT_EQ(f.get_value(), f_expected);
415 EXPECT_EQ(g.get_value(), g_expected);
416 EXPECT_EQ(h.get_value(), h_expected);
428 size_t num_repetitions = 5;
429 for (
size_t i = 0; i < num_repetitions; ++i) {
432 element_ct input_b = element_ct::from_witness(&
builder, affine_element::infinity());
434 auto standard_a = input_a.get_standard_form();
435 auto standard_b = input_b.get_standard_form();
440 fq standard_a_x = standard_a.x().get_value().lo;
441 fq standard_a_y = standard_a.y().get_value().lo;
443 fq standard_b_x = standard_b.x().get_value().lo;
444 fq standard_b_y = standard_b.y().get_value().lo;
447 EXPECT_EQ(standard_a_x, 0);
448 EXPECT_EQ(standard_a_y, 0);
449 EXPECT_EQ(standard_b_x, 0);
450 EXPECT_EQ(standard_b_y, 0);
459 size_t num_repetitions = 10;
460 for (
size_t i = 0; i < num_repetitions; ++i) {
468 uint256_t c_x_u256 = c.x().get_value().lo;
469 uint256_t c_y_u256 = c.y().get_value().lo;
471 fq c_x_result(c_x_u256);
472 fq c_y_result(c_y_u256);
474 EXPECT_EQ(c_x_result, c_expected.x);
475 EXPECT_EQ(c_y_result, c_expected.y);
484 size_t num_repetitions = 10;
485 for (
size_t i = 0; i < num_repetitions; ++i) {
495 EXPECT_EQ(
fq(result_x), expected.x);
496 EXPECT_EQ(
fq(result_y), expected.y);
504 size_t num_repetitions = 1;
505 for (
size_t i = 0; i < num_repetitions; ++i) {
508 input_b.self_set_infinity();
528 EXPECT_EQ(c.get_value(), c_expected);
529 EXPECT_EQ(d.get_value(), d_expected);
530 EXPECT_EQ(e.get_value(), e_expected);
531 EXPECT_EQ(f.get_value(), f_expected);
532 EXPECT_EQ(g.get_value(), g_expected);
533 EXPECT_EQ(h.get_value(), h_expected);
543 size_t num_repetitions = 10;
544 for (
size_t i = 0; i < num_repetitions; ++i) {
554 EXPECT_EQ(
fq(result_x), expected.x);
555 EXPECT_EQ(
fq(result_y), expected.y);
564 size_t num_repetitions = 10;
565 for (
size_t i = 0; i < num_repetitions; ++i) {
575 EXPECT_EQ(
fq(result_x), expected.x);
576 EXPECT_EQ(
fq(result_y), expected.y);
585 size_t num_repetitions = 10;
586 for (
size_t i = 0; i < num_repetitions; ++i) {
598 uint256_t diff_x = diff.x().get_value().lo;
599 uint256_t diff_y = diff.y().get_value().lo;
601 EXPECT_EQ(
fq(sum_x), expected_sum.x);
602 EXPECT_EQ(
fq(sum_y), expected_sum.y);
603 EXPECT_EQ(
fq(diff_x), expected_diff.x);
604 EXPECT_EQ(
fq(diff_y), expected_diff.y);
612 size_t num_repetitions = 10;
613 for (
size_t i = 0; i < num_repetitions; ++i) {
620 uint256_t c_x_u256 = c.x().get_value().lo;
621 uint256_t c_y_u256 = c.y().get_value().lo;
623 fq c_x_result(c_x_u256);
624 fq c_y_result(c_y_u256);
626 EXPECT_EQ(c_x_result, c_expected.x);
627 EXPECT_EQ(c_y_result, c_expected.y);
638 input_infinity.self_set_infinity();
641 element_ct result_infinity = a_infinity.dbl();
658 uint256_t result_x = result_normal.x().get_value().lo;
659 uint256_t result_y = result_normal.y().get_value().lo;
660 fq expected_x(result_x);
661 fq expected_y(result_y);
662 EXPECT_EQ(expected_x, expected_normal.x);
663 EXPECT_EQ(expected_y, expected_normal.y);
680 auto x_coord = element_ct::BaseField::from_witness(&
builder, test_point.x);
681 auto y_coord = element_ct::BaseField::from_witness(&
builder,
fq(0));
695 size_t num_repetitions = 5;
696 for (
size_t i = 0; i < num_repetitions; ++i) {
705 uint256_t dbl_x = doubled.x().get_value().lo;
706 uint256_t dbl_y = doubled.y().get_value().lo;
708 EXPECT_EQ(
fq(sum_x),
fq(dbl_x));
709 EXPECT_EQ(
fq(sum_y),
fq(dbl_y));
719 size_t num_repetitions = 5;
720 for (
size_t i = 0; i < num_repetitions; ++i) {
730 uint256_t expected_x = expected.x().get_value().lo;
731 uint256_t expected_y = expected.y().get_value().lo;
733 EXPECT_EQ(
fq(result_x),
fq(expected_x));
734 EXPECT_EQ(
fq(result_y),
fq(expected_y));
744 size_t num_repetitions = 10;
745 for (
size_t i = 0; i < num_repetitions; ++i) {
751 auto acc = element_ct::chain_add_start(
a,
b);
752 auto acc_out = element_ct::chain_add(c, acc);
759 EXPECT_EQ(
fq(result_x), expected.x);
760 EXPECT_EQ(
fq(result_y), expected.y);
763 auto lambda_prev = (input_b.y - input_a.y) / (input_b.x - input_a.x);
764 auto x3_prev = lambda_prev * lambda_prev - input_b.x - input_a.x;
765 auto y3_prev = lambda_prev * (input_a.x - x3_prev) - input_a.y;
766 auto lambda = (y3_prev - input_c.y) / (x3_prev - input_c.x);
767 auto x3 = lambda * lambda - x3_prev - input_c.x;
769 uint256_t x3_u256 = acc_out.x3_prev.get_value().lo;
770 uint256_t lambda_u256 = acc_out.lambda_prev.get_value().lo;
772 fq x3_result(x3_u256);
773 fq lambda_result(lambda_u256);
775 EXPECT_EQ(x3_result, x3);
776 EXPECT_EQ(lambda_result, lambda);
785 size_t num_repetitions = 10;
786 for (
size_t i = 0; i < num_repetitions; ++i) {
791 for (
size_t j = 0; j < i; ++j) {
796 typename element_ct::chain_add_accumulator add_1 =
797 element_ct::chain_add_start(add_1_big_0, add_2_big_0);
798 to_add.emplace_back(add_1);
800 acc_big.multiple_montgomery_ladder(to_add);
809 size_t num_repetitions = 10;
810 for (
size_t i = 0; i < num_repetitions; ++i) {
818 uint256_t x_after = normalized.x().get_value().lo;
819 uint256_t y_after = normalized.y().get_value().lo;
821 EXPECT_EQ(
fq(x_before),
fq(x_after));
822 EXPECT_EQ(
fq(y_before),
fq(y_after));
830 size_t num_repetitions = 10;
831 for (
size_t i = 0; i < num_repetitions; ++i) {
839 uint256_t x_after = reduced.x().get_value().lo;
840 uint256_t y_after = reduced.y().get_value().lo;
842 EXPECT_EQ(
fq(x_before),
fq(x_after));
843 EXPECT_EQ(
fq(y_before),
fq(y_after));
861 EXPECT_EQ(
fq(neg_x), expected.x);
862 EXPECT_EQ(
fq(neg_y), expected.y);
871 size_t num_repetitions = 10;
872 for (
size_t i = 0; i < num_repetitions; ++i) {
884 EXPECT_EQ(c.get_value(), c_expected);
894 size_t num_repetitions = 10;
895 for (
size_t i = 0; i < num_repetitions; ++i) {
906 EXPECT_EQ(c.get_value(), c_expected);
916 size_t num_repetitions = 10;
917 for (
size_t i = 0; i < num_repetitions; ++i) {
922 a.incomplete_assert_equal(
b,
"elements don't match");
929 size_t num_repetitions = 10;
930 for (
size_t i = 0; i < num_repetitions; ++i) {
932 input_a.self_set_infinity();
936 a.incomplete_assert_equal(
b,
"elements don't match");
946 a.incomplete_assert_equal(
a,
"self assertion test");
960 while (input_a == input_b) {
961 input_b = element::random_element();
966 a.incomplete_assert_equal(
b,
"elements don't match");
970 EXPECT_EQ(
builder.failed(),
true);
971 EXPECT_EQ(
builder.err(),
"elements don't match (x coordinate)");
982 input_b.y = -input_a.y;
985 auto x_coord = element_ct::BaseField::from_witness(&
builder, input_a.x);
986 auto y_coord_a = element_ct::BaseField::from_witness(&
builder, input_a.y);
987 auto y_coord_b = element_ct::BaseField::from_witness(&
builder, input_b.y);
993 a.incomplete_assert_equal(
b,
"elements don't match");
996 EXPECT_EQ(
builder.failed(),
true);
997 EXPECT_EQ(
builder.err(),
"elements don't match (y coordinate)");
1005 input_a.self_set_infinity();
1009 a.incomplete_assert_equal(
b,
"infinity flag mismatch test");
1011 EXPECT_EQ(
builder.failed(),
true);
1014 EXPECT_EQ(
builder.err(),
"infinity flag mismatch test (x coordinate)");
1016 EXPECT_EQ(
builder.err(),
"infinity flag mismatch test (infinity flag)");
1024 size_t max_num_bits = 254;
1025 for (
size_t length = 2; length < max_num_bits; length += 1) {
1030 scalar_raw = scalar_raw >> (256 - length);
1032 scalar_val =
fr(scalar_raw);
1035 if (scalar_val ==
fr(0)) {
1039 auto naf = element_ct::compute_naf(scalar, length);
1042 fr reconstructed_val(0);
1043 for (
size_t i = 0; i < length; i++) {
1044 reconstructed_val += (
fr(1) -
fr(2) *
fr(naf[i].get_value())) *
fr(
uint256_t(1) << (length - 1 - i));
1046 reconstructed_val -=
fr(naf[length].get_value());
1047 EXPECT_EQ(scalar_val, reconstructed_val);
1055 for (
size_t max_num_bits : { 0UL, 1UL, 2UL, 64UL, 128UL }) {
1059 auto naf = element_ct::compute_naf(scalar, max_num_bits);
1060 ASSERT_FALSE(naf.empty());
1063 const size_t length = naf.size() - 1;
1064 EXPECT_FALSE(naf[0].get_value());
1065 EXPECT_TRUE(naf[length].get_value());
1066 for (
size_t k = 1; k < length; ++k) {
1067 EXPECT_TRUE(naf[k].get_value());
1071 fr reconstructed(0);
1072 for (
size_t i = 0; i < length; ++i) {
1073 reconstructed += (
fr(1) -
fr(2) *
fr(naf[i].get_value())) *
fr(
uint256_t(1) << (length - 1 - i));
1075 reconstructed -=
fr(naf[length].get_value());
1076 EXPECT_EQ(reconstructed,
fr(0));
1092 scalar_raw = (scalar_raw >> 136) << 136;
1093 fr scalar_val =
fr(scalar_raw);
1101 auto naf = element_ct::compute_naf(scalar, length);
1104 for (
const auto& bit : naf) {
1105 EXPECT_EQ(bit.get_origin_tag(), submitted_value_origin_tag);
1109 fr reconstructed_val(0);
1110 for (
size_t i = 0; i < length; i++) {
1111 reconstructed_val += (
fr(1) -
fr(2) *
fr(naf[i].get_value())) *
fr(
uint256_t(1) << (length - 1 - i));
1113 reconstructed_val -=
fr(naf[length].get_value());
1115 EXPECT_EQ(scalar_val, reconstructed_val);
1125 GTEST_SKIP() <<
"composite-Fr reconstruction uses a different witness layout";
1140 auto naf = element_ct::compute_naf(scalar, num_rounds);
1150 (target_int < top_pow) ? target_int + top_pow : target_int + top_pow -
fr::modulus;
1151 const uint64_t skew = shifted_scalar.
get_bit(0) ? 0 : 1;
1152 const uint256_t lower_bits_int = (range_size - 1 - shifted_scalar - skew) / 2;
1155 builder.set_variable(naf[0].get_witness_index(),
fr(1));
1156 builder.set_variable(naf[num_rounds].get_witness_index(),
fr(skew));
1157 for (
size_t k = 1; k < num_rounds; ++k) {
1158 builder.set_variable(naf[k].get_witness_index(),
1159 fr(lower_bits_int.
get_bit(num_rounds - 1 - k) ? 1 : 0));
1163 const size_t num_inputs = num_rounds + 1;
1164 const size_t num_gates = (num_inputs + 2) / 3;
1165 const size_t padded_size = num_gates * 3;
1166 const uint32_t accumulate_start_idx = naf[0].get_witness_index() + 1;
1168 std::vector<fr> summands(padded_size,
fr(0));
1169 for (
size_t i = 0; i < num_rounds; ++i) {
1170 const fr naf_bit =
builder.get_variable(naf[num_rounds - 1 - i].get_witness_index());
1173 summands[num_rounds] = -
builder.get_variable(naf[num_rounds].get_witness_index());
1175 fr accumulator = std::accumulate(summands.begin(), summands.end(),
fr(0));
1176 EXPECT_EQ(accumulator, scalar_val) <<
"rebalance arithmetic should give a field-equivalent reconstruction";
1177 builder.set_variable(accumulate_start_idx, accumulator);
1178 for (
size_t gate_idx = 0; gate_idx + 1 < num_gates; ++gate_idx) {
1179 accumulator -= summands[3 * gate_idx] + summands[(3 * gate_idx) + 1] + summands[(3 * gate_idx) + 2];
1180 builder.set_variable(accumulate_start_idx + 1 +
static_cast<uint32_t
>(gate_idx), accumulator);
1184 <<
"compute_naf must reject the malicious top-bit-flipped NAF assignment";
1194 constexpr size_t max_num_bits = 128;
1198 for (
size_t k = 0; k < 2; ++k) {
1201 (void)element_ct::compute_naf(scalar, max_num_bits);
1204 EXPECT_EQ(builders[0].blocks, builders[1].blocks);
1210 size_t num_repetitions = 1;
1211 for (
size_t i = 0; i < num_repetitions; ++i) {
1220 fq c_x_result(c.x().get_value().lo);
1221 fq c_y_result(c.y().get_value().lo);
1223 EXPECT_EQ(c_x_result, c_expected.x);
1224 EXPECT_EQ(c_y_result, c_expected.y);
1241 bool expected_is_inf = expected.is_point_at_infinity();
1243 EXPECT_EQ(result_is_inf, expected_is_inf);
1246 if (!expected_is_inf) {
1250 EXPECT_EQ(
fq(result_x), expected.x);
1251 EXPECT_EQ(
fq(result_y), expected.y);
1261 run_mul_and_check(P, x, expected_infinity);
1267 P = element_ct::constant_infinity(&
builder);
1269 input.self_set_infinity();
1270 P = element_ct::from_witness(&
builder, input);
1275 run_mul_and_check(P, x, expected_infinity);
1282 run_mul_and_check(P, one, input);
1287 fr neg_one = -
fr(1);
1291 run_mul_and_check(P, neg_one_ct, expected);
1301 std::vector<size_t> test_lengths = { 2, 3, 10, 11, 31, 32, 63, 64, 127, 128, 252, 253 };
1303 for (
size_t i : test_lengths) {
1308 scalar_raw = scalar_raw >> (256 - i);
1309 fr scalar =
fr(scalar_raw);
1312 if (scalar ==
fr(0)) {
1325 fq c_x_result(c.x().get_value().lo);
1326 fq c_y_result(c.y().get_value().lo);
1328 EXPECT_EQ(c_x_result, c_expected.x);
1330 EXPECT_EQ(c_y_result, c_expected.y);
1346 points[0] = element::infinity();
1347 points[1] = element::random_element();
1348 std::vector<size_t> gates(2);
1350 bool expect_infinity =
true;
1351 for (
auto [point, num_gates] :
zip_view(points, gates)) {
1354 const size_t max_num_bits = 128;
1356 fr scalar =
fr(scalar_raw);
1361 element_ct c = P.scalar_mul(x, max_num_bits);
1362 num_gates =
builder.get_num_finalized_gates_inefficient();
1366 expect_infinity =
false;
1368 EXPECT_EQ(gates[0], gates[1]);
1374 size_t num_repetitions = 1;
1375 for (
size_t i = 0; i < num_repetitions; ++i) {
1380 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
1383 if ((
uint256_t(scalar_b).get_bit(0) & 1) == 0) {
1391 element_ct c = element_ct::batch_mul({ P_a, P_b }, { x_a, x_b });
1396 fq c_x_result(c.x().get_value().lo);
1397 fq c_y_result(c.y().get_value().lo);
1399 EXPECT_EQ(c_x_result, expected.x);
1400 EXPECT_EQ(c_y_result, expected.y);
1408 size_t num_repetitions = 1;
1409 for (
size_t i = 0; i < num_repetitions; ++i) {
1412 input_b.self_set_infinity();
1415 const size_t max_num_bits = 128;
1417 scalar_raw_a = scalar_raw_a >> (256 - max_num_bits);
1418 fr scalar_a =
fr(scalar_raw_a);
1421 scalar_raw_b = scalar_raw_b >> (256 - max_num_bits);
1422 fr scalar_b =
fr(scalar_raw_b);
1429 element_ct c = element_ct::batch_mul({ P_a, P_b }, { x_a, x_b }, 128);
1434 fq c_x_result(c.x().get_value().lo);
1435 fq c_y_result(c.y().get_value().lo);
1437 EXPECT_EQ(c_x_result, expected.x);
1438 EXPECT_EQ(c_y_result, expected.y);
1461 std::vector<fr> input_scalars = { scalar_a, scalar_b, scalar_c };
1465 for (
size_t i = 0; i < 3; ++i) {
1468 scalars.emplace_back(scalar);
1469 points.emplace_back(point);
1482 fq c_x_result(c.x().get_value().lo);
1483 fq c_y_result(c.y().get_value().lo);
1485 EXPECT_EQ(c_x_result, expected.x);
1486 EXPECT_EQ(c_y_result, expected.y);
1505 std::vector<fr> input_scalars = { scalar_a, scalar_b, scalar_c };
1509 for (
size_t i = 0; i < 3; ++i) {
1511 points.emplace_back(point);
1514 scalars.emplace_back(scalar);
1519 element_ct::batch_mul(points, scalars, 4,
false);
1522 EXPECT_EQ(
builder.err(),
"bigfield: prime limb diff is zero, but expected non-zero");
1531 using BaseField =
typename element_ct::BaseField;
1535 for (
size_t i = 0; i < 2; ++i) {
1541 auto [_masked_points, _masked_scalars, offset_G] = stdlib::element_default::element_test_accessor::
1542 mask_points<Builder, typename element_ct::BaseField, scalar_ct, typename Curve::GroupNative>(
1543 circuit_points, circuit_scalars);
1549 for (
size_t i = 0; i < BaseField::NUM_LIMBS; ++i) {
1550 builder.set_variable(offset_G.x().get_limb(i).element.get_witness_index(), 0);
1551 builder.set_variable(offset_G.y().get_limb(i).element.get_witness_index(), 0);
1553 builder.set_variable(offset_G.is_point_at_infinity().get_witness_index(), 1);
1563 using BaseField =
typename element_ct::BaseField;
1567 for (
size_t i = 0; i < 2; ++i) {
1572 auto [masked_points, _masked_scalars, _offset_G] = stdlib::element_default::element_test_accessor::
1573 mask_points<Builder, typename element_ct::BaseField, scalar_ct, typename Curve::GroupNative>(
1574 circuit_points, circuit_scalars);
1579 for (
size_t i = 0; i < BaseField::NUM_LIMBS; ++i) {
1580 builder.set_variable(masked_points[0].x().get_limb(i).
element.get_witness_index(), 0);
1581 builder.set_variable(masked_points[0].y().get_limb(i).
element.get_witness_index(), 0);
1583 builder.set_variable(masked_points[0].is_point_at_infinity().get_witness_index(), 1);
1591 size_t num_repetitions = 1;
1592 for (
size_t i = 0; i < num_repetitions; ++i) {
1594 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
1602 fq c_x_result(c.x().get_value().lo);
1603 fq c_y_result(c.y().get_value().lo);
1605 EXPECT_EQ(c_x_result, expected.x);
1606 EXPECT_EQ(c_y_result, expected.y);
1614 const bool short_scalars =
false,
1615 const bool with_edgecases =
false)
1624 const bool short_scalars =
false,
1625 const bool with_edgecases =
false)
1629 const size_t num_points = point_types.size();
1631 std::vector<fr> scalars;
1635 for (
size_t i = 0; i < num_points; ++i) {
1637 if (short_scalars) {
1639 scalars.push_back(input_scalar);
1640 circuit_scalars.push_back(x);
1643 scalars.push_back(input_scalar);
1644 circuit_scalars.push_back(x);
1649 points.push_back(input_point);
1650 circuit_points.push_back(P);
1654 element_ct::batch_mul(circuit_points, circuit_scalars, 0, with_edgecases);
1658 for (
size_t i = 0; i < num_points; ++i) {
1659 expected_point += (
element(points[i]) * scalars[i]);
1662 expected_point = expected_point.normalize();
1663 fq result_x(result_point.x().get_value().lo);
1664 fq result_y(result_point.y().get_value().lo);
1666 EXPECT_EQ(result_x, expected_point.x);
1667 EXPECT_EQ(result_y, expected_point.y);
1674 const size_t num_points = 5;
1677 std::vector<fr> scalars;
1678 for (
size_t i = 0; i < num_points; ++i) {
1685 for (
size_t i = 0; i < num_points; ++i) {
1686 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1690 element_ct result_point = element_ct::batch_mul(circuit_points, circuit_scalars);
1694 for (
size_t i = 0; i < num_points; ++i) {
1695 expected_point += (
element(points[i]) * scalars[i]);
1698 expected_point = expected_point.normalize();
1699 fq result_x(result_point.x().get_value().lo);
1700 fq result_y(result_point.y().get_value().lo);
1702 EXPECT_EQ(result_x, expected_point.x);
1703 EXPECT_EQ(result_y, expected_point.y);
1710 const size_t num_points = 5;
1713 std::vector<fr> scalars;
1714 for (
size_t i = 0; i < num_points; ++i) {
1721 for (
size_t i = 0; i < num_points; ++i) {
1722 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1727 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1731 for (
size_t i = 0; i < num_points; ++i) {
1732 expected_point += (
element(points[i]) * scalars[i]);
1735 expected_point = expected_point.normalize();
1737 fq result2_x(result_point2.x().get_value().lo);
1738 fq result2_y(result_point2.y().get_value().lo);
1740 EXPECT_EQ(result2_x, expected_point.x);
1741 EXPECT_EQ(result2_y, expected_point.y);
1748 const auto test_repeated_points = [](
const uint32_t num_points) {
1750 info(
"num points: ", num_points);
1752 std::vector<fr> scalars;
1753 for (
size_t idx = 0; idx < num_points; idx++) {
1754 points.push_back(affine_element::one());
1755 scalars.push_back(1);
1759 ASSERT_EQ(points.size(), scalars.size());
1763 for (
size_t i = 0; i < num_points; ++i) {
1764 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1768 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1770 auto expected_point = element::infinity();
1771 for (
const auto& point : points) {
1772 expected_point += point;
1774 expected_point = expected_point.normalize();
1776 fq result_x(result_point.x().get_value().lo);
1777 fq result_y(result_point.y().get_value().lo);
1779 EXPECT_EQ(result_x, expected_point.x);
1780 EXPECT_EQ(result_y, expected_point.y);
1784 test_repeated_points(2);
1785 test_repeated_points(3);
1786 test_repeated_points(4);
1787 test_repeated_points(5);
1788 test_repeated_points(6);
1789 test_repeated_points(7);
1796 points.push_back(affine_element::infinity());
1798 std::vector<fr> scalars;
1799 scalars.push_back(1);
1800 scalars.push_back(1);
1803 ASSERT_EQ(points.size(), scalars.size());
1804 const size_t num_points = points.size();
1808 for (
size_t i = 0; i < num_points; ++i) {
1809 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1814 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1816 element expected_point = points[1];
1817 expected_point = expected_point.normalize();
1819 fq result_x(result_point.x().get_value().lo);
1820 fq result_y(result_point.y().get_value().lo);
1822 EXPECT_EQ(result_x, expected_point.x);
1823 EXPECT_EQ(result_y, expected_point.y);
1832 std::vector<fr> scalars;
1833 scalars.push_back(0);
1834 scalars.push_back(1);
1837 ASSERT_EQ(points.size(), scalars.size());
1838 const size_t num_points = points.size();
1842 for (
size_t i = 0; i < num_points; ++i) {
1843 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1848 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1850 element expected_point = points[1];
1851 expected_point = expected_point.normalize();
1853 fq result_x(result_point.x().get_value().lo);
1854 fq result_y(result_point.y().get_value().lo);
1856 EXPECT_EQ(result_x, expected_point.x);
1857 EXPECT_EQ(result_y, expected_point.y);
1868 std::vector<fr> scalars;
1870 for (
size_t i = 0; i < 5; ++i) {
1871 points.push_back(affine_element::infinity());
1878 for (
size_t i = 0; i < points.size(); ++i) {
1879 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1883 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1895 std::vector<fr> scalars;
1897 for (
size_t i = 0; i < 5; ++i) {
1905 for (
size_t i = 0; i < points.size(); ++i) {
1906 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1910 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1922 std::vector<fr> scalars;
1924 for (
size_t i = 0; i < 6; ++i) {
1933 for (
size_t i = 0; i < points.size(); ++i) {
1934 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1938 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1941 element expected = element::infinity();
1942 for (
size_t i = 0; i < points.size(); ++i) {
1943 expected += (
element(points[i]) * scalars[i]);
1950 EXPECT_EQ(
fq(result_x), expected_affine.x);
1951 EXPECT_EQ(
fq(result_y), expected_affine.y);
1961 constexpr size_t max_num_bits = 128;
1962 constexpr size_t num_points = 4;
1966 for (
size_t i = 0; i < num_points; ++i) {
1967 input_points.push_back(
affine_element(element::random_element()));
1969 scalar_assignments[0].push_back(
fr(s_raw));
1970 scalar_assignments[1].push_back((i % 2 == 0) ?
fr::zero() :
fr(s_raw));
1974 for (
size_t k = 0; k < 2; ++k) {
1978 for (
size_t i = 0; i < num_points; ++i) {
1979 circuit_points.push_back(element_ct::from_witness(&
builder, input_points[i]));
1984 element_ct::batch_mul(circuit_points, circuit_scalars, max_num_bits,
false);
1986 element expected = element::infinity();
1987 for (
size_t i = 0; i < num_points; ++i) {
1988 expected += (
element(input_points[i]) * scalar_assignments[k][i]);
1991 if (expected_affine.is_point_at_infinity()) {
1994 const uint256_t result_x = circuit_result.x().get_value().lo;
1995 const uint256_t result_y = circuit_result.y().get_value().lo;
1996 EXPECT_EQ(
fq(result_x), expected_affine.x);
1997 EXPECT_EQ(
fq(result_y), expected_affine.y);
2003 EXPECT_EQ(builders[0].blocks, builders[1].blocks);
2011 std::vector<fr> scalars;
2013 for (
size_t i = 0; i < 6; ++i) {
2015 points.push_back((i % 2 == 0) ? affine_element::infinity() :
affine_element(element::random_element()));
2022 for (
size_t i = 0; i < points.size(); ++i) {
2023 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
2027 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
2030 element expected = element::infinity();
2031 for (
size_t i = 0; i < points.size(); ++i) {
2032 if (!points[i].is_point_at_infinity()) {
2033 expected += (
element(points[i]) * scalars[i]);
2041 EXPECT_EQ(
fq(result_x), expected_affine.x);
2042 EXPECT_EQ(
fq(result_y), expected_affine.y);
2052 std::vector<fr> scalars;
2059 points.push_back(P);
2060 scalars.push_back(scalar);
2061 points.push_back(neg_P);
2062 scalars.push_back(scalar);
2065 for (
size_t i = 0; i < 3; ++i) {
2073 for (
size_t i = 0; i < points.size(); ++i) {
2074 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
2078 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
2081 element expected = element::infinity();
2082 for (
size_t i = 0; i < points.size(); ++i) {
2083 expected += (
element(points[i]) * scalars[i]);
2090 EXPECT_EQ(
fq(result_x), expected_affine.x);
2091 EXPECT_EQ(
fq(result_y), expected_affine.y);
2101 std::vector<fr> scalars_native;
2106 for (
size_t i = 0; i < 3; ++i) {
2109 points_native.push_back(point);
2110 scalars_native.push_back(scalar);
2111 circuit_points.push_back(point_ct);
2116 for (
size_t i = 0; i < 3; ++i) {
2119 points_native.push_back(point);
2120 scalars_native.push_back(scalar);
2121 circuit_points.push_back(point_ct);
2126 for (
size_t i = 0; i < 4; ++i) {
2129 points_native.push_back(point);
2130 scalars_native.push_back(scalar);
2131 circuit_points.push_back(
element_ct(point.x, point.y));
2136 for (
size_t i = 0; i < 4; ++i) {
2139 points_native.push_back(point);
2140 scalars_native.push_back(scalar);
2141 circuit_points.push_back(point_ct);
2145 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars);
2148 element expected = element::infinity();
2149 for (
size_t i = 0; i < points_native.size(); ++i) {
2150 expected += (
element(points_native[i]) * scalars_native[i]);
2157 EXPECT_EQ(
fq(result_x), expected_affine.x);
2158 EXPECT_EQ(
fq(result_y), expected_affine.y);
2168 std::vector<fr> scalars;
2169 constexpr size_t num_points = 20;
2171 for (
size_t i = 0; i < num_points; ++i) {
2179 for (
size_t i = 0; i < points.size(); ++i) {
2180 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
2184 element_ct result = element_ct::batch_mul(circuit_points, circuit_scalars);
2187 element expected = element::infinity();
2188 for (
size_t i = 0; i < points.size(); ++i) {
2189 expected += (
element(points[i]) * scalars[i]);
2196 EXPECT_EQ(
fq(result_x), expected_affine.x);
2197 EXPECT_EQ(
fq(result_y), expected_affine.y);
2212 EXPECT_EQ(
fq(inf.x().get_value().lo),
fq(0));
2213 EXPECT_EQ(
fq(inf.y().get_value().lo),
fq(0));
2225 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2226 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2236 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2237 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2247 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2248 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2257 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2258 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2279 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2280 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2294 EXPECT_EQ(
fq(
result.x().get_value().lo), input_a.x);
2295 EXPECT_EQ(
fq(
result.y().get_value().lo), input_a.y);
2309 EXPECT_EQ(
fq(
result.x().get_value().lo), input.x);
2310 EXPECT_EQ(
fq(
result.y().get_value().lo), input.y);
2331 EXPECT_EQ(
fq(
result.x().get_value().lo), input_a.x);
2332 EXPECT_EQ(
fq(
result.y().get_value().lo), input_a.y);
2368 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2369 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2394 EXPECT_EQ(
fq(P.x().get_value().lo),
fq(0));
2395 EXPECT_EQ(
fq(P.y().get_value().lo),
fq(0));
2399 element_ct standardized = P.get_standard_form();
2401 EXPECT_EQ(
fq(standardized.x().get_value().lo),
fq(0));
2402 EXPECT_EQ(
fq(standardized.y().get_value().lo),
fq(0));
2413 auto x_zero = element_ct::BaseField::from_witness(&
builder,
fq(0));
2414 auto y_zero = element_ct::BaseField::from_witness(&
builder,
fq(0));
2436 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2437 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2448 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2449 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2476 element_ct::from_witness(&
builder, P),
2477 element_ct::from_witness(&
builder, Q),
2478 element_ct::from_witness(&
builder, P),
2479 element_ct::from_witness(&
builder, Q),
2490 EXPECT_EQ(
fq(
result.x().get_value().lo),
fq(0));
2491 EXPECT_EQ(
fq(
result.y().get_value().lo),
fq(0));
2509 EXPECT_EQ(
fq(
result.x().get_value().lo), input.x);
2510 EXPECT_EQ(
fq(
result.y().get_value().lo), input.y);
2515 EXPECT_EQ(
fq(result2.x().get_value().lo), input.x);
2516 EXPECT_EQ(
fq(result2.y().get_value().lo), input.y);
2537 EXPECT_EQ(
fq(
result.x().get_value().lo), input2.x);
2538 EXPECT_EQ(
fq(
result.y().get_value().lo), input2.y);
2542 EXPECT_EQ(
fq(result2.x().get_value().lo), input2.x);
2543 EXPECT_EQ(
fq(result2.y().get_value().lo), input2.y);
2585 using Builder = TestFixture::Builder;
2587 using Fq = TestFixture::Curve::BaseField;
2588 using FqNative = TestFixture::Curve::BaseFieldNative;
2589 using GroupNative = TestFixture::Curve::GroupNative;
2592 auto [native_point, witness_point] = TestFixture::get_random_witness_point(&
builder);
2595 Fq expected_zero = witness_point.validate_on_curve(
"biggroup::validate_on_curve",
false);
2596 expected_zero.assert_equal(
Fq::zero());
2597 EXPECT_EQ(expected_zero.get_value(),
static_cast<uint512_t>(FqNative::zero()));
2600 Fq random_x = Fq::from_witness(&
builder, FqNative::random_element());
2601 Fq random_y = Fq::from_witness(&
builder, FqNative::random_element());
2602 element_ct invalid_point(random_x, random_y,
false);
2603 Fq expected_non_zero = invalid_point.validate_on_curve(
"biggroup::validate_on_curve",
false);
2604 Fq expected_value = -random_y.
sqr() + random_x.
pow(3) +
Fq(
uint256_t(GroupNative::curve_b));
2605 if constexpr (GroupNative::has_a) {
2606 expected_value += random_x *
Fq(
uint256_t(GroupNative::curve_a));
2608 expected_non_zero.assert_equal(expected_value);
2611 expected_non_zero.self_reduce();
2612 expected_value.self_reduce();
2613 EXPECT_EQ(expected_non_zero.get_value(), expected_value.get_value());
2615 TestFixture::EXPECT_CIRCUIT_CORRECTNESS(
builder);
2618 [[maybe_unused]]
Fq _ = invalid_point.validate_on_curve();
2619 TestFixture::EXPECT_CIRCUIT_CORRECTNESS(
builder,
false);
2625 TestFixture::test_basic_tag_logic();
2630 TestFixture::test_assert_coordinates_in_field();
2636 TestFixture::test_add();
2646 TestFixture::test_add_points_at_infinity();
2650 TestFixture::test_standard_form_of_point_at_infinity();
2656 TestFixture::test_sub();
2666 TestFixture::test_sub_points_at_infinity();
2670 TestFixture::test_dbl();
2678 TestFixture::test_dbl_with_infinity();
2683 GTEST_SKIP() <<
"mega builder does not support this edge case";
2685 TestFixture::test_dbl_with_y_zero();
2690 TestFixture::test_add_equals_dbl();
2694 TestFixture::test_sub_neg_equals_double();
2701 GTEST_SKIP() <<
"mega builder does not implement chain_add function";
2703 TestFixture::test_chain_add();
2709 GTEST_SKIP() <<
"mega builder does not implement chain_add function";
2726 GTEST_SKIP() <<
"mega builder does not implement multiple_montgomery_ladder function";
2728 TestFixture::test_multiple_montgomery_ladder();
2735 TestFixture::test_normalize();
2745 TestFixture::test_reduce();
2810 TestFixture::test_checked_unconditional_add_sub();
2821 TestFixture::test_conditional_negate();
2832 TestFixture::test_conditional_select();
2846 TestFixture::test_incomplete_assert_equal();
2850 TestFixture::test_incomplete_assert_equal_failure();
2856 size_t num_repetitions = 1;
2857 for (
size_t i = 0; i < num_repetitions; i++) {
2858 TestFixture::test_compute_naf();
2861 GTEST_SKIP() <<
"mega builder does not implement compute_naf function";
2868 TestFixture::test_compute_naf_zero();
2870 GTEST_SKIP() <<
"mega builder does not implement compute_naf function";
2877 TestFixture::test_compute_naf_overflow_lower_half();
2879 GTEST_SKIP() <<
"mega builder does not implement compute_naf function";
2886 TestFixture::test_compute_naf_top_bit_rejects_malicious_witness();
2888 GTEST_SKIP() <<
"mega builder does not implement compute_naf function";
2895 TestFixture::test_compute_naf_witness_value_independence();
2897 GTEST_SKIP() <<
"mega builder does not implement compute_naf function";
2903 TestFixture::test_mul();
2913 TestFixture::test_mul_edge_cases();
2925 GTEST_SKIP() <<
"mega builder does not implement scalar_mul function";
2927 TestFixture::test_short_scalar_mul_with_bit_lengths();
2934 GTEST_SKIP() <<
"mega builder does not implement scalar_mul function";
2936 TestFixture::test_short_scalar_mul_infinity();
2944 TestFixture::test_helper_batch_mul(1);
2950 TestFixture::test_helper_batch_mul(2);
2954 TestFixture::test_helper_batch_mul(2,
true);
2958 TestFixture::test_helper_batch_mul(2,
false,
true);
2962 TestFixture::test_helper_batch_mul(2,
true,
true);
2973 TestFixture::test_helper_batch_mul(3);
2979 TestFixture::test_helper_batch_mul(4);
2985 TestFixture::test_helper_batch_mul(5);
2989 TestFixture::test_helper_batch_mul(5,
false,
true);
2993 TestFixture::test_helper_batch_mul(5,
true);
2997 TestFixture::test_helper_batch_mul(5,
true,
true);
3001 TestFixture::test_helper_batch_mul(
3009 TestFixture::test_helper_batch_mul(6);
3014 TestFixture::test_twin_mul();
3019 TestFixture::test_twin_mul_with_infinity();
3024 TestFixture::test_batch_mul_linearly_dependent_generators();
3030 GTEST_SKIP() <<
"this failure test is designed for ultra builder only";
3032 TestFixture::test_batch_mul_linearly_dependent_generators_failure();
3039 GTEST_SKIP() <<
"mask_points is only used on the ultra path";
3041 TestFixture::test_offset_generator_infinity_is_rejected();
3048 GTEST_SKIP() <<
"mask_points is only used on the ultra path";
3050 TestFixture::test_masked_point_infinity_is_rejected();
3056 TestFixture::test_one();
3061 TestFixture::test_batch_mul();
3066 TestFixture::test_batch_mul_edgecase_equivalence();
3070 TestFixture::test_batch_mul_edge_case_set1();
3075 TestFixture::test_batch_mul_edge_case_set2();
3081 TestFixture::test_batch_mul_all_infinity();
3086 TestFixture::test_batch_mul_all_zero_scalars();
3091 TestFixture::test_batch_mul_mixed_zero_scalars();
3097 GTEST_SKIP() <<
"mega builder uses goblin_element batch_mul; the witness-value partition is in the ultra path";
3099 TestFixture::test_batch_mul_short_scalars_witness_value_independence();
3105 TestFixture::test_batch_mul_mixed_infinity();
3110 TestFixture::test_batch_mul_cancellation();
3115 TestFixture::test_batch_mul_mixed_constant_witness();
3120 TestFixture::test_batch_mul_large_number_of_points();
3126 TestFixture::test_infinity_canonical_representation();
3131 TestFixture::test_infinity_chained_operations();
3136 TestFixture::test_conditional_select_with_infinity();
3141 TestFixture::test_conditional_negate_with_infinity();
3146 TestFixture::test_get_standard_form_normalizes_infinity();
3151 TestFixture::test_infinity_auto_detection_in_constructor();
3156 TestFixture::test_scalar_mul_infinity_edge_cases();
3161 TestFixture::test_batch_mul_complete_cancellation();
3166 TestFixture::test_add_constant_infinity();
3171 TestFixture::test_witness_infinity_from_operations();
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
#define BB_DISABLE_ASSERTS()
TestType< stdlib::secp256r1< bb::UltraCircuitBuilder >, stdlib::secp256r1< bb::UltraCircuitBuilder >::ScalarField, false > secp256r1_with_ultra
TestType< stdlib::bn254< bb::UltraCircuitBuilder >, stdlib::bn254< bb::UltraCircuitBuilder >::ScalarField, false > bn254_with_ultra
TestType< stdlib::bn254< bb::UltraCircuitBuilder >, bb::stdlib::bigfield< bb::UltraCircuitBuilder, bb::Bn254FrParams >, true > bn254_with_ultra_scalar_bigfield
TestType< stdlib::bn254< bb::MegaCircuitBuilder >, stdlib::bn254< bb::MegaCircuitBuilder >::ScalarField, false > bn254_with_mega
constexpr InputType operator!(InputType type)
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
BB_INLINE constexpr void self_set_infinity() noexcept
group_elements::affine_element< Fq, Fr, Params > affine_element
static constexpr element one
group_elements::element< Fq, Fr, Params > element
virtual uint8_t get_random_uint8()=0
virtual uint256_t get_random_uint256()=0
constexpr bool get_bit(uint64_t bit_index) const
constexpr uint64_t get_msb() const
static void set_limb_element(bigfield &bf, size_t i, const typename bigfield::field_ct &v)
void set_origin_tag(const bb::OriginTag &tag) const
static bigfield from_witness(Builder *ctx, const bb::field< T > &input)
static constexpr bool is_composite
Implements boolean logic in-circuit.
static auto checked_unconditional_add_sub(const element< C, Fq, Fr, G > &elem1, const element< C, Fq, Fr, G > &elem2)
static field_t from_witness(Builder *ctx, const bb::fr &input)
static void test_checked_unconditional_add_sub(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
static void test_sub_points_at_infinity()
static void test_sub_neg_equals_double()
static void test_helper_batch_mul(std::vector< InputType > point_types, std::vector< InputType > scalar_types, const bool short_scalars=false, const bool with_edgecases=false)
static void test_conditional_negate(InputType point_type=InputType::WITNESS, InputType predicate_type=InputType::WITNESS)
static void test_batch_mul_edgecase_equivalence()
static void test_reduce(InputType point_type=InputType::WITNESS)
static void test_twin_mul()
static void test_witness_infinity_from_operations()
static void test_add_points_at_infinity()
static void test_chain_add(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS, InputType c_type=InputType::WITNESS)
static void test_conditional_negate_with_infinity()
static void test_compute_naf()
typename g1::element element
static void test_multiple_montgomery_ladder()
static void test_batch_mul_cancellation()
static void test_add_constant_infinity()
static void test_masked_point_infinity_is_rejected()
static void test_dbl_with_infinity()
static std::pair< affine_element, element_ct > get_random_constant_point(Builder *builder)
static void test_compute_naf_zero()
static void test_mul(InputType scalar_type=InputType::WITNESS, InputType point_type=InputType::WITNESS)
static void test_batch_mul_mixed_infinity()
typename Curve::ScalarFieldNative fr
static void test_compute_naf_top_bit_rejects_malicious_witness()
static void test_batch_mul_edge_case_set2()
static std::pair< fr, scalar_ct > get_random_constant_scalar(Builder *builder, bool even=false)
static void test_get_standard_form_normalizes_infinity()
typename TestType::element_ct element_ct
static void test_assert_coordinates_in_field()
static std::pair< affine_element, element_ct > get_random_witness_point(Builder *builder)
static void test_infinity_auto_detection_in_constructor()
static void test_mul_edge_cases(InputType scalar_type=InputType::WITNESS, InputType point_type=InputType::WITNESS)
typename g1::affine_element affine_element
typename TestType::Curve Curve
static std::pair< fr, scalar_ct > get_random_witness_scalar(Builder *builder, bool even=false)
static void test_batch_mul_linearly_dependent_generators()
static void test_offset_generator_infinity_is_rejected()
static void test_conditional_select(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS, InputType predicate_type=InputType::WITNESS)
static void test_basic_tag_logic()
static void test_add(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
typename Curve::Builder Builder
static void test_conditional_select_with_infinity()
static void test_incomplete_assert_equal()
static void test_batch_mul_mixed_constant_witness()
static void test_twin_mul_with_infinity()
static void test_unary_negate(InputType a_type=InputType::WITNESS)
typename TestType::scalar_ct scalar_ct
stdlib::bool_t< Builder > bool_ct
static std::pair< fr, scalar_ct > get_random_scalar(Builder *builder, InputType type, bool even=false)
static void test_batch_mul_edge_case_set1()
static void test_checked_unconditional_subtract(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
static void test_short_scalar_mul_with_bit_lengths()
static void test_short_scalar_mul_infinity()
static void test_dbl(InputType a_type=InputType::WITNESS)
static void test_normalize(InputType point_type=InputType::WITNESS)
static void test_infinity_chained_operations()
static void test_batch_mul_short_scalars_witness_value_independence()
static void test_incomplete_assert_equal_failure()
static bool is_infinity(const element_ct &e)
static std::pair< fr, scalar_ct > get_random_short_scalar(Builder *builder, InputType type, size_t num_bits)
stdlib::witness_t< Builder > witness_ct
static void test_standard_form_of_point_at_infinity()
Check that converting a point at infinity into standard form ensures the coordinates are zeroes.
typename Curve::GroupNative g1
static void test_scalar_mul_infinity_edge_cases()
static void test_compute_naf_witness_value_independence()
typename Curve::BaseFieldNative fq
static void test_batch_mul_mixed_zero_scalars()
static void test_add_assign(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
static std::pair< affine_element, element_ct > get_random_point(Builder *builder, InputType type)
static void test_batch_mul_large_number_of_points()
static void test_dbl_with_y_zero()
static void test_sub_assign(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
static void test_batch_mul()
static void test_batch_mul_all_zero_scalars()
static void test_compute_naf_overflow_lower_half()
static void test_batch_mul_complete_cancellation()
static void test_add_equals_dbl()
static void test_helper_batch_mul(size_t num_points, const bool short_scalars=false, const bool with_edgecases=false)
static void test_sub(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
static void test_batch_mul_linearly_dependent_generators_failure()
static constexpr auto EXPECT_CIRCUIT_CORRECTNESS
static void test_infinity_canonical_representation()
static void test_batch_mul_all_infinity()
static void test_checked_unconditional_add(InputType a_type=InputType::WITNESS, InputType b_type=InputType::WITNESS)
void benchmark_info(Args...)
Info used to store circuit statistics during CI/CD with concrete structure. Writes straight to log.
secp256r1_ct::Group element_ct
uintx< uint256_t > uint512_t
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
Inner sum(Cont< Inner, Args... > const &in)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
testing::Types< VKTestParams< UltraFlavor, stdlib::recursion::honk::DefaultIO< UltraCircuitBuilder > >, VKTestParams< UltraFlavor, stdlib::recursion::honk::RollupIO >, VKTestParams< UltraKeccakFlavor, stdlib::recursion::honk::DefaultIO< UltraCircuitBuilder > >, VKTestParams< MegaFlavor, stdlib::recursion::honk::DefaultIO< MegaCircuitBuilder > > > TestTypes
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
#define STANDARD_TESTING_TAGS
bb::stdlib::element< typename Curve::Builder, typename Curve::BaseField, ScalarField_, typename Curve::GroupNative > bigfield_element
std::conditional_t< use_bigfield, bigfield_element, typename Curve::Group > element_ct
static constexpr uint256_t modulus
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr field sqr() const noexcept
BB_INLINE constexpr field reduce() const noexcept
reduce once, i.e., if the value is bigger than the modulus, subtract off the modulus once.
static constexpr field zero()
#define HEAVY_TYPED_TEST(x, y)