Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove code duplication in alt_bn128 add functions and update docs #20

Merged
merged 2 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 18 additions & 60 deletions libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
75 changes: 18 additions & 57 deletions libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down