diff --git a/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp b/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp index 214e96c2..3b231077 100755 --- a/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp +++ b/libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp @@ -152,10 +152,9 @@ alt_bn128_G1 alt_bn128_G1::operator+(const alt_bn128_G1 &other) const // no need to handle points of order 2,4 // (they cannot exist in a prime-order subgroup) - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) + // using Jacobian coordinates according to + // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + // Note: (X1:Y1:Z1) = (X2:Y2:Z2) // iff // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 // iff @@ -173,12 +172,17 @@ alt_bn128_G1 alt_bn128_G1::operator+(const alt_bn128_G1 &other) const alt_bn128_Fq S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2 alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + // check for doubling case if (U1 == U2 && S1 == S2) { // dbl case; nothing of above can be reused return this->dbl(); } +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif + // rest of add case alt_bn128_Fq H = U2 - U1; // H = U2-U1 alt_bn128_Fq S2_minus_S1 = S2-S1; @@ -207,50 +211,7 @@ alt_bn128_G1 alt_bn128_G1::operator-(const alt_bn128_G1 &other) const alt_bn128_G1 alt_bn128_G1::add(const alt_bn128_G1 &other) const { - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // handle double case - if (this->operator==(other)) - { - return this->dbl(); - } - -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl - - alt_bn128_Fq Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2 - alt_bn128_Fq Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2 - alt_bn128_Fq U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2 - alt_bn128_Fq U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1 - alt_bn128_Fq S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2 - alt_bn128_Fq S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1 - alt_bn128_Fq H = U2 - U1; // H = U2-U1 - alt_bn128_Fq S2_minus_S1 = S2-S1; - alt_bn128_Fq I = (H+H).squared(); // I = (2 * H)^2 - alt_bn128_Fq J = H * I; // J = H * I - alt_bn128_Fq r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) - alt_bn128_Fq V = U1 * I; // V = U1 * I - alt_bn128_Fq X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V - alt_bn128_Fq S1_J = S1 * J; - alt_bn128_Fq Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J - alt_bn128_Fq Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return alt_bn128_G1(X3, Y3, Z3); + return (*this) + other; } alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const @@ -273,15 +234,13 @@ alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const // no need to handle points of order 2,4 // (they cannot exist in a prime-order subgroup) - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) + // using Jacobian coordinates according to + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + // Note: (X1:Y1:Z1) = (X2:Y2:Z2) // iff // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 // iff // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - // we know that Z2 = 1 const alt_bn128_Fq Z1Z1 = (this->Z).squared(); @@ -294,6 +253,7 @@ alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const const alt_bn128_Fq &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2 const alt_bn128_Fq S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + // check for doubling case if (U1 == U2 && S1 == S2) { // dbl case; nothing of above can be reused @@ -303,11 +263,9 @@ alt_bn128_G1 alt_bn128_G1::mixed_add(const alt_bn128_G1 &other) const #ifdef PROFILE_OP_COUNTS this->add_cnt++; #endif - - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + alt_bn128_Fq H = U2-(this->X); // H = U2-X1 - alt_bn128_Fq HH = H.squared() ; // HH = H&2 + alt_bn128_Fq HH = H.squared() ; // HH = H^2 alt_bn128_Fq I = HH+HH; // I = 4*HH I = I + I; alt_bn128_Fq J = H*I; // J = H*I @@ -336,9 +294,9 @@ alt_bn128_G1 alt_bn128_G1::dbl() const // no need to handle points of order 2,4 // (they cannot exist in a prime-order subgroup) - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - + // using Jacobian coordinates according to + // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + alt_bn128_Fq A = (this->X).squared(); // A = X1^2 alt_bn128_Fq B = (this->Y).squared(); // B = Y1^2 alt_bn128_Fq C = B.squared(); // C = B^2 diff --git a/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp b/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp index 4e8c9944..81183098 100755 --- a/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp +++ b/libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp @@ -162,10 +162,9 @@ alt_bn128_G2 alt_bn128_G2::operator+(const alt_bn128_G2 &other) const // no need to handle points of order 2,4 // (they cannot exist in a prime-order subgroup) - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) + // using Jacobian coordinates according to + // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + // Note: (X1:Y1:Z1) = (X2:Y2:Z2) // iff // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 // iff @@ -183,12 +182,17 @@ alt_bn128_G2 alt_bn128_G2::operator+(const alt_bn128_G2 &other) const alt_bn128_Fq2 S1 = (this->Y) * Z2_cubed; // S1 = Y1 * Z2 * Z2Z2 alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + // check for doubling case if (U1 == U2 && S1 == S2) { // dbl case; nothing of above can be reused return this->dbl(); } +#ifdef PROFILE_OP_COUNTS + this->add_cnt++; +#endif + // rest of add case alt_bn128_Fq2 H = U2 - U1; // H = U2-U1 alt_bn128_Fq2 S2_minus_S1 = S2-S1; @@ -217,50 +221,7 @@ alt_bn128_G2 alt_bn128_G2::operator-(const alt_bn128_G2 &other) const alt_bn128_G2 alt_bn128_G2::add(const alt_bn128_G2 &other) const { - // handle special cases having to do with O - if (this->is_zero()) - { - return other; - } - - if (other.is_zero()) - { - return *this; - } - - // no need to handle points of order 2,4 - // (they cannot exist in a prime-order subgroup) - - // handle double case - if (this->operator==(other)) - { - return this->dbl(); - } - -#ifdef PROFILE_OP_COUNTS - this->add_cnt++; -#endif - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#addition-add-1998-cmo-2 - - alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); // Z1Z1 = Z1^2 - alt_bn128_Fq2 Z2Z2 = (other.Z).squared(); // Z2Z2 = Z2^2 - alt_bn128_Fq2 U1 = (this->X) * Z2Z2; // U1 = X1 * Z2Z2 - alt_bn128_Fq2 U2 = (other.X) * Z1Z1; // U2 = X2 * Z1Z1 - alt_bn128_Fq2 S1 = (this->Y) * (other.Z) * Z2Z2; // S1 = Y1 * Z2 * Z2Z2 - alt_bn128_Fq2 S2 = (other.Y) * (this->Z) * Z1Z1; // S2 = Y2 * Z1 * Z1Z1 - alt_bn128_Fq2 H = U2 - U1; // H = U2-U1 - alt_bn128_Fq2 S2_minus_S1 = S2-S1; - alt_bn128_Fq2 I = (H+H).squared(); // I = (2 * H)^2 - alt_bn128_Fq2 J = H * I; // J = H * I - alt_bn128_Fq2 r = S2_minus_S1 + S2_minus_S1; // r = 2 * (S2-S1) - alt_bn128_Fq2 V = U1 * I; // V = U1 * I - alt_bn128_Fq2 X3 = r.squared() - J - (V+V); // X3 = r^2 - J - 2 * V - alt_bn128_Fq2 S1_J = S1 * J; - alt_bn128_Fq2 Y3 = r * (V-X3) - (S1_J+S1_J); // Y3 = r * (V-X3)-2 S1 J - alt_bn128_Fq2 Z3 = ((this->Z+other.Z).squared()-Z1Z1-Z2Z2) * H; // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return alt_bn128_G2(X3, Y3, Z3); + return (*this) + other; } alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const @@ -283,15 +244,13 @@ alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const // no need to handle points of order 2,4 // (they cannot exist in a prime-order subgroup) - // check for doubling case - - // using Jacobian coordinates so: - // (X1:Y1:Z1) = (X2:Y2:Z2) + // using Jacobian coordinates according to + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + // Note: (X1:Y1:Z1) = (X2:Y2:Z2) // iff // X1/Z1^2 == X2/Z2^2 and Y1/Z1^3 == Y2/Z2^3 // iff // X1 * Z2^2 == X2 * Z1^2 and Y1 * Z2^3 == Y2 * Z1^3 - // we know that Z2 = 1 const alt_bn128_Fq2 Z1Z1 = (this->Z).squared(); @@ -304,6 +263,7 @@ alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const const alt_bn128_Fq2 &S1 = (this->Y); // S1 = Y1 * Z2 * Z2Z2 const alt_bn128_Fq2 S2 = (other.Y) * Z1_cubed; // S2 = Y2 * Z1 * Z1Z1 + // check for doubling case if (U1 == U2 && S1 == S2) { // dbl case; nothing of above can be reused @@ -314,10 +274,8 @@ alt_bn128_G2 alt_bn128_G2::mixed_add(const alt_bn128_G2 &other) const this->add_cnt++; #endif - // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl alt_bn128_Fq2 H = U2-(this->X); // H = U2-X1 - alt_bn128_Fq2 HH = H.squared() ; // HH = H&2 + alt_bn128_Fq2 HH = H.squared() ; // HH = H^2 alt_bn128_Fq2 I = HH+HH; // I = 4*HH I = I + I; alt_bn128_Fq2 J = H*I; // J = H*I @@ -344,8 +302,11 @@ alt_bn128_G2 alt_bn128_G2::dbl() const } // NOTE: does not handle O and pts of order 2,4 - // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-projective.html#doubling-dbl-2007-bl + // (they cannot exist in a prime-order subgroup) + // using Jacobian coordinates according to + // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + alt_bn128_Fq2 A = (this->X).squared(); // A = X1^2 alt_bn128_Fq2 B = (this->Y).squared(); // B = Y1^2 alt_bn128_Fq2 C = B.squared(); // C = B^2