40 const std::vector<Fr>& scalars,
41 [[maybe_unused]]
const size_t max_num_bits,
42 [[maybe_unused]]
const bool handle_edge_cases)
44 auto builder = validate_context<C>(validate_context<C>(points), validate_context<C>(scalars));
46 BB_ASSERT(
builder !=
nullptr,
"biggroup_goblin: builder context is invalid.");
47 BB_ASSERT(points.size() == scalars.size(),
"biggroup_goblin: points and scalars lengths not equal.");
53 size_t num_points = points.size();
56 for (
size_t i = 0; i < num_points; ++i) {
57 auto& point = points[i];
58 auto& scalar = scalars[i];
61 tag_union =
OriginTag(tag_union,
OriginTag(point.get_origin_tag(), scalar.get_origin_tag()));
64 bool scalar_is_constant_equal_one = scalar.is_constant() && scalar.get_value() == 1;
65 if (scalar_is_constant_equal_one) {
66 op_tuple =
builder->queue_ecc_add_accum(point.get_value());
68 op_tuple =
builder->queue_ecc_mul_accum(point.get_value(), scalar.get_value());
74 auto x_lo = Fr::from_witness_index(
builder, op_tuple.
x_lo);
75 auto x_hi = Fr::from_witness_index(
builder, op_tuple.
x_hi);
76 auto y_lo = Fr::from_witness_index(
builder, op_tuple.
y_lo);
77 auto y_hi = Fr::from_witness_index(
builder, op_tuple.
y_hi);
81 if (!point.get_value().is_point_at_infinity()) {
85 x_lo.assert_equal(point._x.limbs[0]);
86 x_hi.assert_equal(point._x.limbs[1]);
87 y_lo.assert_equal(point._y.limbs[0]);
88 y_hi.assert_equal(point._y.limbs[1]);
91 if (!scalar_is_constant_equal_one) {
92 auto z_1 = Fr::from_witness_index(
builder, op_tuple.
z_1);
93 auto z_2 = Fr::from_witness_index(
builder, op_tuple.
z_2);
95 scalar.assert_equal(z_1 - z_2 * beta);
103 if (scalar_is_constant_equal_one) {
104 builder->update_used_witnesses({ op_tuple.
z_1, op_tuple.
z_2 });
108 auto op_tuple =
builder->queue_ecc_eq();
112 builder->update_used_witnesses({ op_tuple.z_1, op_tuple.z_2 });
114 auto x_lo = Fr::from_witness_index(
builder, op_tuple.x_lo);
115 auto x_hi = Fr::from_witness_index(
builder, op_tuple.x_hi);
116 auto y_lo = Fr::from_witness_index(
builder, op_tuple.y_lo);
117 auto y_hi = Fr::from_witness_index(
builder, op_tuple.y_hi);
118 Fq point_x(x_lo, x_hi);
119 Fq point_y(y_lo, y_hi);
static goblin_element batch_mul(const std::vector< goblin_element > &points, const std::vector< Fr > &scalars, const size_t max_num_bits=0, const bool handle_edge_cases=false)
Goblin style batch multiplication.