public override ECPoint ScaleX(ECFieldElement scale)
        {
            if (this.IsInfinity)
                return this;

            switch (CurveCoordinateSystem)
            {
            case ECCurve.COORD_LAMBDA_AFFINE:
            {
                // Y is actually Lambda (X + Y/X) here
                ECFieldElement X = RawXCoord, L = RawYCoord;

                ECFieldElement X2 = X.Multiply(scale);
                ECFieldElement L2 = L.Add(X).Divide(scale).Add(X2);

                return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed);
            }
            case ECCurve.COORD_LAMBDA_PROJECTIVE:
            {
                // Y is actually Lambda (X + Y/X) here
                ECFieldElement X = RawXCoord, L = RawYCoord, Z = RawZCoords[0];

                // We scale the Z coordinate also, to avoid an inversion
                ECFieldElement X2 = X.Multiply(scale.Square());
                ECFieldElement L2 = L.Add(X).Add(X2);
                ECFieldElement Z2 = Z.Multiply(scale);

                return Curve.CreateRawPoint(X, L2, new ECFieldElement[] { Z2 }, IsCompressed);
            }
            default:
            {
                return base.ScaleX(scale);
            }
            }
        }
        protected virtual ECFieldElement CalculateJacobianModifiedW(ECFieldElement Z, ECFieldElement ZSquared)
        {
            ECFieldElement a4 = this.Curve.A;
            if (a4.IsZero || Z.IsOne)
                return a4;

            if (ZSquared == null)
            {
                ZSquared = Z.Square();
            }

            ECFieldElement W = ZSquared.Square();
            ECFieldElement a4Neg = a4.Negate();
            if (a4Neg.BitLength < a4.BitLength)
            {
                W = W.Multiply(a4Neg).Negate();
            }
            else
            {
                W = W.Multiply(a4);
            }
            return W;
        }
 internal virtual ECPoint Normalize(ECFieldElement zInv)
 {
     switch (this.CurveCoordinateSystem)
     {
         case ECCurve.COORD_HOMOGENEOUS:
         case ECCurve.COORD_LAMBDA_PROJECTIVE:
         {
             return CreateScaledPoint(zInv, zInv);
         }
         case ECCurve.COORD_JACOBIAN:
         case ECCurve.COORD_JACOBIAN_CHUDNOVSKY:
         case ECCurve.COORD_JACOBIAN_MODIFIED:
         {
             ECFieldElement zInv2 = zInv.Square(), zInv3 = zInv2.Multiply(zInv);
             return CreateScaledPoint(zInv2, zInv3);
         }
         default:
         {
             throw new InvalidOperationException("not a projective coordinate system");
         }
     }
 }
 private ECFieldElement CheckSqrt(ECFieldElement z)
 {
     return z.Square().Equals(this) ? z : null;
 }