1#include "../biggroup/biggroup.hpp"
2#include "../bigfield/bigfield.hpp"
3#include "../bool/bool.hpp"
4#include "../field/field.hpp"
24template <
typename _Curve,
bool _use_bigfield = false>
struct TestType {
29 typename std::conditional<_use_bigfield, typename Curve::g1_bigfr_ct, typename Curve::Group>::type;
32 typename std::conditional<_use_bigfield, typename Curve::bigfr_ct, typename Curve::ScalarField>::type;
41 using fq =
typename Curve::BaseFieldNative;
42 using fr =
typename Curve::ScalarFieldNative;
43 using g1 =
typename Curve::GroupNative;
52 info(
"num gates = ",
builder.get_estimated_num_finalized_gates());
63 a.set_origin_tag(next_submitted_value_origin_tag);
65 EXPECT_EQ(
a.get_origin_tag(), next_submitted_value_origin_tag);
70 a.x.set_origin_tag(submitted_value_origin_tag);
71 a.y.set_origin_tag(challenge_origin_tag);
72 a.set_point_at_infinity(pif);
73 EXPECT_EQ(
a.get_origin_tag(), first_second_third_merged_tag);
79 b.set_origin_tag(instant_death_tag);
81 EXPECT_THROW(
b +
b, std::runtime_error);
87 size_t num_repetitions = 10;
88 for (
size_t i = 0; i < num_repetitions; ++i) {
96 a.set_origin_tag(submitted_value_origin_tag);
97 b.set_origin_tag(challenge_origin_tag);
99 uint64_t before =
builder.get_estimated_num_finalized_gates();
101 uint64_t after =
builder.get_estimated_num_finalized_gates();
104 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
105 if (i == num_repetitions - 1) {
107 benchmark_info(Builder::NAME_STRING,
"Biggroup",
"ADD",
"Gate Count", after - before);
115 fq c_x_result(c_x_u256);
116 fq c_y_result(c_y_u256);
118 EXPECT_EQ(c_x_result, c_expected.
x);
119 EXPECT_EQ(c_y_result, c_expected.
y);
128 size_t num_repetitions = 1;
129 for (
size_t i = 0; i < num_repetitions; ++i) {
140 a.set_origin_tag(submitted_value_origin_tag);
141 b.set_origin_tag(challenge_origin_tag);
142 a_alternate.set_origin_tag(next_challenge_tag);
144 const auto second_round_challenge_tag =
146 a_negated.set_origin_tag(second_round_challenge_tag);
156 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
157 EXPECT_EQ(d.get_origin_tag(), first_two_merged_tag);
158 EXPECT_EQ(e.get_origin_tag(), challenge_origin_tag);
159 EXPECT_EQ(f.get_origin_tag(), submitted_value_origin_tag);
160 EXPECT_EQ(g.get_origin_tag(), first_and_third_merged_tag);
161 EXPECT_EQ(h.get_origin_tag(),
OriginTag(submitted_value_origin_tag, second_round_challenge_tag));
170 EXPECT_EQ(c.get_value(), c_expected);
171 EXPECT_EQ(d.get_value(), d_expected);
172 EXPECT_EQ(e.get_value(), e_expected);
173 EXPECT_EQ(f.get_value(), f_expected);
174 EXPECT_EQ(g.get_value(), g_expected);
175 EXPECT_EQ(h.get_value(), h_expected);
187 size_t num_repetitions = 5;
188 for (
size_t i = 0; i < num_repetitions; ++i) {
190 element_ct input_a(element::random_element());
191 element_ct input_b = element_ct::from_witness(&
builder, element::random_element());
192 input_a.set_point_at_infinity(
true);
193 input_b.set_point_at_infinity(
true);
196 input_a.set_origin_tag(submitted_value_origin_tag);
197 input_b.set_origin_tag(challenge_origin_tag);
199 auto standard_a = input_a.get_standard_form();
200 auto standard_b = input_b.get_standard_form();
204 EXPECT_EQ(standard_a.get_origin_tag(), submitted_value_origin_tag);
205 EXPECT_EQ(standard_b.get_origin_tag(), challenge_origin_tag);
207 EXPECT_EQ(standard_a.is_point_at_infinity().get_value(),
true);
208 EXPECT_EQ(standard_b.is_point_at_infinity().get_value(),
true);
210 fq standard_a_x = standard_a.x.get_value().lo;
211 fq standard_a_y = standard_a.y.get_value().lo;
213 fq standard_b_x = standard_b.x.get_value().lo;
214 fq standard_b_y = standard_b.y.get_value().lo;
216 EXPECT_EQ(standard_a_x, 0);
217 EXPECT_EQ(standard_a_y, 0);
218 EXPECT_EQ(standard_b_x, 0);
219 EXPECT_EQ(standard_b_y, 0);
227 size_t num_repetitions = 10;
228 for (
size_t i = 0; i < num_repetitions; ++i) {
236 a.set_origin_tag(submitted_value_origin_tag);
237 b.set_origin_tag(challenge_origin_tag);
242 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
249 fq c_x_result(c_x_u256);
250 fq c_y_result(c_y_u256);
252 EXPECT_EQ(c_x_result, c_expected.
x);
253 EXPECT_EQ(c_y_result, c_expected.
y);
262 size_t num_repetitions = 1;
263 for (
size_t i = 0; i < num_repetitions; ++i) {
274 a.set_origin_tag(submitted_value_origin_tag);
275 b.set_origin_tag(challenge_origin_tag);
276 a_alternate.set_origin_tag(next_challenge_tag);
278 const auto second_round_challenge_tag =
280 a_negated.set_origin_tag(second_round_challenge_tag);
290 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
291 EXPECT_EQ(d.get_origin_tag(), first_two_merged_tag);
292 EXPECT_EQ(e.get_origin_tag(), challenge_origin_tag);
293 EXPECT_EQ(f.get_origin_tag(), submitted_value_origin_tag);
294 EXPECT_EQ(g.get_origin_tag(), first_and_third_merged_tag);
295 EXPECT_EQ(h.get_origin_tag(),
OriginTag(submitted_value_origin_tag, second_round_challenge_tag));
304 EXPECT_EQ(c.get_value(), c_expected);
305 EXPECT_EQ(d.get_value(), d_expected);
306 EXPECT_EQ(e.get_value(), e_expected);
307 EXPECT_EQ(f.get_value(), f_expected);
308 EXPECT_EQ(g.get_value(), g_expected);
309 EXPECT_EQ(h.get_value(), h_expected);
318 size_t num_repetitions = 10;
319 for (
size_t i = 0; i < num_repetitions; ++i) {
324 a.set_origin_tag(submitted_value_origin_tag);
329 EXPECT_EQ(c.get_origin_tag(), submitted_value_origin_tag);
336 fq c_x_result(c_x_u256);
337 fq c_y_result(c_y_u256);
339 EXPECT_EQ(c_x_result, c_expected.
x);
340 EXPECT_EQ(c_y_result, c_expected.
y);
349 size_t num_repetitions = 10;
350 for (
size_t i = 0; i < num_repetitions; ++i) {
353 a.set_origin_tag(submitted_value_origin_tag);
356 bool negate = (
engine.get_random_uint32() % 2) == 1;
363 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
366 EXPECT_EQ(c.get_value(), c_expected);
375 size_t num_repetitions = 10;
376 for (
size_t i = 0; i < num_repetitions; ++i) {
379 bool select_a = (
engine.get_random_uint32() % 2) == 1;
385 a.set_origin_tag(submitted_value_origin_tag);
386 b.set_origin_tag(challenge_origin_tag);
392 EXPECT_EQ(c.get_origin_tag(), first_second_third_merged_tag);
395 EXPECT_EQ(c.get_value(), c_expected);
406 size_t num_repetitions = 10;
407 for (
size_t i = 0; i < num_repetitions; ++i) {
413 a.set_origin_tag(submitted_value_origin_tag);
414 b.set_origin_tag(challenge_origin_tag);
416 a.incomplete_assert_equal(
b,
"elements don't match");
423 size_t num_repetitions = 10;
424 for (
size_t i = 0; i < num_repetitions; ++i) {
430 a.set_origin_tag(submitted_value_origin_tag);
431 b.set_origin_tag(challenge_origin_tag);
436 a.incomplete_assert_equal(
b,
"elements don't match");
446 a.incomplete_assert_equal(
a,
"self assertion test");
460 while (input_a == input_b) {
461 input_b = element::random_element();
467 a.set_origin_tag(submitted_value_origin_tag);
468 b.set_origin_tag(challenge_origin_tag);
470 a.incomplete_assert_equal(
b,
"elements don't match");
474 EXPECT_EQ(
builder.failed(),
true);
475 EXPECT_EQ(
builder.err(),
"elements don't match (x coordinate)");
483 while (input_a == input_b) {
484 input_b = element::random_element();
490 a.set_origin_tag(submitted_value_origin_tag);
491 b.set_origin_tag(challenge_origin_tag);
495 a.incomplete_assert_equal(
b,
"elements don't match");
498 EXPECT_EQ(
builder.failed(),
true);
499 EXPECT_EQ(
builder.err(),
"elements don't match (y coordinate)");
514 a.incomplete_assert_equal(
b,
"infinity flag mismatch test");
516 EXPECT_EQ(
builder.failed(),
true);
517 EXPECT_EQ(
builder.err(),
"infinity flag mismatch test (infinity flag)");
529 while (input_a == input_b) {
530 input_b = element::random_element();
536 a.set_point_at_infinity(is_infinity);
537 b.set_point_at_infinity(is_infinity);
540 a.set_origin_tag(submitted_value_origin_tag);
541 b.set_origin_tag(challenge_origin_tag);
543 a.incomplete_assert_equal(
b,
"points at infinity with different x,y should not be equal");
546 EXPECT_EQ(
builder.failed(),
true);
547 EXPECT_EQ(
builder.err(),
"points at infinity with different x,y should not be equal (x coordinate)");
553 size_t num_repetitions = 1;
554 for (
size_t i = 0; i < num_repetitions; ++i) {
562 a.set_origin_tag(submitted_value_origin_tag);
563 b.set_origin_tag(challenge_origin_tag);
568 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
575 fq c_x_result(c_x_u256);
576 fq c_y_result(c_y_u256);
578 EXPECT_EQ(c_x_result, c_expected.
x);
579 EXPECT_EQ(c_y_result, c_expected.
y);
588 size_t num_repetitions = 1;
589 for (
size_t i = 0; i < num_repetitions; ++i) {
599 x.set_origin_tag(challenge_origin_tag);
600 P.set_origin_tag(submitted_value_origin_tag);
608 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
609 fq c_x_result(c.x.get_value().lo);
610 fq c_y_result(c.y.get_value().lo);
612 EXPECT_EQ(c_x_result, c_expected.
x);
613 EXPECT_EQ(c_y_result, c_expected.
y);
623 const size_t max_num_bits = 128;
626 for (
size_t i = 2; i < max_num_bits; i += 2) {
631 scalar_raw = scalar_raw >> (256 - i);
632 fr scalar =
fr(scalar_raw);
635 if (scalar ==
fr(0)) {
643 x.set_origin_tag(challenge_origin_tag);
644 P.set_origin_tag(submitted_value_origin_tag);
653 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
654 fq c_x_result(c.x.get_value().lo);
655 fq c_y_result(c.y.get_value().lo);
657 EXPECT_EQ(c_x_result, c_expected.
x);
659 EXPECT_EQ(c_y_result, c_expected.
y);
668 const size_t max_num_bits = 254;
671 for (
size_t i = 128; i < max_num_bits; i += 2) {
676 scalar_raw = scalar_raw >> (256 - i);
677 fr scalar =
fr(scalar_raw);
683 x.set_origin_tag(challenge_origin_tag);
684 P.set_origin_tag(submitted_value_origin_tag);
693 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
694 fq c_x_result(c.x.get_value().lo);
695 fq c_y_result(c.y.get_value().lo);
697 EXPECT_EQ(c_x_result, c_expected.
x);
699 EXPECT_EQ(c_y_result, c_expected.
y);
714 points[0] = element::infinity();
715 points[1] = element::random_element();
717 std::vector<size_t> gates(2);
720 bool expect_infinity =
true;
722 for (
auto [point, num_gates] :
zip_view(points, gates)) {
725 const size_t max_num_bits = 128;
729 scalar_raw = scalar_raw >> (256 - max_num_bits);
730 fr scalar =
fr(scalar_raw);
736 x.set_origin_tag(challenge_origin_tag);
737 P.set_origin_tag(submitted_value_origin_tag);
742 num_gates =
builder.get_estimated_num_finalized_gates();
744 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
746 EXPECT_EQ(c.is_point_at_infinity().get_value(), expect_infinity);
749 expect_infinity =
false;
752 EXPECT_EQ(gates[0], gates[1]);
758 size_t num_repetitions = 1;
759 for (
size_t i = 0; i < num_repetitions; ++i) {
764 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
767 if ((
uint256_t(scalar_b).get_bit(0) & 1) == 0) {
776 P_a.set_origin_tag(submitted_value_origin_tag);
777 x_a.set_origin_tag(challenge_origin_tag);
778 P_b.set_origin_tag(next_submitted_value_origin_tag);
779 x_b.set_origin_tag(next_challenge_tag);
781 element_ct c = element_ct::batch_mul({ P_a, P_b }, { x_a, x_b });
784 EXPECT_EQ(c.get_origin_tag(), first_to_fourth_merged_tag);
788 fq c_x_result(c.x.get_value().lo);
789 fq c_y_result(c.y.get_value().lo);
791 EXPECT_EQ(c_x_result, expected.
x);
792 EXPECT_EQ(c_y_result, expected.
y);
800 size_t num_repetitions = 1;
801 for (
size_t i = 0; i < num_repetitions; ++i) {
808 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
811 if ((
uint256_t(scalar_b).get_bit(0) & 1) == 0) {
818 P_a.set_origin_tag(
OriginTag(0, 0,
true));
819 tag_union =
OriginTag(tag_union, P_a.get_origin_tag());
823 x_a.set_origin_tag(
OriginTag(0, 0,
false));
824 tag_union =
OriginTag(tag_union, x_a.get_origin_tag());
827 P_b.set_origin_tag(
OriginTag(0, 1,
true));
828 tag_union =
OriginTag(tag_union, P_b.get_origin_tag());
831 x_b.set_origin_tag(
OriginTag(0, 1,
false));
832 tag_union =
OriginTag(tag_union, x_b.get_origin_tag());
835 P_c.set_origin_tag(
OriginTag(0, 2,
true));
836 tag_union =
OriginTag(tag_union, P_c.get_origin_tag());
839 x_c.set_origin_tag(
OriginTag(0, 2,
false));
840 tag_union =
OriginTag(tag_union, x_c.get_origin_tag());
842 element_ct c = element_ct::batch_mul({ P_a, P_b, P_c }, { x_a, x_b, x_c });
844 EXPECT_EQ(c.get_origin_tag(), tag_union);
850 fq c_x_result(c.x.get_value().lo);
851 fq c_y_result(c.y.get_value().lo);
853 EXPECT_EQ(c_x_result, expected.
x);
854 EXPECT_EQ(c_y_result, expected.
y);
863 size_t num_repetitions = 1;
864 for (
size_t i = 0; i < num_repetitions; ++i) {
873 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
876 if ((
uint256_t(scalar_b).get_bit(0) & 1) == 0) {
884 P_a.set_origin_tag(
OriginTag(0, 0,
true));
885 tag_union =
OriginTag(tag_union, P_a.get_origin_tag());
889 x_a.set_origin_tag(
OriginTag(0, 0,
false));
890 tag_union =
OriginTag(tag_union, x_a.get_origin_tag());
893 P_b.set_origin_tag(
OriginTag(0, 1,
true));
894 tag_union =
OriginTag(tag_union, P_b.get_origin_tag());
897 x_b.set_origin_tag(
OriginTag(0, 1,
false));
898 tag_union =
OriginTag(tag_union, x_b.get_origin_tag());
901 P_c.set_origin_tag(
OriginTag(0, 2,
true));
902 tag_union =
OriginTag(tag_union, P_c.get_origin_tag());
905 x_c.set_origin_tag(
OriginTag(0, 2,
false));
906 tag_union =
OriginTag(tag_union, x_c.get_origin_tag());
909 P_d.set_origin_tag(
OriginTag(0, 3,
true));
910 tag_union =
OriginTag(tag_union, P_d.get_origin_tag());
913 x_d.set_origin_tag(
OriginTag(0, 3,
false));
914 tag_union =
OriginTag(tag_union, x_d.get_origin_tag());
916 element_ct c = element_ct::batch_mul({ P_a, P_b, P_c, P_d }, { x_a, x_b, x_c, x_d });
919 EXPECT_EQ(c.get_origin_tag(), tag_union);
926 fq c_x_result(c.x.get_value().lo);
927 fq c_y_result(c.y.get_value().lo);
929 EXPECT_EQ(c_x_result, expected.
x);
930 EXPECT_EQ(c_y_result, expected.
y);
939 size_t num_repetitions = 1;
940 for (
size_t i = 0; i < num_repetitions; ++i) {
942 if ((
uint256_t(scalar_a).get_bit(0) & 1) == 1) {
948 P_a.set_origin_tag(submitted_value_origin_tag);
952 x_a.set_origin_tag(challenge_origin_tag);
956 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
958 fq c_x_result(c.x.get_value().lo);
959 fq c_y_result(c.y.get_value().lo);
961 EXPECT_EQ(c_x_result, expected.
x);
962 EXPECT_EQ(c_y_result, expected.
y);
972 const size_t num_points = 5;
975 std::vector<fr> scalars;
976 for (
size_t i = 0; i < num_points; ++i) {
984 for (
size_t i = 0; i < num_points; ++i) {
985 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
988 circuit_points[i].set_origin_tag(
OriginTag(0, i,
true));
989 tag_union =
OriginTag(tag_union, circuit_points[i].get_origin_tag());
990 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
993 circuit_scalars[i].set_origin_tag(
OriginTag(0, i,
false));
994 tag_union =
OriginTag(tag_union, circuit_scalars[i].get_origin_tag());
997 element_ct result_point = element_ct::batch_mul(circuit_points, circuit_scalars);
1000 EXPECT_EQ(result_point.get_origin_tag(), tag_union);
1004 for (
size_t i = 0; i < num_points; ++i) {
1005 expected_point += (
element(points[i]) * scalars[i]);
1008 expected_point = expected_point.normalize();
1009 fq result_x(result_point.x.get_value().lo);
1010 fq result_y(result_point.y.get_value().lo);
1012 EXPECT_EQ(result_x, expected_point.x);
1013 EXPECT_EQ(result_y, expected_point.y);
1020 const size_t num_points = 5;
1023 std::vector<fr> scalars;
1024 for (
size_t i = 0; i < num_points; ++i) {
1033 for (
size_t i = 0; i < num_points; ++i) {
1034 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1037 circuit_points[i].set_origin_tag(
OriginTag(0, i,
true));
1038 tag_union =
OriginTag(tag_union, circuit_points[i].get_origin_tag());
1039 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1042 circuit_scalars[i].set_origin_tag(
OriginTag(0, i,
false));
1043 tag_union =
OriginTag(tag_union, circuit_scalars[i].get_origin_tag());
1047 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1050 EXPECT_EQ(result_point2.get_origin_tag(), tag_union);
1053 for (
size_t i = 0; i < num_points; ++i) {
1054 expected_point += (
element(points[i]) * scalars[i]);
1057 expected_point = expected_point.normalize();
1059 fq result2_x(result_point2.x.get_value().lo);
1060 fq result2_y(result_point2.y.get_value().lo);
1062 EXPECT_EQ(result2_x, expected_point.x);
1063 EXPECT_EQ(result2_y, expected_point.y);
1070 const auto test_repeated_points = [](
const uint32_t num_points) {
1072 info(
"num points: ", num_points);
1074 std::vector<fr> scalars;
1075 for (
size_t idx = 0; idx < num_points; idx++) {
1077 scalars.push_back(1);
1081 ASSERT_EQ(points.size(), scalars.size());
1087 for (
size_t i = 0; i < num_points; ++i) {
1088 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1091 circuit_points[i].set_origin_tag(
1093 tag_union =
OriginTag(tag_union, circuit_points[i].get_origin_tag());
1094 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1097 circuit_scalars[i].set_origin_tag(
1099 tag_union =
OriginTag(tag_union, circuit_scalars[i].get_origin_tag());
1102 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1105 EXPECT_EQ(result_point.get_origin_tag(), tag_union);
1107 auto expected_point = element::infinity();
1108 for (
const auto& point : points) {
1109 expected_point += point;
1111 expected_point = expected_point.normalize();
1113 fq result_x(result_point.x.get_value().lo);
1114 fq result_y(result_point.y.get_value().lo);
1116 EXPECT_EQ(result_x, expected_point.x);
1117 EXPECT_EQ(result_y, expected_point.y);
1121 test_repeated_points(2);
1122 test_repeated_points(3);
1123 test_repeated_points(4);
1124 test_repeated_points(5);
1125 test_repeated_points(6);
1126 test_repeated_points(7);
1135 std::vector<fr> scalars;
1136 scalars.push_back(1);
1137 scalars.push_back(1);
1140 ASSERT_EQ(points.size(), scalars.size());
1141 const size_t num_points = points.size();
1147 for (
size_t i = 0; i < num_points; ++i) {
1148 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1151 circuit_points[i].set_origin_tag(
1153 tag_union =
OriginTag(tag_union, circuit_points[i].get_origin_tag());
1154 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1157 circuit_scalars[i].set_origin_tag(
1159 tag_union =
OriginTag(tag_union, circuit_scalars[i].get_origin_tag());
1163 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1166 EXPECT_EQ(result_point.get_origin_tag(), tag_union);
1168 element expected_point = points[1];
1169 expected_point = expected_point.normalize();
1171 fq result_x(result_point.x.get_value().lo);
1172 fq result_y(result_point.y.get_value().lo);
1174 EXPECT_EQ(result_x, expected_point.x);
1175 EXPECT_EQ(result_y, expected_point.y);
1184 std::vector<fr> scalars;
1185 scalars.push_back(0);
1186 scalars.push_back(1);
1189 ASSERT_EQ(points.size(), scalars.size());
1190 const size_t num_points = points.size();
1195 for (
size_t i = 0; i < num_points; ++i) {
1196 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1199 circuit_points[i].set_origin_tag(
1201 tag_union =
OriginTag(tag_union, circuit_points[i].get_origin_tag());
1202 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1205 circuit_scalars[i].set_origin_tag(
1207 tag_union =
OriginTag(tag_union, circuit_scalars[i].get_origin_tag());
1211 element_ct::batch_mul(circuit_points, circuit_scalars, 0,
true);
1214 EXPECT_EQ(result_point.get_origin_tag(), tag_union);
1216 element expected_point = points[1];
1217 expected_point = expected_point.normalize();
1219 fq result_x(result_point.x.get_value().lo);
1220 fq result_y(result_point.y.get_value().lo);
1222 EXPECT_EQ(result_x, expected_point.x);
1223 EXPECT_EQ(result_y, expected_point.y);
1232 size_t num_repetitions = 10;
1233 for (
size_t i = 0; i < num_repetitions; ++i) {
1242 auto acc = element_ct::chain_add_start(
a,
b);
1243 auto acc_out = element_ct::chain_add(c, acc);
1245 auto lambda_prev = (input_b.
y - input_a.
y) / (input_b.
x - input_a.
x);
1246 auto x3_prev = lambda_prev * lambda_prev - input_b.
x - input_a.
x;
1247 auto y3_prev = lambda_prev * (input_a.
x - x3_prev) - input_a.
y;
1248 auto lambda = (y3_prev - input_c.
y) / (x3_prev - input_c.
x);
1249 auto x3 = lambda * lambda - x3_prev - input_c.
x;
1251 uint256_t x3_u256 = acc_out.x3_prev.get_value().lo;
1252 uint256_t lambda_u256 = acc_out.lambda_prev.get_value().lo;
1254 fq x3_result(x3_u256);
1255 fq lambda_result(lambda_u256);
1257 EXPECT_EQ(x3_result, x3);
1258 EXPECT_EQ(lambda_result, lambda);
1267 size_t num_repetitions = 10;
1268 for (
size_t i = 0; i < num_repetitions; ++i) {
1273 for (
size_t j = 0; j < i; ++j) {
1278 typename element_ct::chain_add_accumulator add_1 =
1279 element_ct::chain_add_start(add_1_big_0, add_2_big_0);
1280 to_add.emplace_back(add_1);
1282 acc_big.multiple_montgomery_ladder(to_add);
1291 size_t max_num_bits = 254;
1298 scalar_raw = scalar_raw >> (256 -
length);
1300 scalar_val =
fr(scalar_raw);
1303 if (scalar_val ==
fr(0)) {
1308 scalar.set_origin_tag(submitted_value_origin_tag);
1309 auto naf = element_ct::compute_naf(scalar,
length);
1311 for (
const auto& bit : naf) {
1313 EXPECT_EQ(bit.get_origin_tag(), submitted_value_origin_tag);
1316 fr reconstructed_val(0);
1317 for (
size_t i = 0; i <
length; i++) {
1320 reconstructed_val -=
fr(naf[
length].get_value());
1321 EXPECT_EQ(scalar_val, reconstructed_val);
1334 scalar.set_origin_tag(submitted_value_origin_tag);
1336 const auto result = element_ct::compute_wnaf(scalar);
1338 for (
const auto& wnaf_entry : result) {
1339 EXPECT_EQ(wnaf_entry.get_origin_tag(), submitted_value_origin_tag);
1348 size_t num_repetitions = 1;
1349 for (
size_t i = 0; i < num_repetitions; ++i) {
1352 if ((
uint256_t(scalar).get_bit(0) & 1) == 1) {
1359 P.set_origin_tag(submitted_value_origin_tag);
1360 x.set_origin_tag(challenge_origin_tag);
1363 element_ct c = element_ct::wnaf_batch_mul({ P }, { x });
1366 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
1370 fq c_x_result(c.x.get_value().lo);
1371 fq c_y_result(c.y.get_value().lo);
1373 EXPECT_EQ(c_x_result, c_expected.
x);
1374 EXPECT_EQ(c_y_result, c_expected.
y);
1387 std::vector<fr> scalars;
1388 scalars.push_back(1);
1389 scalars.push_back(1);
1392 ASSERT_EQ(points.size(), scalars.size());
1393 const size_t num_points = points.size();
1398 for (
size_t i = 0; i < num_points; ++i) {
1399 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1400 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1403 circuit_points[i].set_origin_tag(
1405 circuit_scalars[i].set_origin_tag(
1408 OriginTag(union_tag, circuit_points[i].get_origin_tag(), circuit_scalars[i].get_origin_tag());
1411 element_ct result_point = element_ct::wnaf_batch_mul(circuit_points, circuit_scalars);
1414 EXPECT_EQ(result_point.get_origin_tag(), union_tag);
1416 element expected_point = points[0] + points[1];
1417 expected_point = expected_point.normalize();
1419 fq result_x(result_point.x.get_value().lo);
1420 fq result_y(result_point.y.get_value().lo);
1422 EXPECT_EQ(result_x, expected_point.x);
1423 EXPECT_EQ(result_y, expected_point.y);
1432 std::vector<fr> scalars;
1433 scalars.push_back(1);
1434 scalars.push_back(1);
1437 ASSERT_EQ(points.size(), scalars.size());
1438 const size_t num_points = points.size();
1443 for (
size_t i = 0; i < num_points; ++i) {
1444 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1445 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1448 circuit_points[i].set_origin_tag(
1450 circuit_scalars[i].set_origin_tag(
1453 OriginTag(union_tag, circuit_points[i].get_origin_tag(), circuit_scalars[i].get_origin_tag());
1455 element_ct result_point = element_ct::wnaf_batch_mul(circuit_points, circuit_scalars);
1458 EXPECT_EQ(result_point.get_origin_tag(), union_tag);
1460 element expected_point = points[1];
1461 expected_point = expected_point.normalize();
1463 fq result_x(result_point.x.get_value().lo);
1464 fq result_y(result_point.y.get_value().lo);
1466 EXPECT_EQ(result_x, expected_point.x);
1467 EXPECT_EQ(result_y, expected_point.y);
1476 std::vector<fr> scalars;
1477 scalars.push_back(0);
1478 scalars.push_back(1);
1481 ASSERT_EQ(points.size(), scalars.size());
1482 const size_t num_points = points.size();
1487 for (
size_t i = 0; i < num_points; ++i) {
1488 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1489 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1492 circuit_points[i].set_origin_tag(
1494 circuit_scalars[i].set_origin_tag(
1497 OriginTag(union_tag, circuit_points[i].get_origin_tag(), circuit_scalars[i].get_origin_tag());
1500 element_ct result_point = element_ct::wnaf_batch_mul(circuit_points, circuit_scalars);
1503 EXPECT_EQ(result_point.get_origin_tag(), union_tag);
1505 element expected_point = points[1];
1506 expected_point = expected_point.normalize();
1508 fq result_x(result_point.x.get_value().lo);
1509 fq result_y(result_point.y.get_value().lo);
1511 EXPECT_EQ(result_x, expected_point.x);
1512 EXPECT_EQ(result_y, expected_point.y);
1520 const size_t num_points = 11;
1523 std::vector<fr> scalars;
1524 for (
size_t i = 0; i < num_points; ++i) {
1527 scalar_raw.
data[2] = 0ULL;
1528 scalar_raw.
data[3] = 0ULL;
1529 scalars.push_back(
fr(scalar_raw));
1534 for (
size_t i = 0; i < num_points; ++i) {
1535 circuit_points.push_back(element_ct::from_witness(&
builder, points[i]));
1536 circuit_scalars.push_back(scalar_ct::from_witness(&
builder, scalars[i]));
1539 circuit_points[i].set_origin_tag(
OriginTag(0, i,
true));
1540 circuit_scalars[i].set_origin_tag(
OriginTag(0, i,
false));
1541 union_tag =
OriginTag(union_tag, circuit_points[i].get_origin_tag(), circuit_scalars[i].get_origin_tag());
1544 element_ct result_point = element_ct::batch_mul(circuit_points, circuit_scalars, 128);
1547 EXPECT_EQ(result_point.get_origin_tag(), union_tag);
1551 for (
size_t i = 0; i < num_points; ++i) {
1552 expected_point += (
element(points[i]) * scalars[i]);
1555 expected_point = expected_point.normalize();
1556 fq result_x(result_point.x.get_value().lo);
1557 fq result_y(result_point.y.get_value().lo);
1559 EXPECT_EQ(result_x, expected_point.x);
1560 EXPECT_EQ(result_y, expected_point.y);
1568 size_t num_repetitions = 1;
1569 for (
size_t i = 0; i < num_repetitions; ++i) {
1572 scalar_u256.
data[0] =
engine.get_random_uint64();
1573 scalar_u256.
data[1] =
engine.get_random_uint64();
1574 fr scalar(scalar_u256);
1575 if ((
uint256_t(scalar).get_bit(0) & 1) == 1) {
1582 P.set_origin_tag(submitted_value_origin_tag);
1583 x.set_origin_tag(challenge_origin_tag);
1587 element_ct c = element_ct::template wnaf_batch_mul<128>({ P }, { x });
1591 EXPECT_EQ(c.get_origin_tag(), first_two_merged_tag);
1595 fq c_x_result(c.x.get_value().lo);
1596 fq c_y_result(c.y.get_value().lo);
1598 EXPECT_EQ(c_x_result, c_expected.
x);
1599 EXPECT_EQ(c_y_result, c_expected.
y);
1608 size_t num_repetitions = 1;
1609 for (
size_t i = 0; i < num_repetitions; ++i) {
1610 const auto get_128_bit_scalar = []() {
1612 scalar_u256.
data[0] =
engine.get_random_uint64();
1613 scalar_u256.
data[1] =
engine.get_random_uint64();
1614 fr scalar(scalar_u256);
1633 P1.set_origin_tag(element_tags[0]);
1634 P2.set_origin_tag(element_tags[1]);
1635 P3.set_origin_tag(element_tags[2]);
1636 P4.set_origin_tag(element_tags[3]);
1638 fr scalar1 = get_128_bit_scalar();
1639 fr scalar2 = get_128_bit_scalar();
1640 fr scalar3 = get_128_bit_scalar();
1641 fr scalar4 = get_128_bit_scalar();
1655 x1.set_origin_tag(scalar_tags[0]);
1656 x2.set_origin_tag(scalar_tags[1]);
1657 x3.set_origin_tag(scalar_tags[2]);
1658 x4.set_origin_tag(scalar_tags[3]);
1661 for (
size_t j = 0; j < element_tags.size(); j++) {
1662 union_tag =
OriginTag(union_tag, element_tags[j], scalar_tags[j]);
1666 element_ct c = element_ct::batch_mul({ P1, P2, P3, P4 }, { x1, x2, x3, x4 }, 128);
1670 EXPECT_EQ(c.get_origin_tag(), union_tag);
1671 element out = input1 * scalar1;
1672 out += (input2 * scalar2);
1673 out += (input3 * scalar3);
1674 out += (input4 * scalar4);
1677 fq c_x_result(c.x.get_value().lo);
1678 fq c_y_result(c.y.get_value().lo);
1680 EXPECT_EQ(c_x_result, c_expected.
x);
1681 EXPECT_EQ(c_y_result, c_expected.
y);
1689 const size_t num_big_points = 2;
1690 const size_t num_small_points = 1;
1693 std::vector<fr> big_scalars;
1695 std::vector<fr> small_scalars;
1697 for (
size_t i = 0; i < num_big_points; ++i) {
1701 for (
size_t i = 0; i < num_small_points; ++i) {
1702 small_points.push_back(
affine_element(element::random_element()));
1704 scalar_raw.
data[2] = 0ULL;
1705 scalar_raw.
data[3] = 0ULL;
1706 small_scalars.push_back(
fr(scalar_raw));
1714 for (
size_t i = 0; i < num_big_points; ++i) {
1715 big_circuit_points.push_back(element_ct::from_witness(&
builder, big_points[i]));
1716 big_circuit_scalars.push_back(scalar_ct::from_witness(&
builder, big_scalars[i]));
1719 big_circuit_points[i].set_origin_tag(
1721 big_circuit_scalars[i].set_origin_tag(
1724 OriginTag(union_tag, big_circuit_points[i].get_origin_tag(), big_circuit_scalars[i].get_origin_tag());
1726 for (
size_t i = 0; i < num_small_points; ++i) {
1727 small_circuit_points.push_back(element_ct::from_witness(&
builder, small_points[i]));
1728 small_circuit_scalars.push_back(scalar_ct::from_witness(&
builder, small_scalars[i]));
1731 small_circuit_points[i].set_origin_tag(
1732 OriginTag(0, i + num_big_points,
true));
1733 small_circuit_scalars[i].set_origin_tag(
1734 OriginTag(0, i + num_big_points,
false));
1736 union_tag, small_circuit_points[i].get_origin_tag(), small_circuit_scalars[i].get_origin_tag());
1739 element_ct result_point = element_ct::bn254_endo_batch_mul(
1740 big_circuit_points, big_circuit_scalars, small_circuit_points, small_circuit_scalars, 128);
1743 EXPECT_EQ(result_point.get_origin_tag(), union_tag);
1747 for (
size_t i = 0; i < num_big_points; ++i) {
1748 expected_point += (
element(big_points[i]) * big_scalars[i]);
1750 for (
size_t i = 0; i < num_small_points; ++i) {
1751 expected_point += (
element(small_points[i]) * small_scalars[i]);
1754 expected_point = expected_point.normalize();
1755 fq result_x(result_point.x.get_value().lo);
1756 fq result_y(result_point.y.get_value().lo);
1758 EXPECT_EQ(result_x, expected_point.x);
1759 EXPECT_EQ(result_y, expected_point.y);
1767 size_t num_repetitions = 1;
1769 const auto get_small_scalar = []() {
1776 for (
size_t i = 0; i < num_repetitions; ++i) {
1787 std::vector<fr> small_scalars_w(25);
1788 std::vector<fr> big_scalars_w(5);
1789 std::vector<fr> double_scalars_w(11);
1791 for (
size_t i = 0; i < 25; ++i) {
1793 small_scalars_w[i] = get_small_scalar();
1794 small_points[i] = element_ct::from_witness(&
builder, small_points_w[i]);
1795 small_scalars[i] = scalar_ct::from_witness(&
builder, small_scalars_w[i]);
1797 for (
size_t i = 0; i < 5; ++i) {
1800 big_points[i] = element_ct::from_witness(&
builder, big_points_w[i]);
1801 big_scalars[i] = scalar_ct::from_witness(&
builder, big_scalars_w[i]);
1803 for (
size_t i = 0; i < 11; ++i) {
1805 double_scalars_w[i] = get_small_scalar();
1806 double_points[i] = element_ct::from_witness(&
builder, double_points_w[i]);
1807 double_scalars[i] = scalar_ct::from_witness(&
builder, double_scalars_w[i]);
1810 fr omega = get_small_scalar();
1812 const auto double_opening_result = element_ct::batch_mul(double_points, double_scalars, 128);
1813 small_points.push_back(double_opening_result);
1814 small_scalars.push_back(scalar_ct::from_witness(&
builder, omega));
1816 auto opening_result =
1817 element_ct::bn254_endo_batch_mul(big_points, big_scalars, small_points, small_scalars, 128);
1819 opening_result = opening_result + double_opening_result;
1820 opening_result = opening_result.normalize();
1824 for (
size_t i = 0; i < 11; ++i) {
1825 expected += (double_points_w[i] * double_scalars_w[i]);
1827 expected *= (omega + 1);
1828 for (
size_t i = 0; i < 25; ++i) {
1829 expected += (small_points_w[i] * small_scalars_w[i]);
1831 for (
size_t i = 0; i < 5; ++i) {
1832 expected += (big_points_w[i] * big_scalars_w[i]);
1834 expected = expected.normalize();
1836 fq result_x(opening_result.x.get_value().lo);
1837 fq result_y(opening_result.y.get_value().lo);
1839 EXPECT_EQ(result_x, expected.x);
1840 EXPECT_EQ(result_y, expected.y);
1855 TestFixture::test_basic_tag_logic();
1860 TestFixture::test_add();
1864 TestFixture::test_add_points_at_infinity();
1868 TestFixture::test_standard_form_of_point_at_infinity();
1872 TestFixture::test_sub();
1877 TestFixture::test_sub_points_at_infinity();
1881 TestFixture::test_dbl();
1885 TestFixture::test_conditional_negate();
1889 TestFixture::test_conditional_select();
1893 TestFixture::test_incomplete_assert_equal_success();
1897 TestFixture::test_incomplete_assert_equal_failure();
1901 TestFixture::test_incomplete_assert_equal_edge_cases();
1906 GTEST_SKIP() <<
"https://github.com/AztecProtocol/barretenberg/issues/1290";
1908 TestFixture::test_montgomery_ladder();
1913 TestFixture::test_mul();
1921 TestFixture::test_short_scalar_mul_2_126();
1929 TestFixture::test_short_scalar_mul_128_252();
1938 TestFixture::test_short_scalar_mul_infinity();
1945 GTEST_SKIP() <<
"https://github.com/AztecProtocol/barretenberg/issues/1290";
1947 TestFixture::test_twin_mul();
1953 GTEST_SKIP() <<
"https://github.com/AztecProtocol/barretenberg/issues/1290";
1955 TestFixture::test_triple_mul();
1961 GTEST_SKIP() <<
"https://github.com/AztecProtocol/barretenberg/issues/1290";
1963 TestFixture::test_quad_mul();
1968 TestFixture::test_one();
1972 TestFixture::test_batch_mul();
1980 TestFixture::test_batch_mul_edgecase_equivalence();
1985 TestFixture::test_batch_mul_edge_case_set1();
1990 TestFixture::test_batch_mul_edge_case_set2();
1996 GTEST_SKIP() <<
"https://github.com/AztecProtocol/barretenberg/issues/1290";
1998 TestFixture::test_chain_add();
2005 GTEST_SKIP() <<
"https://github.com/AztecProtocol/barretenberg/issues/1290";
2007 TestFixture::test_multiple_montgomery_ladder();
2015 size_t num_repetitions = 1;
2016 for (
size_t i = 0; i < num_repetitions; i++) {
2017 TestFixture::test_compute_naf();
2030 TestFixture::test_compute_wnaf();
2040 TestFixture::test_compute_wnaf();
2051 TestFixture::test_compute_wnaf();
2059 if constexpr (TypeParam::use_bigfield) {
2065 TestFixture::test_batch_mul_short_scalars();
2071 if constexpr (TypeParam::use_bigfield) {
2077 TestFixture::test_wnaf_batch_mul_128_bit();
2083 if constexpr (TypeParam::use_bigfield) {
2086 TestFixture::test_wnaf_batch_4();
2093 if constexpr (TypeParam::Curve::type == CurveType::BN254 && !TypeParam::use_bigfield) {
2097 TestFixture::test_bn254_endo_batch_mul();
2105 if constexpr (TypeParam::Curve::type == CurveType::BN254 && !TypeParam::use_bigfield) {
2109 TestFixture::test_mixed_mul_bn254_endo();
testing::Types< TestType< stdlib::bn254< bb::UltraCircuitBuilder >, UseBigfield::Yes >, TestType< stdlib::bn254< bb::MegaCircuitBuilder >, UseBigfield::No > > TestTypes
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
static affine_element infinity()
constexpr void self_set_infinity() noexcept
static constexpr affine_element one() noexcept
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
Implements boolean logic in-circuit.
void set_origin_tag(const OriginTag &new_tag) const
static void test_sub_points_at_infinity()
static void test_batch_mul_edgecase_equivalence()
static void test_twin_mul()
static void test_batch_mul_short_scalars()
static void test_add_points_at_infinity()
static void test_compute_naf()
typename g1::element element
static void test_multiple_montgomery_ladder()
static void test_conditional_negate()
static void test_conditional_select()
typename Curve::ScalarFieldNative fr
static void test_batch_mul_edge_case_set2()
typename TestType::element_ct element_ct
static void test_mixed_mul_bn254_endo()
static void test_montgomery_ladder()
static void test_quad_mul()
static void test_bn254_endo_batch_mul()
typename g1::affine_element affine_element
static void test_short_scalar_mul_128_252()
typename TestType::Curve Curve
static void test_incomplete_assert_equal_edge_cases()
static void test_basic_tag_logic()
typename Curve::Builder Builder
typename TestType::scalar_ct scalar_ct
stdlib::bool_t< Builder > bool_ct
static void test_triple_mul()
static void test_batch_mul_edge_case_set1()
static void test_wnaf_batch_mul_128_bit()
static void test_short_scalar_mul_infinity()
static void test_incomplete_assert_equal_success()
static void test_incomplete_assert_equal_failure()
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.
static void test_wnaf_batch_mul()
typename Curve::GroupNative g1
static void test_wnaf_batch_mul_edge_cases()
static void test_compute_wnaf()
static void test_wnaf_batch_4()
typename Curve::BaseFieldNative fq
static void test_short_scalar_mul_2_126()
static void test_chain_add()
static void test_batch_mul()
static constexpr auto EXPECT_CIRCUIT_CORRECTNESS
void benchmark_info(Args...)
Info used to store circuit statistics during CI/CD with concrete structure. Writes straight to log.
uint8_t const size_t length
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
#define STANDARD_TESTING_TAGS
typename std::conditional< _use_bigfield, typename Curve::g1_bigfr_ct, typename Curve::Group >::type element_ct
typename std::conditional< _use_bigfield, typename Curve::bigfr_ct, typename Curve::ScalarField >::type scalar_ct
static const bool use_bigfield
BB_INLINE constexpr field to_montgomery_form() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr field from_montgomery_form() const noexcept
#define HEAVY_TYPED_TEST(x, y)