32 fq2 T0 =
a.x.frobenius_map();
33 fq2 T1 =
a.y.frobenius_map();
51 fq2 H = (work_point.
y + work_point.
z).sqr() - B -
C;
59 work_point.
x = A * (B - F);
60 work_point.
y =
G.
sqr() - (J + J + J);
68 fq2 A = Q.
y * work_point.
z;
69 fq2 B = Q.
x * work_point.
z;
70 fq2 theta = work_point.
y - A;
71 fq2 lambda = work_point.
x - B;
75 fq2 F = work_point.
z *
C;
76 fq2 G = work_point.
x * D;
77 fq2 H = E + F -
G -
G;
78 fq2 I = work_point.
y * E;
79 fq2 J = theta * Q.
x - lambda * Q.
y;
81 work_point.
x = lambda * H;
82 work_point.
y = theta * (
G - H) - I;
83 work_point.
z = work_point.
z * E;
96 for (
unsigned char loop_bit :
loop_bits) {
102 }
else if (loop_bit == 3) {
119 throw_or_abort(
"precompute_miller_lines: Cannot precompute Miller lines for the point at infinity.");
133 for (
unsigned char loop_bit :
loop_bits) {
134 work_scalar = work_scalar.
sqr();
136 work_line.
o = lines.
lines[it].o.mul_by_fq(minus_y_P);
137 work_line.
w = lines.
lines[it].w.mul_by_fq(P.
x);
138 work_line.
vw = lines.
lines[it].vw;
143 work_line.
o = lines.
lines[it].o.mul_by_fq(P.
y);
144 work_line.
w = lines.
lines[it].w.mul_by_fq(minus_x_P);
145 work_line.
vw = lines.
lines[it].vw;
151 work_line.
o = lines.
lines[it].o.mul_by_fq(P.
y);
152 work_line.
w = lines.
lines[it].w.mul_by_fq(minus_x_P);
153 work_line.
vw = lines.
lines[it].vw;
156 work_line.
o = lines.
lines[it].o.mul_by_fq(P.
y);
157 work_line.
w = lines.
lines[it].w.mul_by_fq(minus_x_P);
158 work_line.
vw = lines.
lines[it].vw;
172 for (
unsigned char loop_bit :
loop_bits) {
173 work_scalar = work_scalar.
sqr();
174 for (
size_t j = 0; j < num_pairs; ++j) {
175 const auto& coeff = lines[j].
lines[it];
176 work_line.
o = coeff.o.mul_by_fq(-points[j].y);
177 work_line.
w = coeff.w.mul_by_fq(points[j].x);
178 work_line.
vw = coeff.vw;
183 for (
size_t j = 0; j < num_pairs; ++j) {
184 const auto& coeff = lines[j].
lines[it];
185 work_line.
o = coeff.o.mul_by_fq(points[j].y);
186 work_line.
w = coeff.w.mul_by_fq(-points[j].x);
187 work_line.
vw = coeff.vw;
194 for (
size_t j = 0; j < num_pairs; ++j) {
195 const auto& coeff = lines[j].
lines[it];
196 work_line.
o = coeff.o.mul_by_fq(points[j].y);
197 work_line.
w = coeff.w.mul_by_fq(-points[j].x);
198 work_line.
vw = coeff.vw;
202 for (
size_t j = 0; j < num_pairs; ++j) {
203 const auto& coeff = lines[j].
lines[it];
204 work_line.
o = coeff.o.mul_by_fq(points[j].y);
205 work_line.
w = coeff.w.mul_by_fq(-points[j].x);
206 work_line.
vw = coeff.vw;
217 return a *
a.frobenius_map_two();
286 const size_t num_points)
288 for (
size_t i = 0; i < num_points; ++i) {
289 if (!P_affines[i].on_curve()) {
290 throw_or_abort(
"reduced_ate_pairing_batch_precomputed: one of the points is not on the curve.");
302 const size_t num_points)
305 lines.reserve(num_points);
307 bool has_infinity_pair =
false;
308 for (
size_t i = 0; i < num_points; ++i) {
309 if (!P_affines[i].on_curve()) {
310 throw_or_abort(
"reduced_ate_pairing_batch: one of the P points is not on the curve.");
312 if (!Q_affines[i].on_curve()) {
313 throw_or_abort(
"reduced_ate_pairing_batch: one of the Q points is not on the curve.");
318 if (!P_affines[i].is_point_at_infinity() && !Q_affines[i].is_point_at_infinity()) {
322 has_infinity_pair =
true;
330 if (!has_infinity_pair) {
338 filtered_points.reserve(num_points);
339 for (
size_t i = 0; i < num_points; ++i) {
340 if (!P_affines[i].is_point_at_infinity() && !Q_affines[i].is_point_at_infinity()) {
341 filtered_points.emplace_back(P_affines[i]);
constexpr field12 cyclotomic_squared() const
constexpr field12 frobenius_map_three() const
constexpr field12 invert() const
constexpr field12 unitary_inverse() const
constexpr void self_sparse_mul(const ell_coeffs &ell)
Multiply the element by a sparse element of the form ell.o + ell.w * w + ell.vw * wv.
static constexpr field12 one()
constexpr field12 sqr() const
constexpr field12 frobenius_map_two() const
constexpr field12 frobenius_map_one() const
constexpr bool is_point_at_infinity() const noexcept
constexpr bool on_curve() const noexcept
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
BB_INLINE constexpr bool is_point_at_infinity() const noexcept
#define G(r, i, a, b, c, d)
constexpr void doubling_step_for_miller_loop(g2Projective &work_point, fq12::ell_coeffs &line)
Doubling step for Miller loop calculation.
constexpr fq12 final_exponentiation_exp_by_z(const fq12 &elt)
constexpr std::array< uint8_t, loop_length > loop_bits
constexpr fq12 final_exponentiation_tricky_part(const fq12 &elt)
fq12 reduced_ate_pairing_batch_precomputed(const g1::affine_element *P_affines, const miller_lines *lines, const size_t num_points)
constexpr fq12 reduced_ate_pairing(const g1::affine_element &P_affine, const g2::affine_element &Q_affine)
constexpr g2Projective twisted_frobenius(const g2Projective &a)
Compute where is the untwisting isomorphism and is the Frobenius morphism.
constexpr fq12 final_exponentiation_easy_part(const fq12 &elt)
constexpr void mixed_addition_step_for_miller_loop(const g2Projective &Q, g2Projective &work_point, fq12::ell_coeffs &line)
Addition step for Miller loop calculation.
constexpr fq12 miller_loop_batch(const g1::affine_element *points, const miller_lines *lines, size_t num_pairs)
Compute the Miller loop for multiple pairs of points.
constexpr void precompute_miller_lines(const g2Projective &Q, miller_lines &lines)
Precomputation of Miller lines for a point Q in G2.
fq12 reduced_ate_pairing_batch(const g1::affine_element *P_affines, const g2::affine_element *Q_affines, const size_t num_points)
constexpr std::array< bool, z_loop_length > z_loop_bits
constexpr fq12 miller_loop(const g1::affine_element &P, const miller_lines &lines)
Miller loop implementation.
field< Bn254FqParams > fq
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
constexpr field2 sqr() const noexcept
constexpr field2 mul_by_fq(const base_field &a) const noexcept
static constexpr field2 one()
static constexpr field2 frobenius_on_twisted_curve_y()
static constexpr field2 twist_coeff_b()
static constexpr field2 frobenius_on_twisted_curve_x()
constexpr field invert() const noexcept
std::array< fq12::ell_coeffs, precomputed_coefficients_length > lines
void throw_or_abort(std::string const &err)