40 const std::vector<Fr>& scalars,
41 [[maybe_unused]]
const size_t max_num_bits,
42 [[maybe_unused]]
const bool handle_edge_cases,
43 [[maybe_unused]]
const Fr& masking_scalar)
45 auto builder = validate_context<C>(validate_context<C>(points), validate_context<C>(scalars));
47 BB_ASSERT(
builder !=
nullptr,
"biggroup_goblin: builder context is invalid.");
48 BB_ASSERT(points.size() == scalars.size(),
"biggroup_goblin: points and scalars lengths not equal.");
54 size_t num_points = points.size();
57 for (
size_t i = 0; i < num_points; ++i) {
58 auto& point = points[i];
59 auto& scalar = scalars[i];
62 tag_union =
OriginTag(tag_union,
OriginTag(point.get_origin_tag(), scalar.get_origin_tag()));
65 bool scalar_is_constant_equal_one = scalar.is_constant() && scalar.get_value() == 1;
66 if (scalar_is_constant_equal_one) {
67 op_tuple =
builder->queue_ecc_add_accum(point.get_value());
69 op_tuple =
builder->queue_ecc_mul_accum(point.get_value(), scalar.get_value());
75 auto x_lo = Fr::from_witness_index(
builder, op_tuple.
x_lo);
76 auto x_hi = Fr::from_witness_index(
builder, op_tuple.
x_hi);
77 auto y_lo = Fr::from_witness_index(
builder, op_tuple.
y_lo);
78 auto y_hi = Fr::from_witness_index(
builder, op_tuple.
y_hi);
82 if (!point.get_value().is_point_at_infinity()) {
86 x_lo.assert_equal(point._x.limbs[0]);
87 x_hi.assert_equal(point._x.limbs[1]);
88 y_lo.assert_equal(point._y.limbs[0]);
89 y_hi.assert_equal(point._y.limbs[1]);
92 if (!scalar_is_constant_equal_one) {
93 auto z_1 = Fr::from_witness_index(
builder, op_tuple.
z_1);
94 auto z_2 = Fr::from_witness_index(
builder, op_tuple.
z_2);
96 scalar.assert_equal(z_1 - z_2 * beta);
104 if (scalar_is_constant_equal_one) {
105 builder->update_used_witnesses({ op_tuple.
z_1, op_tuple.
z_2 });
109 auto op_tuple =
builder->queue_ecc_eq();
113 builder->update_used_witnesses({ op_tuple.z_1, op_tuple.z_2 });
115 auto x_lo = Fr::from_witness_index(
builder, op_tuple.x_lo);
116 auto x_hi = Fr::from_witness_index(
builder, op_tuple.x_hi);
117 auto y_lo = Fr::from_witness_index(
builder, op_tuple.y_lo);
118 auto y_hi = Fr::from_witness_index(
builder, op_tuple.y_hi);
119 Fq point_x(x_lo, x_hi);
120 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, const Fr &masking_scalar=Fr(1))
Goblin style batch multiplication.