Files
SuperVPN/output/Libraries/BouncyCastle.Crypto/Org/BouncyCastle/Math/EC/FpPoint.cs
2025-10-09 09:57:24 +09:00

604 lines
21 KiB
C#

using System;
namespace Org.BouncyCastle.Math.EC;
public class FpPoint : AbstractFpPoint
{
[Obsolete("Use ECCurve.CreatePoint to construct points")]
public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)
: this(curve, x, y, withCompression: false)
{
}
[Obsolete("Per-point compression property will be removed, see GetEncoded(bool)")]
public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
: base(curve, x, y, withCompression)
{
if (x == null != (y == null))
{
throw new ArgumentException("Exactly one of the field elements is null");
}
}
internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
: base(curve, x, y, zs, withCompression)
{
}
protected override ECPoint Detach()
{
return new FpPoint(null, AffineXCoord, AffineYCoord, withCompression: false);
}
public override ECFieldElement GetZCoord(int index)
{
if (index == 1 && 4 == CurveCoordinateSystem)
{
return GetJacobianModifiedW();
}
return base.GetZCoord(index);
}
public override ECPoint Add(ECPoint b)
{
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return this;
}
if (this == b)
{
return Twice();
}
ECCurve curve = Curve;
int coordinateSystem = curve.CoordinateSystem;
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement rawYCoord2 = b.RawYCoord;
switch (coordinateSystem)
{
case 0:
{
ECFieldElement eCFieldElement32 = rawXCoord2.Subtract(rawXCoord);
ECFieldElement eCFieldElement33 = rawYCoord2.Subtract(rawYCoord);
if (eCFieldElement32.IsZero)
{
if (eCFieldElement33.IsZero)
{
return Twice();
}
return Curve.Infinity;
}
ECFieldElement eCFieldElement34 = eCFieldElement33.Divide(eCFieldElement32);
ECFieldElement eCFieldElement35 = eCFieldElement34.Square().Subtract(rawXCoord).Subtract(rawXCoord2);
ECFieldElement y3 = eCFieldElement34.Multiply(rawXCoord.Subtract(eCFieldElement35)).Subtract(rawYCoord);
return new FpPoint(Curve, eCFieldElement35, y3, base.IsCompressed);
}
case 1:
{
ECFieldElement eCFieldElement21 = base.RawZCoords[0];
ECFieldElement eCFieldElement22 = b.RawZCoords[0];
bool isOne3 = eCFieldElement21.IsOne;
bool isOne4 = eCFieldElement22.IsOne;
ECFieldElement eCFieldElement23 = (isOne3 ? rawYCoord2 : rawYCoord2.Multiply(eCFieldElement21));
ECFieldElement eCFieldElement24 = (isOne4 ? rawYCoord : rawYCoord.Multiply(eCFieldElement22));
ECFieldElement eCFieldElement25 = eCFieldElement23.Subtract(eCFieldElement24);
ECFieldElement eCFieldElement26 = (isOne3 ? rawXCoord2 : rawXCoord2.Multiply(eCFieldElement21));
ECFieldElement b6 = (isOne4 ? rawXCoord : rawXCoord.Multiply(eCFieldElement22));
ECFieldElement eCFieldElement27 = eCFieldElement26.Subtract(b6);
if (eCFieldElement27.IsZero)
{
if (eCFieldElement25.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement b7 = (isOne3 ? eCFieldElement22 : (isOne4 ? eCFieldElement21 : eCFieldElement21.Multiply(eCFieldElement22)));
ECFieldElement eCFieldElement28 = eCFieldElement27.Square();
ECFieldElement eCFieldElement29 = eCFieldElement28.Multiply(eCFieldElement27);
ECFieldElement eCFieldElement30 = eCFieldElement28.Multiply(b6);
ECFieldElement b8 = eCFieldElement25.Square().Multiply(b7).Subtract(eCFieldElement29)
.Subtract(Two(eCFieldElement30));
ECFieldElement x = eCFieldElement27.Multiply(b8);
ECFieldElement y2 = eCFieldElement30.Subtract(b8).MultiplyMinusProduct(eCFieldElement25, eCFieldElement24, eCFieldElement29);
ECFieldElement eCFieldElement31 = eCFieldElement29.Multiply(b7);
return new FpPoint(curve, x, y2, new ECFieldElement[1] { eCFieldElement31 }, base.IsCompressed);
}
case 2:
case 4:
{
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement eCFieldElement2 = b.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement zSquared = null;
ECFieldElement eCFieldElement7;
ECFieldElement y;
ECFieldElement eCFieldElement8;
if (!isOne && eCFieldElement.Equals(eCFieldElement2))
{
ECFieldElement eCFieldElement3 = rawXCoord.Subtract(rawXCoord2);
ECFieldElement eCFieldElement4 = rawYCoord.Subtract(rawYCoord2);
if (eCFieldElement3.IsZero)
{
if (eCFieldElement4.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement5 = eCFieldElement3.Square();
ECFieldElement eCFieldElement6 = rawXCoord.Multiply(eCFieldElement5);
ECFieldElement b2 = rawXCoord2.Multiply(eCFieldElement5);
ECFieldElement b3 = eCFieldElement6.Subtract(b2).Multiply(rawYCoord);
eCFieldElement7 = eCFieldElement4.Square().Subtract(eCFieldElement6).Subtract(b2);
y = eCFieldElement6.Subtract(eCFieldElement7).Multiply(eCFieldElement4).Subtract(b3);
eCFieldElement8 = eCFieldElement3;
if (isOne)
{
zSquared = eCFieldElement5;
}
else
{
eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement);
}
}
else
{
ECFieldElement b4;
ECFieldElement b5;
if (isOne)
{
ECFieldElement eCFieldElement9 = eCFieldElement;
b4 = rawXCoord2;
b5 = rawYCoord2;
}
else
{
ECFieldElement eCFieldElement9 = eCFieldElement.Square();
b4 = eCFieldElement9.Multiply(rawXCoord2);
ECFieldElement eCFieldElement10 = eCFieldElement9.Multiply(eCFieldElement);
b5 = eCFieldElement10.Multiply(rawYCoord2);
}
bool isOne2 = eCFieldElement2.IsOne;
ECFieldElement eCFieldElement12;
ECFieldElement eCFieldElement13;
if (isOne2)
{
ECFieldElement eCFieldElement11 = eCFieldElement2;
eCFieldElement12 = rawXCoord;
eCFieldElement13 = rawYCoord;
}
else
{
ECFieldElement eCFieldElement11 = eCFieldElement2.Square();
eCFieldElement12 = eCFieldElement11.Multiply(rawXCoord);
ECFieldElement eCFieldElement14 = eCFieldElement11.Multiply(eCFieldElement2);
eCFieldElement13 = eCFieldElement14.Multiply(rawYCoord);
}
ECFieldElement eCFieldElement15 = eCFieldElement12.Subtract(b4);
ECFieldElement eCFieldElement16 = eCFieldElement13.Subtract(b5);
if (eCFieldElement15.IsZero)
{
if (eCFieldElement16.IsZero)
{
return Twice();
}
return curve.Infinity;
}
ECFieldElement eCFieldElement17 = eCFieldElement15.Square();
ECFieldElement eCFieldElement18 = eCFieldElement17.Multiply(eCFieldElement15);
ECFieldElement eCFieldElement19 = eCFieldElement17.Multiply(eCFieldElement12);
eCFieldElement7 = eCFieldElement16.Square().Add(eCFieldElement18).Subtract(Two(eCFieldElement19));
y = eCFieldElement19.Subtract(eCFieldElement7).MultiplyMinusProduct(eCFieldElement16, eCFieldElement18, eCFieldElement13);
eCFieldElement8 = eCFieldElement15;
if (!isOne)
{
eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement);
}
if (!isOne2)
{
eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement2);
}
if (eCFieldElement8 == eCFieldElement15)
{
zSquared = eCFieldElement17;
}
}
ECFieldElement[] zs;
if (coordinateSystem == 4)
{
ECFieldElement eCFieldElement20 = CalculateJacobianModifiedW(eCFieldElement8, zSquared);
zs = new ECFieldElement[2] { eCFieldElement8, eCFieldElement20 };
}
else
{
zs = new ECFieldElement[1] { eCFieldElement8 };
}
return new FpPoint(curve, eCFieldElement7, y, zs, base.IsCompressed);
}
default:
throw new InvalidOperationException("unsupported coordinate system");
}
}
public override ECPoint Twice()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return curve.Infinity;
}
int coordinateSystem = curve.CoordinateSystem;
ECFieldElement rawXCoord = base.RawXCoord;
switch (coordinateSystem)
{
case 0:
{
ECFieldElement x3 = rawXCoord.Square();
ECFieldElement eCFieldElement10 = Three(x3).Add(Curve.A).Divide(Two(rawYCoord));
ECFieldElement eCFieldElement11 = eCFieldElement10.Square().Subtract(Two(rawXCoord));
ECFieldElement y2 = eCFieldElement10.Multiply(rawXCoord.Subtract(eCFieldElement11)).Subtract(rawYCoord);
return new FpPoint(Curve, eCFieldElement11, y2, base.IsCompressed);
}
case 1:
{
ECFieldElement eCFieldElement12 = base.RawZCoords[0];
bool isOne2 = eCFieldElement12.IsOne;
ECFieldElement eCFieldElement13 = curve.A;
if (!eCFieldElement13.IsZero && !isOne2)
{
eCFieldElement13 = eCFieldElement13.Multiply(eCFieldElement12.Square());
}
eCFieldElement13 = eCFieldElement13.Add(Three(rawXCoord.Square()));
ECFieldElement eCFieldElement14 = (isOne2 ? rawYCoord : rawYCoord.Multiply(eCFieldElement12));
ECFieldElement eCFieldElement15 = (isOne2 ? rawYCoord.Square() : eCFieldElement14.Multiply(rawYCoord));
ECFieldElement x4 = rawXCoord.Multiply(eCFieldElement15);
ECFieldElement eCFieldElement16 = Four(x4);
ECFieldElement eCFieldElement17 = eCFieldElement13.Square().Subtract(Two(eCFieldElement16));
ECFieldElement eCFieldElement18 = Two(eCFieldElement14);
ECFieldElement x5 = eCFieldElement17.Multiply(eCFieldElement18);
ECFieldElement eCFieldElement19 = Two(eCFieldElement15);
ECFieldElement y3 = eCFieldElement16.Subtract(eCFieldElement17).Multiply(eCFieldElement13).Subtract(Two(eCFieldElement19.Square()));
ECFieldElement x6 = (isOne2 ? Two(eCFieldElement19) : eCFieldElement18.Square());
ECFieldElement eCFieldElement20 = Two(x6).Multiply(eCFieldElement14);
return new FpPoint(curve, x5, y3, new ECFieldElement[1] { eCFieldElement20 }, base.IsCompressed);
}
case 2:
{
ECFieldElement eCFieldElement = base.RawZCoords[0];
bool isOne = eCFieldElement.IsOne;
ECFieldElement eCFieldElement2 = rawYCoord.Square();
ECFieldElement x = eCFieldElement2.Square();
ECFieldElement a = curve.A;
ECFieldElement eCFieldElement3 = a.Negate();
ECFieldElement eCFieldElement4;
ECFieldElement eCFieldElement5;
if (eCFieldElement3.ToBigInteger().Equals(BigInteger.ValueOf(3L)))
{
ECFieldElement b = (isOne ? eCFieldElement : eCFieldElement.Square());
eCFieldElement4 = Three(rawXCoord.Add(b).Multiply(rawXCoord.Subtract(b)));
eCFieldElement5 = Four(eCFieldElement2.Multiply(rawXCoord));
}
else
{
ECFieldElement x2 = rawXCoord.Square();
eCFieldElement4 = Three(x2);
if (isOne)
{
eCFieldElement4 = eCFieldElement4.Add(a);
}
else if (!a.IsZero)
{
ECFieldElement eCFieldElement6 = (isOne ? eCFieldElement : eCFieldElement.Square());
ECFieldElement eCFieldElement7 = eCFieldElement6.Square();
eCFieldElement4 = ((eCFieldElement3.BitLength >= a.BitLength) ? eCFieldElement4.Add(eCFieldElement7.Multiply(a)) : eCFieldElement4.Subtract(eCFieldElement7.Multiply(eCFieldElement3)));
}
eCFieldElement5 = Four(rawXCoord.Multiply(eCFieldElement2));
}
ECFieldElement eCFieldElement8 = eCFieldElement4.Square().Subtract(Two(eCFieldElement5));
ECFieldElement y = eCFieldElement5.Subtract(eCFieldElement8).Multiply(eCFieldElement4).Subtract(Eight(x));
ECFieldElement eCFieldElement9 = Two(rawYCoord);
if (!isOne)
{
eCFieldElement9 = eCFieldElement9.Multiply(eCFieldElement);
}
return new FpPoint(curve, eCFieldElement8, y, new ECFieldElement[1] { eCFieldElement9 }, base.IsCompressed);
}
case 4:
return TwiceJacobianModified(calculateW: true);
default:
throw new InvalidOperationException("unsupported coordinate system");
}
}
public override ECPoint TwicePlus(ECPoint b)
{
if (this == b)
{
return ThreeTimes();
}
if (base.IsInfinity)
{
return b;
}
if (b.IsInfinity)
{
return Twice();
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return b;
}
ECCurve curve = Curve;
switch (curve.CoordinateSystem)
{
case 0:
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawXCoord2 = b.RawXCoord;
ECFieldElement rawYCoord2 = b.RawYCoord;
ECFieldElement eCFieldElement = rawXCoord2.Subtract(rawXCoord);
ECFieldElement eCFieldElement2 = rawYCoord2.Subtract(rawYCoord);
if (eCFieldElement.IsZero)
{
if (eCFieldElement2.IsZero)
{
return ThreeTimes();
}
return this;
}
ECFieldElement eCFieldElement3 = eCFieldElement.Square();
ECFieldElement b2 = eCFieldElement2.Square();
ECFieldElement eCFieldElement4 = eCFieldElement3.Multiply(Two(rawXCoord).Add(rawXCoord2)).Subtract(b2);
if (eCFieldElement4.IsZero)
{
return Curve.Infinity;
}
ECFieldElement eCFieldElement5 = eCFieldElement4.Multiply(eCFieldElement);
ECFieldElement b3 = eCFieldElement5.Invert();
ECFieldElement eCFieldElement6 = eCFieldElement4.Multiply(b3).Multiply(eCFieldElement2);
ECFieldElement eCFieldElement7 = Two(rawYCoord).Multiply(eCFieldElement3).Multiply(eCFieldElement).Multiply(b3)
.Subtract(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement7.Subtract(eCFieldElement6).Multiply(eCFieldElement6.Add(eCFieldElement7)).Add(rawXCoord2);
ECFieldElement y = rawXCoord.Subtract(eCFieldElement8).Multiply(eCFieldElement7).Subtract(rawYCoord);
return new FpPoint(Curve, eCFieldElement8, y, base.IsCompressed);
}
case 4:
return TwiceJacobianModified(calculateW: false).Add(b);
default:
return Twice().Add(b);
}
}
public override ECPoint ThreeTimes()
{
if (base.IsInfinity)
{
return this;
}
ECFieldElement rawYCoord = base.RawYCoord;
if (rawYCoord.IsZero)
{
return this;
}
ECCurve curve = Curve;
switch (curve.CoordinateSystem)
{
case 0:
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement eCFieldElement = Two(rawYCoord);
ECFieldElement eCFieldElement2 = eCFieldElement.Square();
ECFieldElement eCFieldElement3 = Three(rawXCoord.Square()).Add(Curve.A);
ECFieldElement b = eCFieldElement3.Square();
ECFieldElement eCFieldElement4 = Three(rawXCoord).Multiply(eCFieldElement2).Subtract(b);
if (eCFieldElement4.IsZero)
{
return Curve.Infinity;
}
ECFieldElement eCFieldElement5 = eCFieldElement4.Multiply(eCFieldElement);
ECFieldElement b2 = eCFieldElement5.Invert();
ECFieldElement eCFieldElement6 = eCFieldElement4.Multiply(b2).Multiply(eCFieldElement3);
ECFieldElement eCFieldElement7 = eCFieldElement2.Square().Multiply(b2).Subtract(eCFieldElement6);
ECFieldElement eCFieldElement8 = eCFieldElement7.Subtract(eCFieldElement6).Multiply(eCFieldElement6.Add(eCFieldElement7)).Add(rawXCoord);
ECFieldElement y = rawXCoord.Subtract(eCFieldElement8).Multiply(eCFieldElement7).Subtract(rawYCoord);
return new FpPoint(Curve, eCFieldElement8, y, base.IsCompressed);
}
case 4:
return TwiceJacobianModified(calculateW: false).Add(this);
default:
return Twice().Add(this);
}
}
public override ECPoint TimesPow2(int e)
{
if (e < 0)
{
throw new ArgumentException("cannot be negative", "e");
}
if (e == 0 || base.IsInfinity)
{
return this;
}
if (e == 1)
{
return Twice();
}
ECCurve curve = Curve;
ECFieldElement eCFieldElement = base.RawYCoord;
if (eCFieldElement.IsZero)
{
return curve.Infinity;
}
int coordinateSystem = curve.CoordinateSystem;
ECFieldElement eCFieldElement2 = curve.A;
ECFieldElement eCFieldElement3 = base.RawXCoord;
ECFieldElement eCFieldElement4 = ((base.RawZCoords.Length < 1) ? curve.FromBigInteger(BigInteger.One) : base.RawZCoords[0]);
if (!eCFieldElement4.IsOne)
{
switch (coordinateSystem)
{
case 1:
{
ECFieldElement eCFieldElement5 = eCFieldElement4.Square();
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement4);
eCFieldElement = eCFieldElement.Multiply(eCFieldElement5);
eCFieldElement2 = CalculateJacobianModifiedW(eCFieldElement4, eCFieldElement5);
break;
}
case 2:
eCFieldElement2 = CalculateJacobianModifiedW(eCFieldElement4, null);
break;
case 4:
eCFieldElement2 = GetJacobianModifiedW();
break;
}
}
for (int i = 0; i < e; i++)
{
if (eCFieldElement.IsZero)
{
return curve.Infinity;
}
ECFieldElement x = eCFieldElement3.Square();
ECFieldElement eCFieldElement6 = Three(x);
ECFieldElement eCFieldElement7 = Two(eCFieldElement);
ECFieldElement eCFieldElement8 = eCFieldElement7.Multiply(eCFieldElement);
ECFieldElement eCFieldElement9 = Two(eCFieldElement3.Multiply(eCFieldElement8));
ECFieldElement x2 = eCFieldElement8.Square();
ECFieldElement eCFieldElement10 = Two(x2);
if (!eCFieldElement2.IsZero)
{
eCFieldElement6 = eCFieldElement6.Add(eCFieldElement2);
eCFieldElement2 = Two(eCFieldElement10.Multiply(eCFieldElement2));
}
eCFieldElement3 = eCFieldElement6.Square().Subtract(Two(eCFieldElement9));
eCFieldElement = eCFieldElement6.Multiply(eCFieldElement9.Subtract(eCFieldElement3)).Subtract(eCFieldElement10);
eCFieldElement4 = (eCFieldElement4.IsOne ? eCFieldElement7 : eCFieldElement7.Multiply(eCFieldElement4));
}
switch (coordinateSystem)
{
case 0:
{
ECFieldElement eCFieldElement11 = eCFieldElement4.Invert();
ECFieldElement eCFieldElement12 = eCFieldElement11.Square();
ECFieldElement b = eCFieldElement12.Multiply(eCFieldElement11);
return new FpPoint(curve, eCFieldElement3.Multiply(eCFieldElement12), eCFieldElement.Multiply(b), base.IsCompressed);
}
case 1:
eCFieldElement3 = eCFieldElement3.Multiply(eCFieldElement4);
eCFieldElement4 = eCFieldElement4.Multiply(eCFieldElement4.Square());
return new FpPoint(curve, eCFieldElement3, eCFieldElement, new ECFieldElement[1] { eCFieldElement4 }, base.IsCompressed);
case 2:
return new FpPoint(curve, eCFieldElement3, eCFieldElement, new ECFieldElement[1] { eCFieldElement4 }, base.IsCompressed);
case 4:
return new FpPoint(curve, eCFieldElement3, eCFieldElement, new ECFieldElement[2] { eCFieldElement4, eCFieldElement2 }, base.IsCompressed);
default:
throw new InvalidOperationException("unsupported coordinate system");
}
}
protected virtual ECFieldElement Two(ECFieldElement x)
{
return x.Add(x);
}
protected virtual ECFieldElement Three(ECFieldElement x)
{
return Two(x).Add(x);
}
protected virtual ECFieldElement Four(ECFieldElement x)
{
return Two(Two(x));
}
protected virtual ECFieldElement Eight(ECFieldElement x)
{
return Four(Two(x));
}
protected virtual ECFieldElement DoubleProductFromSquares(ECFieldElement a, ECFieldElement b, ECFieldElement aSquared, ECFieldElement bSquared)
{
return a.Add(b).Square().Subtract(aSquared)
.Subtract(bSquared);
}
public override ECPoint Negate()
{
if (base.IsInfinity)
{
return this;
}
ECCurve curve = Curve;
if (curve.CoordinateSystem != 0)
{
return new FpPoint(curve, base.RawXCoord, base.RawYCoord.Negate(), base.RawZCoords, base.IsCompressed);
}
return new FpPoint(curve, base.RawXCoord, base.RawYCoord.Negate(), base.IsCompressed);
}
protected virtual ECFieldElement CalculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
{
ECFieldElement a = Curve.A;
if (a.IsZero || Z.IsOne)
{
return a;
}
if (ZSquared == null)
{
ZSquared = Z.Square();
}
ECFieldElement eCFieldElement = ZSquared.Square();
ECFieldElement eCFieldElement2 = a.Negate();
if (eCFieldElement2.BitLength < a.BitLength)
{
return eCFieldElement.Multiply(eCFieldElement2).Negate();
}
return eCFieldElement.Multiply(a);
}
protected virtual ECFieldElement GetJacobianModifiedW()
{
ECFieldElement[] rawZCoords = base.RawZCoords;
ECFieldElement eCFieldElement = rawZCoords[1];
if (eCFieldElement == null)
{
eCFieldElement = (rawZCoords[1] = CalculateJacobianModifiedW(rawZCoords[0], null));
}
return eCFieldElement;
}
protected virtual FpPoint TwiceJacobianModified(bool calculateW)
{
ECFieldElement rawXCoord = base.RawXCoord;
ECFieldElement rawYCoord = base.RawYCoord;
ECFieldElement eCFieldElement = base.RawZCoords[0];
ECFieldElement jacobianModifiedW = GetJacobianModifiedW();
ECFieldElement x = rawXCoord.Square();
ECFieldElement eCFieldElement2 = Three(x).Add(jacobianModifiedW);
ECFieldElement eCFieldElement3 = Two(rawYCoord);
ECFieldElement eCFieldElement4 = eCFieldElement3.Multiply(rawYCoord);
ECFieldElement eCFieldElement5 = Two(rawXCoord.Multiply(eCFieldElement4));
ECFieldElement eCFieldElement6 = eCFieldElement2.Square().Subtract(Two(eCFieldElement5));
ECFieldElement x2 = eCFieldElement4.Square();
ECFieldElement eCFieldElement7 = Two(x2);
ECFieldElement y = eCFieldElement2.Multiply(eCFieldElement5.Subtract(eCFieldElement6)).Subtract(eCFieldElement7);
ECFieldElement eCFieldElement8 = (calculateW ? Two(eCFieldElement7.Multiply(jacobianModifiedW)) : null);
ECFieldElement eCFieldElement9 = (eCFieldElement.IsOne ? eCFieldElement3 : eCFieldElement3.Multiply(eCFieldElement));
return new FpPoint(Curve, eCFieldElement6, y, new ECFieldElement[2] { eCFieldElement9, eCFieldElement8 }, base.IsCompressed);
}
}