public override ECPoint Twice()
{
if (this.IsInfinity)
{
return this;
}
ECCurve curve = this.Curve;
ECFieldElement X1 = this.RawXCoord;
if (X1.IsZero)
{
// A point with X == 0 is it's own Additive inverse
return curve.Infinity;
}
ECFieldElement L1 = this.RawYCoord, Z1 = this.RawZCoords[0];
bool Z1IsOne = Z1.IsOne;
ECFieldElement L1Z1 = Z1IsOne ? L1 : L1.Multiply(Z1);
ECFieldElement Z1Sq = Z1IsOne ? Z1 : Z1.Square();
ECFieldElement T = L1.Square().Add(L1Z1).Add(Z1Sq);
if (T.IsZero)
{
return new SecT163R2Point(curve, T, curve.B.Sqrt(), IsCompressed);
}
ECFieldElement X3 = T.Square();
ECFieldElement Z3 = Z1IsOne ? T : T.Multiply(Z1Sq);
ECFieldElement X1Z1 = Z1IsOne ? X1 : X1.Multiply(Z1);
ECFieldElement L3 = X1Z1.SquarePlusProduct(T, L1Z1).Add(X3).Add(Z3);
return new SecT163R2Point(curve, X3, L3, new ECFieldElement[] { Z3 }, IsCompressed);
}