Skip to content

Commit

Permalink
Adding zero tests #140
Browse files Browse the repository at this point in the history
Reviewed MNT curves implementation, fixed pairing with infinity bug #140

Updated tests for pairing with infinity #140
  • Loading branch information
vo-nil committed Feb 28, 2024
1 parent 09f9ee0 commit 64ca893
Show file tree
Hide file tree
Showing 14 changed files with 83 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ namespace nil {
using result_type =
curve_element<params_type, form, typename curves::coordinates::projective>;

if (is_zero()) {
return result_type::zero();
}

return result_type(X, Y,
result_type::field_type::value_type::one()); // X = x, Y = y, Z = 1
}
Expand Down
7 changes: 7 additions & 0 deletions include/nil/crypto3/algebra/fields/bls12/scalar_field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ namespace nil {
constexpr static const integral_type modulus =
0x73EDA753299D7D483339D80809A1D80553BDA402FFFE5BFEFFFFFFFF00000001_cppui255;

constexpr static const integral_type group_order_minus_one_half =
0x39F6D3A994CEBEA4199CEC0404D0EC02A9DED2017FFF2DFF7FFFFFFF80000000_cppui255;

typedef typename policy_type::modular_backend modular_backend;
constexpr static const modular_params_type modulus_params = modulus;
typedef nil::crypto3::multiprecision::number<
Expand Down Expand Up @@ -92,6 +95,8 @@ namespace nil {

constexpr static const integral_type modulus =
0x12AB655E9A2CA55660B44D1E5C37B00159AA76FED00000010A11800000000001_cppui253;
constexpr static const integral_type group_order_minus_one_half =
0x0955B2AF4D1652AB305A268F2E1BD800ACD53B7F680000008508C00000000000_cppui253;

typedef typename policy_type::modular_backend modular_backend;
constexpr static const modular_params_type modulus_params = modulus;
Expand All @@ -118,6 +123,8 @@ namespace nil {
#else
constexpr typename bls12_scalar_field<381>::integral_type const bls12_scalar_field<381>::modulus;
constexpr typename bls12_scalar_field<377>::integral_type const bls12_scalar_field<377>::modulus;
constexpr typename bls12_scalar_field<381>::integral_type const bls12_scalar_field<381>::group_order_minus_one_half;
constexpr typename bls12_scalar_field<377>::integral_type const bls12_scalar_field<377>::group_order_minus_one_half;

constexpr
typename bls12_scalar_field<381>::modular_params_type const bls12_scalar_field<381>::modulus_params;
Expand Down
3 changes: 3 additions & 0 deletions include/nil/crypto3/algebra/fields/edwards/base_field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ namespace nil {

constexpr static const integral_type modulus =
0x40D5FC9D2A395B138B924ED6342D41B6EB690B80000001_cppui183;
constexpr static const integral_type group_order_minus_one_half =
0x206AFE4E951CAD89C5C9276B1A16A0DB75B485C0000000_cppui183;

typedef typename policy_type::modular_backend modular_backend;
constexpr static const modular_params_type modulus_params = modulus;
Expand All @@ -78,6 +80,7 @@ namespace nil {
constexpr typename std::size_t const edwards_base_field<183>::value_bits;

constexpr typename edwards_base_field<183>::integral_type const edwards_base_field<183>::modulus;
constexpr typename edwards_base_field<183>::integral_type const edwards_base_field<183>::group_order_minus_one_half;

constexpr typename edwards_base_field<183>::modular_params_type const edwards_base_field<183>::modulus_params;

Expand Down
5 changes: 5 additions & 0 deletions include/nil/crypto3/algebra/fields/mnt4/base_field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ namespace nil {
constexpr static const integral_type modulus =
0x3BCF7BCD473A266249DA7B0548ECAEEC9635D1330EA41A9E35E51200E12C90CD65A71660001_cppui298;

constexpr static const integral_type group_order_minus_one_half =
0x1DE7BDE6A39D133124ED3D82A47657764B1AE89987520D4F1AF2890070964866B2D38B30000_cppui298;

typedef typename policy_type::modular_backend modular_backend;
constexpr static const modular_params_type modulus_params = modulus;
typedef nil::crypto3::multiprecision::number<
Expand All @@ -81,6 +84,8 @@ namespace nil {

constexpr typename mnt4_base_field<298>::integral_type const mnt4_base_field<298>::modulus;

constexpr typename mnt4_base_field<298>::integral_type const mnt4_base_field<298>::group_order_minus_one_half;

constexpr typename mnt4_base_field<298>::modular_params_type const mnt4_base_field<298>::modulus_params;

template<std::size_t Version = 298>
Expand Down
4 changes: 4 additions & 0 deletions include/nil/crypto3/algebra/fields/mnt6/base_field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ namespace nil {
constexpr static const integral_type modulus =
0x3BCF7BCD473A266249DA7B0548ECAEEC9635CF44194FB494C07925D6AD3BB4334A400000001_cppui298;

constexpr static const integral_type group_order_minus_one_half =
0x1DE7BDE6A39D133124ED3D82A47657764B1AE7A20CA7DA4A603C92EB569DDA19A5200000000_cppui298;

typedef typename policy_type::modular_backend modular_backend;
constexpr static const modular_params_type modulus_params = modulus;
typedef nil::crypto3::multiprecision::number<
Expand All @@ -80,6 +83,7 @@ namespace nil {
constexpr typename std::size_t const mnt6_base_field<298>::value_bits;

constexpr typename mnt6_base_field<298>::integral_type const mnt6_base_field<298>::modulus;
constexpr typename mnt6_base_field<298>::integral_type const mnt6_base_field<298>::group_order_minus_one_half;

constexpr typename mnt6_base_field<298>::modular_params_type const mnt6_base_field<298>::modulus_params;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,11 @@ namespace nil {

g1 Pcopy = P.to_affine();

if (P.is_zero()) {
Pcopy.X = g1_type::field_type::value_type::zero();
Pcopy.Y = g1_type::field_type::value_type::zero();
}

ate_g1_precomputed_type result;
result.PX = Pcopy.X;
result.PY = Pcopy.Y;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#ifndef CRYPTO3_ALGEBRA_PAIRING_SHORT_WEIERSTRASS_PROJECTIVE_TYPES_POLICY_HPP
#define CRYPTO3_ALGEBRA_PAIRING_SHORT_WEIERSTRASS_PROJECTIVE_TYPES_POLICY_HPP

#include <vector>

namespace nil {
namespace crypto3 {
namespace algebra {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ namespace nil {

typename g1_affine_type::value_type Pcopy = P.to_affine();

if (P.is_zero()) {
Pcopy.X = g1_type::field_type::value_type::zero();
Pcopy.Y = g1_type::field_type::value_type::zero();
}

g1_precomputed_type result;
result.PX = Pcopy.X;
result.PY = Pcopy.Y;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ namespace nil {

typename g1_affine_type::value_type Pcopy = P.to_affine();

if (P.is_zero()) {
Pcopy.X = g1_type::field_type::value_type::zero();
Pcopy.Y = g1_type::field_type::value_type::zero();
}

g1_precomputed_type result;
result.PX = Pcopy.X;
result.PY = Pcopy.Y;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ namespace nil {

typename g1_affine_type::value_type Pcopy = P.to_affine();

if (P.is_zero()) {
Pcopy.X = g1_type::field_type::value_type::zero();
Pcopy.Y = g1_type::field_type::value_type::zero();
}

g1_precomputed_type result;
result.PX = Pcopy.X;
result.PY = Pcopy.Y;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ namespace nil {
const policy_type::ate_g2_precomputed_type &prec_Q) {

g2_field_type_value L1_coeff =
g2_field_type_value(prec_P.PX, g1_field_type_value::zero()) - prec_Q.QX_over_twist;
g2_field_type_value(prec_P.PX, g1_field_type_value::zero()) -
prec_Q.QX_over_twist;

typename gt_type::value_type f = gt_type::value_type::one();

Expand Down
24 changes: 18 additions & 6 deletions include/nil/crypto3/algebra/pairing/mnt6/298/ate_miller_loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,17 @@ namespace nil {
using g2_field_type_value = typename g2_type::field_type::value_type;

public:
static typename gt_type::value_type process(const policy_type::ate_g1_precomputed_type &prec_P,
const policy_type::ate_g2_precomputed_type &prec_Q) {

/*
* This code is close replica of arkworks implementation
* https://github.com/arkworks-rs/algebra/blob/30ad93b079d345bef03f53d92b1ef7017936af85/ec/src/models/mnt6/mod.rs#L140
*
* The difference is that arkworks are using signed bit representation (-1, 0, 1) of
* ate_loop_count constant, but here is unsigned variant (0, 1).
*/
static typename gt_type::value_type process(
const policy_type::ate_g1_precomputed_type &prec_P,
const policy_type::ate_g2_precomputed_type &prec_Q) {

g2_field_type_value L1_coeff =
g2_field_type_value(prec_P.PX, g1_field_type_value::zero(), g1_field_type_value::zero()) -
Expand All @@ -71,7 +80,7 @@ namespace nil {
std::size_t add_idx = 0;

for (long i = params_type::integral_type_max_bits - 1; i >= 0; --i) {
const bool bit = nil::crypto3::multiprecision::bit_test(params_type::ate_loop_count, i);
const bool bit = multiprecision::bit_test(params_type::ate_loop_count, i);

if (!found_one) {
/* this skips the MSB itself */
Expand All @@ -85,21 +94,24 @@ namespace nil {
typename policy_type::ate_dbl_coeffs dc = prec_Q.dbl_coeffs[dbl_idx++];

typename gt_type::value_type g_RR_at_P = typename gt_type::value_type(
-dc.c_4C - dc.c_J * prec_P.PX_twist + dc.c_L, dc.c_H * prec_P.PY_twist);
dc.c_L - dc.c_4C - dc.c_J * prec_P.PX_twist,
dc.c_H * prec_P.PY_twist);
f = f.squared() * g_RR_at_P;

if (bit) {
typename policy_type::ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
typename gt_type::value_type g_RQ_at_P = typename gt_type::value_type(
ac.c_RZ * prec_P.PY_twist, -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
ac.c_RZ * prec_P.PY_twist,
-(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1) );
f = f * g_RQ_at_P;
}
}

if (params_type::ate_is_loop_count_neg) {
typename policy_type::ate_add_coeffs ac = prec_Q.add_coeffs[add_idx++];
typename gt_type::value_type g_RnegR_at_P = typename gt_type::value_type(
ac.c_RZ * prec_P.PY_twist, -(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1));
ac.c_RZ * prec_P.PY_twist,
-(prec_Q.QY_over_twist * ac.c_RZ + L1_coeff * ac.c_L1) );
f = (f * g_RnegR_at_P).inversed();
}

Expand Down
5 changes: 5 additions & 0 deletions test/curves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ void check_curve_operations(const std::vector<typename CurveGroup::value_type> &
const std::vector<std::size_t> &constants) {
using nil::crypto3::multiprecision::cpp_int;

BOOST_CHECK_EQUAL(points[p1] + CurveGroup::value_type::zero(), points[p1]);
BOOST_CHECK_EQUAL(points[p1] - CurveGroup::value_type::zero(), points[p1]);
BOOST_CHECK_EQUAL(points[p1] - points[p1], CurveGroup::value_type::zero());
BOOST_CHECK_EQUAL(points[p1] * static_cast<cpp_int>(0), CurveGroup::value_type::zero());

BOOST_CHECK_EQUAL(points[p1] + points[p2], points[p1_plus_p2]);
BOOST_CHECK_EQUAL(points[p1] - points[p2], points[p1_minus_p2]);
BOOST_CHECK_EQUAL(points[p1].doubled(), points[p1_dbl]);
Expand Down
13 changes: 13 additions & 0 deletions test/pairing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,10 @@ void check_pairing_operations(std::vector<Fr_value_type> &Fr_elements,
BOOST_CHECK_EQUAL((Fr_elements[A2_poly] * Fr_elements[B2_poly] - Fr_elements[VKx_poly] * Fr_elements[VKy_poly]) *
Fr_elements[VKz_poly].inversed(),
Fr_elements[C2_poly]);

BOOST_CHECK_EQUAL(Fr_elements[A1_poly] * G1_value_type::zero(), G1_value_type::zero());
BOOST_CHECK_EQUAL(Fr_elements[B1_poly] * G2_value_type::zero(), G2_value_type::zero());

BOOST_CHECK_EQUAL(Fr_elements[VKx_poly] * G1_value_type::one(), G1_elements[VKx]);
BOOST_CHECK_EQUAL(Fr_elements[VKy_poly] * G2_value_type::one(), G2_elements[VKy]);
BOOST_CHECK_EQUAL(Fr_elements[VKz_poly] * G2_value_type::one(), G2_elements[VKz]);
Expand All @@ -459,6 +463,15 @@ void check_pairing_operations(std::vector<Fr_value_type> &Fr_elements,
BOOST_CHECK_EQUAL(Fr_elements[B2_poly] * G2_value_type::one(), G2_elements[B2]);
std::cout << " * Basic fields and groups tests finished." << std::endl << std::endl;

std::cout << " * Pairing with infinity tests started..." << std::endl;
BOOST_CHECK_EQUAL(final_exponentiation<CurveType>(pair<CurveType>(G1_value_type::zero(), G2_elements[B1])), GT_value_type::one());
std::cout << " * Pairing with infinity tests finished." << std::endl << std::endl;

std::cout << " * Reduced pairing with infinity tests started..." << std::endl;
BOOST_CHECK_EQUAL(pair_reduced<CurveType>(G1_value_type::zero(), G2_elements[B1]), GT_value_type::one());
std::cout << " * Reduced pairing with infinity tests finished." << std::endl << std::endl;


std::cout << " * Precomputing and pairing tests started..." << std::endl;
BOOST_CHECK_EQUAL(precompute_g1<CurveType>(G1_elements[A1]), G1_prec_elements[prec_A1]);
BOOST_CHECK_EQUAL(precompute_g1<CurveType>(G1_elements[A2]), G1_prec_elements[prec_A2]);
Expand Down

0 comments on commit 64ca893

Please sign in to comment.