48std::tuple<std::vector<element<C, Fq, Fr, G>>, std::vector<Fr>,
element<C, Fq, Fr, G>>
element<C, Fq, Fr, G>::
52 std::vector<Fr> scalars;
57 C*
builder = validate_context<C>(validate_context<C>(_points), validate_context<C>(_scalars));
58 const typename G::affine_element native_offset_generator =
typename G::affine_element(G::element::random_element());
59 const element offset_generator_element = element::from_witness(
builder, native_offset_generator);
65 false,
"mask_points: offset generator must not be the point at infinity");
70 element running_point = offset_generator_element;
73 Fr running_scalar =
Fr(1);
74 Fr last_scalar =
Fr(0);
77 for (
size_t i = 0; i < _points.size(); i++) {
78 scalars.push_back(_scalars[i]);
84 "mask_points: masked point must not be the point at infinity");
85 points.push_back(masked);
88 last_scalar += _scalars[i] * running_scalar;
91 running_scalar += running_scalar;
96 const uint32_t n =
static_cast<uint32_t
>(_points.size());
97 const Fr two_power_n =
Fr(2).
pow(n);
98 const Fr two_power_n_inverse = two_power_n.
invert();
99 last_scalar *= two_power_n_inverse;
100 scalars.push_back(-last_scalar);
101 if constexpr (Fr::is_composite) {
102 scalars.back().self_reduce();
105 points.push_back(running_point);
107 return { points, scalars, offset_generator_element };
118 C*
builder = validate_context<C>(validate_context<C>(_points), validate_context<C>(_scalars));
120 std::vector<Fr> scalars;
123 for (
auto [_point, _scalar] :
zip_view(_points, _scalars)) {
124 bool_ct is_point_at_infinity = _point.is_point_at_infinity();
125 if (is_point_at_infinity.
get_value() &&
static_cast<bool>(is_point_at_infinity.
is_constant())) {
129 if (_scalar.get_value() == 0 && _scalar.is_constant()) {
138 if constexpr (!Fr::is_composite) {
140 scalar = Fr::conditional_assign_internal(is_point_at_infinity, 0, _scalar);
143 scalar = Fr::conditional_assign(is_point_at_infinity, 0, _scalar);
147 points.push_back(point);
148 scalars.push_back(scalar);
151 return { points, scalars };