Original HUSH source code based on ZEC 1.0.8 . For historical purposes only!
https://hush.is
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
547 lines
18 KiB
547 lines
18 KiB
/** @file
|
|
*****************************************************************************
|
|
* @author This file is part of libsnark, developed by SCIPR Lab
|
|
* and contributors (see AUTHORS).
|
|
* @copyright MIT license (see LICENSE file)
|
|
*****************************************************************************/
|
|
|
|
#include "algebra/curves/alt_bn128/alt_bn128_pairing.hpp"
|
|
#include "algebra/curves/alt_bn128/alt_bn128_init.hpp"
|
|
#include "algebra/curves/alt_bn128/alt_bn128_g1.hpp"
|
|
#include "algebra/curves/alt_bn128/alt_bn128_g2.hpp"
|
|
#include <cassert>
|
|
#include "common/profiling.hpp"
|
|
#include "common/assert_except.hpp"
|
|
|
|
namespace libsnark {
|
|
|
|
bool alt_bn128_ate_G1_precomp::operator==(const alt_bn128_ate_G1_precomp &other) const
|
|
{
|
|
return (this->PX == other.PX &&
|
|
this->PY == other.PY);
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_G1_precomp &prec_P)
|
|
{
|
|
out << prec_P.PX << OUTPUT_SEPARATOR << prec_P.PY;
|
|
|
|
return out;
|
|
}
|
|
|
|
std::istream& operator>>(std::istream &in, alt_bn128_ate_G1_precomp &prec_P)
|
|
{
|
|
in >> prec_P.PX;
|
|
consume_OUTPUT_SEPARATOR(in);
|
|
in >> prec_P.PY;
|
|
|
|
return in;
|
|
}
|
|
|
|
bool alt_bn128_ate_ell_coeffs::operator==(const alt_bn128_ate_ell_coeffs &other) const
|
|
{
|
|
return (this->ell_0 == other.ell_0 &&
|
|
this->ell_VW == other.ell_VW &&
|
|
this->ell_VV == other.ell_VV);
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream &out, const alt_bn128_ate_ell_coeffs &c)
|
|
{
|
|
out << c.ell_0 << OUTPUT_SEPARATOR << c.ell_VW << OUTPUT_SEPARATOR << c.ell_VV;
|
|
return out;
|
|
}
|
|
|
|
std::istream& operator>>(std::istream &in, alt_bn128_ate_ell_coeffs &c)
|
|
{
|
|
in >> c.ell_0;
|
|
consume_OUTPUT_SEPARATOR(in);
|
|
in >> c.ell_VW;
|
|
consume_OUTPUT_SEPARATOR(in);
|
|
in >> c.ell_VV;
|
|
|
|
return in;
|
|
}
|
|
|
|
bool alt_bn128_ate_G2_precomp::operator==(const alt_bn128_ate_G2_precomp &other) const
|
|
{
|
|
return (this->QX == other.QX &&
|
|
this->QY == other.QY &&
|
|
this->coeffs == other.coeffs);
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& out, const alt_bn128_ate_G2_precomp &prec_Q)
|
|
{
|
|
out << prec_Q.QX << OUTPUT_SEPARATOR << prec_Q.QY << "\n";
|
|
out << prec_Q.coeffs.size() << "\n";
|
|
for (const alt_bn128_ate_ell_coeffs &c : prec_Q.coeffs)
|
|
{
|
|
out << c << OUTPUT_NEWLINE;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
std::istream& operator>>(std::istream& in, alt_bn128_ate_G2_precomp &prec_Q)
|
|
{
|
|
in >> prec_Q.QX;
|
|
consume_OUTPUT_SEPARATOR(in);
|
|
in >> prec_Q.QY;
|
|
consume_newline(in);
|
|
|
|
prec_Q.coeffs.clear();
|
|
size_t s;
|
|
in >> s;
|
|
|
|
consume_newline(in);
|
|
|
|
prec_Q.coeffs.reserve(s);
|
|
|
|
for (size_t i = 0; i < s; ++i)
|
|
{
|
|
alt_bn128_ate_ell_coeffs c;
|
|
in >> c;
|
|
consume_OUTPUT_NEWLINE(in);
|
|
prec_Q.coeffs.emplace_back(c);
|
|
}
|
|
|
|
return in;
|
|
}
|
|
|
|
/* final exponentiations */
|
|
|
|
alt_bn128_Fq12 alt_bn128_final_exponentiation_first_chunk(const alt_bn128_Fq12 &elt)
|
|
{
|
|
enter_block("Call to alt_bn128_final_exponentiation_first_chunk");
|
|
|
|
/*
|
|
Computes result = elt^((q^6-1)*(q^2+1)).
|
|
Follows, e.g., Beuchat et al page 9, by computing result as follows:
|
|
elt^((q^6-1)*(q^2+1)) = (conj(elt) * elt^(-1))^(q^2+1)
|
|
More precisely:
|
|
A = conj(elt)
|
|
B = elt.inverse()
|
|
C = A * B
|
|
D = C.Frobenius_map(2)
|
|
result = D * C
|
|
*/
|
|
|
|
const alt_bn128_Fq12 A = alt_bn128_Fq12(elt.c0,-elt.c1);
|
|
const alt_bn128_Fq12 B = elt.inverse();
|
|
const alt_bn128_Fq12 C = A * B;
|
|
const alt_bn128_Fq12 D = C.Frobenius_map(2);
|
|
const alt_bn128_Fq12 result = D * C;
|
|
|
|
leave_block("Call to alt_bn128_final_exponentiation_first_chunk");
|
|
|
|
return result;
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_exp_by_neg_z(const alt_bn128_Fq12 &elt)
|
|
{
|
|
enter_block("Call to alt_bn128_exp_by_neg_z");
|
|
|
|
alt_bn128_Fq12 result = elt.cyclotomic_exp(alt_bn128_final_exponent_z);
|
|
if (!alt_bn128_final_exponent_is_z_neg)
|
|
{
|
|
result = result.unitary_inverse();
|
|
}
|
|
|
|
leave_block("Call to alt_bn128_exp_by_neg_z");
|
|
|
|
return result;
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_final_exponentiation_last_chunk(const alt_bn128_Fq12 &elt)
|
|
{
|
|
enter_block("Call to alt_bn128_final_exponentiation_last_chunk");
|
|
|
|
/*
|
|
Follows Laura Fuentes-Castaneda et al. "Faster hashing to G2"
|
|
by computing:
|
|
|
|
result = elt^(q^3 * (12*z^3 + 6z^2 + 4z - 1) +
|
|
q^2 * (12*z^3 + 6z^2 + 6z) +
|
|
q * (12*z^3 + 6z^2 + 4z) +
|
|
1 * (12*z^3 + 12z^2 + 6z + 1))
|
|
which equals
|
|
|
|
result = elt^( 2z * ( 6z^2 + 3z + 1 ) * (q^4 - q^2 + 1)/r ).
|
|
|
|
Using the following addition chain:
|
|
|
|
A = exp_by_neg_z(elt) // = elt^(-z)
|
|
B = A^2 // = elt^(-2*z)
|
|
C = B^2 // = elt^(-4*z)
|
|
D = C * B // = elt^(-6*z)
|
|
E = exp_by_neg_z(D) // = elt^(6*z^2)
|
|
F = E^2 // = elt^(12*z^2)
|
|
G = epx_by_neg_z(F) // = elt^(-12*z^3)
|
|
H = conj(D) // = elt^(6*z)
|
|
I = conj(G) // = elt^(12*z^3)
|
|
J = I * E // = elt^(12*z^3 + 6*z^2)
|
|
K = J * H // = elt^(12*z^3 + 6*z^2 + 6*z)
|
|
L = K * B // = elt^(12*z^3 + 6*z^2 + 4*z)
|
|
M = K * E // = elt^(12*z^3 + 12*z^2 + 6*z)
|
|
N = M * elt // = elt^(12*z^3 + 12*z^2 + 6*z + 1)
|
|
O = L.Frobenius_map(1) // = elt^(q*(12*z^3 + 6*z^2 + 4*z))
|
|
P = O * N // = elt^(q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1))
|
|
Q = K.Frobenius_map(2) // = elt^(q^2 * (12*z^3 + 6*z^2 + 6*z))
|
|
R = Q * P // = elt^(q^2 * (12*z^3 + 6*z^2 + 6*z) + q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1))
|
|
S = conj(elt) // = elt^(-1)
|
|
T = S * L // = elt^(12*z^3 + 6*z^2 + 4*z - 1)
|
|
U = T.Frobenius_map(3) // = elt^(q^3(12*z^3 + 6*z^2 + 4*z - 1))
|
|
V = U * R // = elt^(q^3(12*z^3 + 6*z^2 + 4*z - 1) + q^2 * (12*z^3 + 6*z^2 + 6*z) + q*(12*z^3 + 6*z^2 + 4*z) * (12*z^3 + 12*z^2 + 6*z + 1))
|
|
result = V
|
|
|
|
*/
|
|
|
|
const alt_bn128_Fq12 A = alt_bn128_exp_by_neg_z(elt);
|
|
const alt_bn128_Fq12 B = A.cyclotomic_squared();
|
|
const alt_bn128_Fq12 C = B.cyclotomic_squared();
|
|
const alt_bn128_Fq12 D = C * B;
|
|
const alt_bn128_Fq12 E = alt_bn128_exp_by_neg_z(D);
|
|
const alt_bn128_Fq12 F = E.cyclotomic_squared();
|
|
const alt_bn128_Fq12 G = alt_bn128_exp_by_neg_z(F);
|
|
const alt_bn128_Fq12 H = D.unitary_inverse();
|
|
const alt_bn128_Fq12 I = G.unitary_inverse();
|
|
const alt_bn128_Fq12 J = I * E;
|
|
const alt_bn128_Fq12 K = J * H;
|
|
const alt_bn128_Fq12 L = K * B;
|
|
const alt_bn128_Fq12 M = K * E;
|
|
const alt_bn128_Fq12 N = M * elt;
|
|
const alt_bn128_Fq12 O = L.Frobenius_map(1);
|
|
const alt_bn128_Fq12 P = O * N;
|
|
const alt_bn128_Fq12 Q = K.Frobenius_map(2);
|
|
const alt_bn128_Fq12 R = Q * P;
|
|
const alt_bn128_Fq12 S = elt.unitary_inverse();
|
|
const alt_bn128_Fq12 T = S * L;
|
|
const alt_bn128_Fq12 U = T.Frobenius_map(3);
|
|
const alt_bn128_Fq12 V = U * R;
|
|
|
|
const alt_bn128_Fq12 result = V;
|
|
|
|
leave_block("Call to alt_bn128_final_exponentiation_last_chunk");
|
|
|
|
return result;
|
|
}
|
|
|
|
alt_bn128_GT alt_bn128_final_exponentiation(const alt_bn128_Fq12 &elt)
|
|
{
|
|
enter_block("Call to alt_bn128_final_exponentiation");
|
|
/* OLD naive version:
|
|
alt_bn128_GT result = elt^alt_bn128_final_exponent;
|
|
*/
|
|
alt_bn128_Fq12 A = alt_bn128_final_exponentiation_first_chunk(elt);
|
|
alt_bn128_GT result = alt_bn128_final_exponentiation_last_chunk(A);
|
|
|
|
leave_block("Call to alt_bn128_final_exponentiation");
|
|
return result;
|
|
}
|
|
|
|
/* ate pairing */
|
|
|
|
void doubling_step_for_flipped_miller_loop(const alt_bn128_Fq two_inv,
|
|
alt_bn128_G2 ¤t,
|
|
alt_bn128_ate_ell_coeffs &c)
|
|
{
|
|
const alt_bn128_Fq2 X = current.X, Y = current.Y, Z = current.Z;
|
|
|
|
const alt_bn128_Fq2 A = two_inv * (X * Y); // A = X1 * Y1 / 2
|
|
const alt_bn128_Fq2 B = Y.squared(); // B = Y1^2
|
|
const alt_bn128_Fq2 C = Z.squared(); // C = Z1^2
|
|
const alt_bn128_Fq2 D = C+C+C; // D = 3 * C
|
|
const alt_bn128_Fq2 E = alt_bn128_twist_coeff_b * D; // E = twist_b * D
|
|
const alt_bn128_Fq2 F = E+E+E; // F = 3 * E
|
|
const alt_bn128_Fq2 G = two_inv * (B+F); // G = (B+F)/2
|
|
const alt_bn128_Fq2 H = (Y+Z).squared() - (B+C); // H = (Y1+Z1)^2-(B+C)
|
|
const alt_bn128_Fq2 I = E-B; // I = E-B
|
|
const alt_bn128_Fq2 J = X.squared(); // J = X1^2
|
|
const alt_bn128_Fq2 E_squared = E.squared(); // E_squared = E^2
|
|
|
|
current.X = A * (B-F); // X3 = A * (B-F)
|
|
current.Y = G.squared() - (E_squared+E_squared+E_squared); // Y3 = G^2 - 3*E^2
|
|
current.Z = B * H; // Z3 = B * H
|
|
c.ell_0 = alt_bn128_twist * I; // ell_0 = xi * I
|
|
c.ell_VW = -H; // ell_VW = - H (later: * yP)
|
|
c.ell_VV = J+J+J; // ell_VV = 3*J (later: * xP)
|
|
}
|
|
|
|
void mixed_addition_step_for_flipped_miller_loop(const alt_bn128_G2 base,
|
|
alt_bn128_G2 ¤t,
|
|
alt_bn128_ate_ell_coeffs &c)
|
|
{
|
|
const alt_bn128_Fq2 X1 = current.X, Y1 = current.Y, Z1 = current.Z;
|
|
const alt_bn128_Fq2 &x2 = base.X, &y2 = base.Y;
|
|
|
|
const alt_bn128_Fq2 D = X1 - x2 * Z1; // D = X1 - X2*Z1
|
|
const alt_bn128_Fq2 E = Y1 - y2 * Z1; // E = Y1 - Y2*Z1
|
|
const alt_bn128_Fq2 F = D.squared(); // F = D^2
|
|
const alt_bn128_Fq2 G = E.squared(); // G = E^2
|
|
const alt_bn128_Fq2 H = D*F; // H = D*F
|
|
const alt_bn128_Fq2 I = X1 * F; // I = X1 * F
|
|
const alt_bn128_Fq2 J = H + Z1*G - (I+I); // J = H + Z1*G - (I+I)
|
|
|
|
current.X = D * J; // X3 = D*J
|
|
current.Y = E * (I-J)-(H * Y1); // Y3 = E*(I-J)-(H*Y1)
|
|
current.Z = Z1 * H; // Z3 = Z1*H
|
|
c.ell_0 = alt_bn128_twist * (E * x2 - D * y2); // ell_0 = xi * (E * X2 - D * Y2)
|
|
c.ell_VV = - E; // ell_VV = - E (later: * xP)
|
|
c.ell_VW = D; // ell_VW = D (later: * yP )
|
|
}
|
|
|
|
alt_bn128_ate_G1_precomp alt_bn128_ate_precompute_G1(const alt_bn128_G1& P)
|
|
{
|
|
enter_block("Call to alt_bn128_ate_precompute_G1");
|
|
|
|
alt_bn128_G1 Pcopy = P;
|
|
Pcopy.to_affine_coordinates();
|
|
|
|
alt_bn128_ate_G1_precomp result;
|
|
result.PX = Pcopy.X;
|
|
result.PY = Pcopy.Y;
|
|
|
|
leave_block("Call to alt_bn128_ate_precompute_G1");
|
|
return result;
|
|
}
|
|
|
|
alt_bn128_ate_G2_precomp alt_bn128_ate_precompute_G2(const alt_bn128_G2& Q)
|
|
{
|
|
enter_block("Call to alt_bn128_ate_precompute_G2");
|
|
|
|
alt_bn128_G2 Qcopy(Q);
|
|
Qcopy.to_affine_coordinates();
|
|
|
|
alt_bn128_Fq two_inv = (alt_bn128_Fq("2").inverse()); // could add to global params if needed
|
|
|
|
alt_bn128_ate_G2_precomp result;
|
|
result.QX = Qcopy.X;
|
|
result.QY = Qcopy.Y;
|
|
|
|
alt_bn128_G2 R;
|
|
R.X = Qcopy.X;
|
|
R.Y = Qcopy.Y;
|
|
R.Z = alt_bn128_Fq2::one();
|
|
|
|
const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count;
|
|
bool found_one = false;
|
|
alt_bn128_ate_ell_coeffs c;
|
|
|
|
for (long i = loop_count.max_bits(); i >= 0; --i)
|
|
{
|
|
const bool bit = loop_count.test_bit(i);
|
|
if (!found_one)
|
|
{
|
|
/* this skips the MSB itself */
|
|
found_one |= bit;
|
|
continue;
|
|
}
|
|
|
|
doubling_step_for_flipped_miller_loop(two_inv, R, c);
|
|
result.coeffs.push_back(c);
|
|
|
|
if (bit)
|
|
{
|
|
mixed_addition_step_for_flipped_miller_loop(Qcopy, R, c);
|
|
result.coeffs.push_back(c);
|
|
}
|
|
}
|
|
|
|
alt_bn128_G2 Q1 = Qcopy.mul_by_q();
|
|
assert_except(Q1.Z == alt_bn128_Fq2::one());
|
|
alt_bn128_G2 Q2 = Q1.mul_by_q();
|
|
assert_except(Q2.Z == alt_bn128_Fq2::one());
|
|
|
|
if (alt_bn128_ate_is_loop_count_neg)
|
|
{
|
|
R.Y = - R.Y;
|
|
}
|
|
Q2.Y = - Q2.Y;
|
|
|
|
mixed_addition_step_for_flipped_miller_loop(Q1, R, c);
|
|
result.coeffs.push_back(c);
|
|
|
|
mixed_addition_step_for_flipped_miller_loop(Q2, R, c);
|
|
result.coeffs.push_back(c);
|
|
|
|
leave_block("Call to alt_bn128_ate_precompute_G2");
|
|
return result;
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_ate_miller_loop(const alt_bn128_ate_G1_precomp &prec_P,
|
|
const alt_bn128_ate_G2_precomp &prec_Q)
|
|
{
|
|
enter_block("Call to alt_bn128_ate_miller_loop");
|
|
|
|
alt_bn128_Fq12 f = alt_bn128_Fq12::one();
|
|
|
|
bool found_one = false;
|
|
size_t idx = 0;
|
|
|
|
const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count;
|
|
alt_bn128_ate_ell_coeffs c;
|
|
|
|
for (long i = loop_count.max_bits(); i >= 0; --i)
|
|
{
|
|
const bool bit = loop_count.test_bit(i);
|
|
if (!found_one)
|
|
{
|
|
/* this skips the MSB itself */
|
|
found_one |= bit;
|
|
continue;
|
|
}
|
|
|
|
/* code below gets executed for all bits (EXCEPT the MSB itself) of
|
|
alt_bn128_param_p (skipping leading zeros) in MSB to LSB
|
|
order */
|
|
|
|
c = prec_Q.coeffs[idx++];
|
|
f = f.squared();
|
|
f = f.mul_by_024(c.ell_0, prec_P.PY * c.ell_VW, prec_P.PX * c.ell_VV);
|
|
|
|
if (bit)
|
|
{
|
|
c = prec_Q.coeffs[idx++];
|
|
f = f.mul_by_024(c.ell_0, prec_P.PY * c.ell_VW, prec_P.PX * c.ell_VV);
|
|
}
|
|
|
|
}
|
|
|
|
if (alt_bn128_ate_is_loop_count_neg)
|
|
{
|
|
f = f.inverse();
|
|
}
|
|
|
|
c = prec_Q.coeffs[idx++];
|
|
f = f.mul_by_024(c.ell_0,prec_P.PY * c.ell_VW,prec_P.PX * c.ell_VV);
|
|
|
|
c = prec_Q.coeffs[idx++];
|
|
f = f.mul_by_024(c.ell_0,prec_P.PY * c.ell_VW,prec_P.PX * c.ell_VV);
|
|
|
|
leave_block("Call to alt_bn128_ate_miller_loop");
|
|
return f;
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_ate_double_miller_loop(const alt_bn128_ate_G1_precomp &prec_P1,
|
|
const alt_bn128_ate_G2_precomp &prec_Q1,
|
|
const alt_bn128_ate_G1_precomp &prec_P2,
|
|
const alt_bn128_ate_G2_precomp &prec_Q2)
|
|
{
|
|
enter_block("Call to alt_bn128_ate_double_miller_loop");
|
|
|
|
alt_bn128_Fq12 f = alt_bn128_Fq12::one();
|
|
|
|
bool found_one = false;
|
|
size_t idx = 0;
|
|
|
|
const bigint<alt_bn128_Fr::num_limbs> &loop_count = alt_bn128_ate_loop_count;
|
|
for (long i = loop_count.max_bits(); i >= 0; --i)
|
|
{
|
|
const bool bit = loop_count.test_bit(i);
|
|
if (!found_one)
|
|
{
|
|
/* this skips the MSB itself */
|
|
found_one |= bit;
|
|
continue;
|
|
}
|
|
|
|
/* code below gets executed for all bits (EXCEPT the MSB itself) of
|
|
alt_bn128_param_p (skipping leading zeros) in MSB to LSB
|
|
order */
|
|
|
|
alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx];
|
|
alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx];
|
|
++idx;
|
|
|
|
f = f.squared();
|
|
|
|
f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV);
|
|
f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV);
|
|
|
|
if (bit)
|
|
{
|
|
alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx];
|
|
alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx];
|
|
++idx;
|
|
|
|
f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV);
|
|
f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV);
|
|
}
|
|
}
|
|
|
|
if (alt_bn128_ate_is_loop_count_neg)
|
|
{
|
|
f = f.inverse();
|
|
}
|
|
|
|
alt_bn128_ate_ell_coeffs c1 = prec_Q1.coeffs[idx];
|
|
alt_bn128_ate_ell_coeffs c2 = prec_Q2.coeffs[idx];
|
|
++idx;
|
|
f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV);
|
|
f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV);
|
|
|
|
c1 = prec_Q1.coeffs[idx];
|
|
c2 = prec_Q2.coeffs[idx];
|
|
++idx;
|
|
f = f.mul_by_024(c1.ell_0, prec_P1.PY * c1.ell_VW, prec_P1.PX * c1.ell_VV);
|
|
f = f.mul_by_024(c2.ell_0, prec_P2.PY * c2.ell_VW, prec_P2.PX * c2.ell_VV);
|
|
|
|
leave_block("Call to alt_bn128_ate_double_miller_loop");
|
|
|
|
return f;
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_ate_pairing(const alt_bn128_G1& P, const alt_bn128_G2 &Q)
|
|
{
|
|
enter_block("Call to alt_bn128_ate_pairing");
|
|
alt_bn128_ate_G1_precomp prec_P = alt_bn128_ate_precompute_G1(P);
|
|
alt_bn128_ate_G2_precomp prec_Q = alt_bn128_ate_precompute_G2(Q);
|
|
alt_bn128_Fq12 result = alt_bn128_ate_miller_loop(prec_P, prec_Q);
|
|
leave_block("Call to alt_bn128_ate_pairing");
|
|
return result;
|
|
}
|
|
|
|
alt_bn128_GT alt_bn128_ate_reduced_pairing(const alt_bn128_G1 &P, const alt_bn128_G2 &Q)
|
|
{
|
|
enter_block("Call to alt_bn128_ate_reduced_pairing");
|
|
const alt_bn128_Fq12 f = alt_bn128_ate_pairing(P, Q);
|
|
const alt_bn128_GT result = alt_bn128_final_exponentiation(f);
|
|
leave_block("Call to alt_bn128_ate_reduced_pairing");
|
|
return result;
|
|
}
|
|
|
|
/* choice of pairing */
|
|
|
|
alt_bn128_G1_precomp alt_bn128_precompute_G1(const alt_bn128_G1& P)
|
|
{
|
|
return alt_bn128_ate_precompute_G1(P);
|
|
}
|
|
|
|
alt_bn128_G2_precomp alt_bn128_precompute_G2(const alt_bn128_G2& Q)
|
|
{
|
|
return alt_bn128_ate_precompute_G2(Q);
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_miller_loop(const alt_bn128_G1_precomp &prec_P,
|
|
const alt_bn128_G2_precomp &prec_Q)
|
|
{
|
|
return alt_bn128_ate_miller_loop(prec_P, prec_Q);
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_double_miller_loop(const alt_bn128_G1_precomp &prec_P1,
|
|
const alt_bn128_G2_precomp &prec_Q1,
|
|
const alt_bn128_G1_precomp &prec_P2,
|
|
const alt_bn128_G2_precomp &prec_Q2)
|
|
{
|
|
return alt_bn128_ate_double_miller_loop(prec_P1, prec_Q1, prec_P2, prec_Q2);
|
|
}
|
|
|
|
alt_bn128_Fq12 alt_bn128_pairing(const alt_bn128_G1& P,
|
|
const alt_bn128_G2 &Q)
|
|
{
|
|
return alt_bn128_ate_pairing(P, Q);
|
|
}
|
|
|
|
alt_bn128_GT alt_bn128_reduced_pairing(const alt_bn128_G1 &P,
|
|
const alt_bn128_G2 &Q)
|
|
{
|
|
return alt_bn128_ate_reduced_pairing(P, Q);
|
|
}
|
|
} // libsnark
|
|
|