Exemple #1
0
 protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)
 {
     // TODO Should curve == null be allowed?
     this.curve = curve;
     this.x = x;
     this.y = y;
 }
Exemple #2
0
 internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
 {
     this.m_curve = curve;
     this.m_x = x;
     this.m_y = y;
     this.m_zs = zs;
     this.m_withCompression = withCompression;
 }
Exemple #3
0
 public virtual bool Equals(ECFieldElement other)
 {
     if (this == other)
         return true;
     if (null == other)
         return false;
     return ToBigInteger().Equals(other.ToBigInteger());
 }
        protected internal ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
        {
            if (curve == null)
                throw new ArgumentNullException("curve");

            _curve = curve;
            _x = x;
            _y = y;
            _withCompression = withCompression;
        }
        public static int GetByteLength(
            ECFieldElement fe)
        {
            if (fe is FpFieldElement)
            {
                FpFieldElement ep = (FpFieldElement) fe;

                return (ep.Q.BitLength + 7) / 8;
            }

            F2mFieldElement em = (F2mFieldElement)fe;

            return (em.M + 7) / 8;
        }
Exemple #6
0
 public override ECFieldElement MultiplyMinusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
 {
     return MultiplyPlusProduct(b, x, y);
 }
Exemple #7
0
 protected ECPoint(ECCurve curve, ECFieldElement	x, ECFieldElement y, bool withCompression)
     : this(curve, x, y, GetInitialZCoords(curve), withCompression)
 {
 }
Exemple #8
0
 /**
  * Create a point that encodes with or without point compresion.
  *
  * @param curve the curve to use
  * @param x affine x co-ordinate
  * @param y affine y co-ordinate
  * @param withCompression if true encode with point compression
  */
 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");
 }
Exemple #9
0
 protected internal ECPointBase(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
     : base(curve, x, y, zs, withCompression)
 {
 }
Exemple #10
0
 protected virtual ECPoint CreateScaledPoint(ECFieldElement sx, ECFieldElement sy)
 {
     return Curve.CreateRawPoint(RawXCoord.Multiply(sx), RawYCoord.Multiply(sy), IsCompressed);
 }
Exemple #11
0
 public virtual ECFieldElement[] GetZCoords()
 {
     int zsLen = m_zs.Length;
     if (zsLen == 0)
     {
         return m_zs;
     }
     ECFieldElement[] copy = new ECFieldElement[zsLen];
     Array.Copy(m_zs, 0, copy, 0, zsLen);
     return copy;
 }
Exemple #12
0
        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);
            }
            }
        }
Exemple #13
0
        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;
        }
Exemple #14
0
        public override ECPoint TwicePlus(ECPoint b)
        {
            if (base.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(this.Twice());
            }
            ECCurve        curve     = this.Curve;
            ECFieldElement rawXCoord = base.RawXCoord;

            if (rawXCoord.IsZero)
            {
                return(b);
            }
            int coordinateSystem = curve.CoordinateSystem;
            int num = coordinateSystem;

            if (num != 6)
            {
                return(this.Twice().Add(b));
            }
            ECFieldElement rawXCoord2     = b.RawXCoord;
            ECFieldElement eCFieldElement = b.RawZCoords[0];

            if (rawXCoord2.IsZero || !eCFieldElement.IsOne)
            {
                return(this.Twice().Add(b));
            }
            ECFieldElement rawYCoord       = base.RawYCoord;
            ECFieldElement eCFieldElement2 = base.RawZCoords[0];
            ECFieldElement rawYCoord2      = b.RawYCoord;
            ECFieldElement x  = rawXCoord.Square();
            ECFieldElement b2 = rawYCoord.Square();
            ECFieldElement eCFieldElement3 = eCFieldElement2.Square();
            ECFieldElement b3 = rawYCoord.Multiply(eCFieldElement2);
            ECFieldElement b4 = curve.A.Multiply(eCFieldElement3).Add(b2).Add(b3);
            ECFieldElement eCFieldElement4 = rawYCoord2.AddOne();
            ECFieldElement eCFieldElement5 = curve.A.Add(eCFieldElement4).Multiply(eCFieldElement3).Add(b2).MultiplyPlusProduct(b4, x, eCFieldElement3);
            ECFieldElement eCFieldElement6 = rawXCoord2.Multiply(eCFieldElement3);
            ECFieldElement eCFieldElement7 = eCFieldElement6.Add(b4).Square();

            if (eCFieldElement7.IsZero)
            {
                if (eCFieldElement5.IsZero)
                {
                    return(b.Twice());
                }
                return(curve.Infinity);
            }
            else
            {
                if (eCFieldElement5.IsZero)
                {
                    return(new F2mPoint(curve, eCFieldElement5, curve.B.Sqrt(), base.IsCompressed));
                }
                ECFieldElement x2 = eCFieldElement5.Square().Multiply(eCFieldElement6);
                ECFieldElement eCFieldElement8 = eCFieldElement5.Multiply(eCFieldElement7).Multiply(eCFieldElement3);
                ECFieldElement y = eCFieldElement5.Add(eCFieldElement7).Square().MultiplyPlusProduct(b4, eCFieldElement4, eCFieldElement8);
                return(new F2mPoint(curve, x2, y, new ECFieldElement[]
                {
                    eCFieldElement8
                }, base.IsCompressed));
            }
        }
Exemple #15
0
 public F2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y) : this(curve, x, y, false)
 {
 }
Exemple #16
0
        public override ECPoint Add(ECPoint b)
        {
            if (base.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(this);
            }
            ECCurve        curve            = this.Curve;
            int            coordinateSystem = curve.CoordinateSystem;
            ECFieldElement rawXCoord        = base.RawXCoord;
            ECFieldElement rawXCoord2       = b.RawXCoord;
            int            num = coordinateSystem;

            switch (num)
            {
            case 0:
            {
                ECFieldElement rawYCoord       = base.RawYCoord;
                ECFieldElement rawYCoord2      = b.RawYCoord;
                ECFieldElement eCFieldElement  = rawXCoord.Add(rawXCoord2);
                ECFieldElement eCFieldElement2 = rawYCoord.Add(rawYCoord2);
                if (!eCFieldElement.IsZero)
                {
                    ECFieldElement eCFieldElement3 = eCFieldElement2.Divide(eCFieldElement);
                    ECFieldElement eCFieldElement4 = eCFieldElement3.Square().Add(eCFieldElement3).Add(eCFieldElement).Add(curve.A);
                    ECFieldElement y = eCFieldElement3.Multiply(rawXCoord.Add(eCFieldElement4)).Add(eCFieldElement4).Add(rawYCoord);
                    return(new F2mPoint(curve, eCFieldElement4, y, base.IsCompressed));
                }
                if (eCFieldElement2.IsZero)
                {
                    return(this.Twice());
                }
                return(curve.Infinity);
            }

            case 1:
            {
                ECFieldElement rawYCoord3      = base.RawYCoord;
                ECFieldElement eCFieldElement5 = base.RawZCoords[0];
                ECFieldElement rawYCoord4      = b.RawYCoord;
                ECFieldElement eCFieldElement6 = b.RawZCoords[0];
                bool           isOne           = eCFieldElement5.IsOne;
                ECFieldElement eCFieldElement7 = rawYCoord4;
                ECFieldElement eCFieldElement8 = rawXCoord2;
                if (!isOne)
                {
                    eCFieldElement7 = eCFieldElement7.Multiply(eCFieldElement5);
                    eCFieldElement8 = eCFieldElement8.Multiply(eCFieldElement5);
                }
                bool           isOne2           = eCFieldElement6.IsOne;
                ECFieldElement eCFieldElement9  = rawYCoord3;
                ECFieldElement eCFieldElement10 = rawXCoord;
                if (!isOne2)
                {
                    eCFieldElement9  = eCFieldElement9.Multiply(eCFieldElement6);
                    eCFieldElement10 = eCFieldElement10.Multiply(eCFieldElement6);
                }
                ECFieldElement eCFieldElement11 = eCFieldElement7.Add(eCFieldElement9);
                ECFieldElement eCFieldElement12 = eCFieldElement8.Add(eCFieldElement10);
                if (!eCFieldElement12.IsZero)
                {
                    ECFieldElement eCFieldElement13 = eCFieldElement12.Square();
                    ECFieldElement eCFieldElement14 = eCFieldElement13.Multiply(eCFieldElement12);
                    ECFieldElement b2 = isOne ? eCFieldElement6 : (isOne2 ? eCFieldElement5 : eCFieldElement5.Multiply(eCFieldElement6));
                    ECFieldElement eCFieldElement15 = eCFieldElement11.Add(eCFieldElement12);
                    ECFieldElement eCFieldElement16 = eCFieldElement15.MultiplyPlusProduct(eCFieldElement11, eCFieldElement13, curve.A).Multiply(b2).Add(eCFieldElement14);
                    ECFieldElement x  = eCFieldElement12.Multiply(eCFieldElement16);
                    ECFieldElement b3 = isOne2 ? eCFieldElement13 : eCFieldElement13.Multiply(eCFieldElement6);
                    ECFieldElement y2 = eCFieldElement11.MultiplyPlusProduct(rawXCoord, eCFieldElement12, rawYCoord3).MultiplyPlusProduct(b3, eCFieldElement15, eCFieldElement16);
                    ECFieldElement eCFieldElement17 = eCFieldElement14.Multiply(b2);
                    return(new F2mPoint(curve, x, y2, new ECFieldElement[]
                        {
                            eCFieldElement17
                        }, base.IsCompressed));
                }
                if (eCFieldElement11.IsZero)
                {
                    return(this.Twice());
                }
                return(curve.Infinity);
            }

            default:
                if (num != 6)
                {
                    throw new InvalidOperationException("unsupported coordinate system");
                }
                if (rawXCoord.IsZero)
                {
                    if (rawXCoord2.IsZero)
                    {
                        return(curve.Infinity);
                    }
                    return(b.Add(this));
                }
                else
                {
                    ECFieldElement rawYCoord5       = base.RawYCoord;
                    ECFieldElement eCFieldElement18 = base.RawZCoords[0];
                    ECFieldElement rawYCoord6       = b.RawYCoord;
                    ECFieldElement eCFieldElement19 = b.RawZCoords[0];
                    bool           isOne3           = eCFieldElement18.IsOne;
                    ECFieldElement eCFieldElement20 = rawXCoord2;
                    ECFieldElement eCFieldElement21 = rawYCoord6;
                    if (!isOne3)
                    {
                        eCFieldElement20 = eCFieldElement20.Multiply(eCFieldElement18);
                        eCFieldElement21 = eCFieldElement21.Multiply(eCFieldElement18);
                    }
                    bool           isOne4           = eCFieldElement19.IsOne;
                    ECFieldElement eCFieldElement22 = rawXCoord;
                    ECFieldElement eCFieldElement23 = rawYCoord5;
                    if (!isOne4)
                    {
                        eCFieldElement22 = eCFieldElement22.Multiply(eCFieldElement19);
                        eCFieldElement23 = eCFieldElement23.Multiply(eCFieldElement19);
                    }
                    ECFieldElement eCFieldElement24 = eCFieldElement23.Add(eCFieldElement21);
                    ECFieldElement eCFieldElement25 = eCFieldElement22.Add(eCFieldElement20);
                    if (!eCFieldElement25.IsZero)
                    {
                        ECFieldElement eCFieldElement27;
                        ECFieldElement y3;
                        ECFieldElement eCFieldElement29;
                        if (rawXCoord2.IsZero)
                        {
                            ECPoint eCPoint = this.Normalize();
                            rawXCoord = eCPoint.RawXCoord;
                            ECFieldElement yCoord           = eCPoint.YCoord;
                            ECFieldElement b4               = rawYCoord6;
                            ECFieldElement eCFieldElement26 = yCoord.Add(b4).Divide(rawXCoord);
                            eCFieldElement27 = eCFieldElement26.Square().Add(eCFieldElement26).Add(rawXCoord).Add(curve.A);
                            if (eCFieldElement27.IsZero)
                            {
                                return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed));
                            }
                            ECFieldElement eCFieldElement28 = eCFieldElement26.Multiply(rawXCoord.Add(eCFieldElement27)).Add(eCFieldElement27).Add(yCoord);
                            y3 = eCFieldElement28.Divide(eCFieldElement27).Add(eCFieldElement27);
                            eCFieldElement29 = curve.FromBigInteger(BigInteger.One);
                        }
                        else
                        {
                            eCFieldElement25 = eCFieldElement25.Square();
                            ECFieldElement eCFieldElement30 = eCFieldElement24.Multiply(eCFieldElement22);
                            ECFieldElement eCFieldElement31 = eCFieldElement24.Multiply(eCFieldElement20);
                            eCFieldElement27 = eCFieldElement30.Multiply(eCFieldElement31);
                            if (eCFieldElement27.IsZero)
                            {
                                return(new F2mPoint(curve, eCFieldElement27, curve.B.Sqrt(), base.IsCompressed));
                            }
                            ECFieldElement eCFieldElement32 = eCFieldElement24.Multiply(eCFieldElement25);
                            if (!isOne4)
                            {
                                eCFieldElement32 = eCFieldElement32.Multiply(eCFieldElement19);
                            }
                            y3 = eCFieldElement31.Add(eCFieldElement25).SquarePlusProduct(eCFieldElement32, rawYCoord5.Add(eCFieldElement18));
                            eCFieldElement29 = eCFieldElement32;
                            if (!isOne3)
                            {
                                eCFieldElement29 = eCFieldElement29.Multiply(eCFieldElement18);
                            }
                        }
                        return(new F2mPoint(curve, eCFieldElement27, y3, new ECFieldElement[]
                        {
                            eCFieldElement29
                        }, base.IsCompressed));
                    }
                    if (eCFieldElement24.IsZero)
                    {
                        return(this.Twice());
                    }
                    return(curve.Infinity);
                }
                break;
            }
        }
Exemple #17
0
 internal F2mPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression) : base(curve, x, y, zs, withCompression)
 {
 }
Exemple #18
0
 protected virtual ECFieldElement DoubleProductFromSquares(ECFieldElement a, ECFieldElement b,
     ECFieldElement aSquared, ECFieldElement bSquared)
 {
     /*
      * NOTE: If squaring in the field is faster than multiplication, then this is a quicker
      * way to calculate 2.A.B, if A^2 and B^2 are already known.
      */
     return a.Add(b).Square().Subtract(aSquared).Subtract(bSquared);
 }
Exemple #19
0
        public override ECFieldElement MultiplyPlusProduct(ECFieldElement b, ECFieldElement x, ECFieldElement y)
        {
            LongArray ax = this.x, bx = ((F2mFieldElement)b).x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x;

            LongArray ab = ax.Multiply(bx, m, ks);
            LongArray xy = xx.Multiply(yx, m, ks);

            if (ab == ax || ab == bx)
            {
                ab = (LongArray)ab.Copy();
            }

            ab.AddShiftedByWords(xy, 0);
            ab.Reduce(m, ks);

            return new F2mFieldElement(m, ks, ab);
        }
Exemple #20
0
        /**
         * @param curve base curve
         * @param x x point
         * @param y y point
         * @param withCompression true if encode with point compression.
         */
        public F2mPoint(
            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");
            }

            if (x != null)
            {
                // Check if x and y are elements of the same field
                F2mFieldElement.CheckFieldElements(x, y);

                // Check if x and a are elements of the same field
                if (curve != null)
                {
                    F2mFieldElement.CheckFieldElements(x, curve.A);
                }
            }
        }
Exemple #21
0
 public override ECFieldElement Divide(
     ECFieldElement b)
 {
     // There may be more efficient implementations
     ECFieldElement bInv = b.Invert();
     return Multiply(bInv);
 }
Exemple #22
0
        public override ECPoint ScaleY(ECFieldElement scale)
        {
            if (this.IsInfinity)
                return this;

            switch (CurveCoordinateSystem)
            {
            case ECCurve.COORD_LAMBDA_AFFINE:
            case ECCurve.COORD_LAMBDA_PROJECTIVE:
            {
                ECFieldElement X = RawXCoord, L = RawYCoord;

                // Y is actually Lambda (X + Y/X) here
                ECFieldElement L2 = L.Add(X).Multiply(scale).Add(X);

                return Curve.CreateRawPoint(X, L2, RawZCoords, IsCompressed);
            }
            default:
            {
                return base.ScaleY(scale);
            }
            }
        }
Exemple #23
0
 public override ECFieldElement SquareMinusProduct(ECFieldElement x, ECFieldElement y)
 {
     return SquarePlusProduct(x, y);
 }
Exemple #24
0
 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");
         }
     }
 }
Exemple #25
0
        public override ECFieldElement SquarePlusProduct(ECFieldElement x, ECFieldElement y)
        {
            LongArray ax = this.x, xx = ((F2mFieldElement)x).x, yx = ((F2mFieldElement)y).x;

            LongArray aa = ax.Square(m, ks);
            LongArray xy = xx.Multiply(yx, m, ks);

            if (aa == ax)
            {
                aa = (LongArray)aa.Copy();
            }

            aa.AddShiftedByWords(xy, 0);
            aa.Reduce(m, ks);

            return new F2mFieldElement(m, ks, aa);
        }
Exemple #26
0
 public virtual ECPoint ScaleY(ECFieldElement scale)
 {
     return IsInfinity
         ? this
         : Curve.CreateRawPoint(RawXCoord, RawYCoord.Multiply(scale), RawZCoords, IsCompressed);
 }
Exemple #27
0
 protected virtual ECFieldElement Two(ECFieldElement x)
 {
     return x.Add(x);
 }
Exemple #28
0
 /**
  * Create a point which encodes with point compression.
  *
  * @param curve the curve to use
  * @param x affine x co-ordinate
  * @param y affine y co-ordinate
  */
 public FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y)
     : this(curve, x, y, false)
 {
 }
Exemple #29
0
 protected virtual ECFieldElement Three(ECFieldElement x)
 {
     return Two(x).Add(x);
 }
Exemple #30
0
 internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
     : base(curve, x, y, zs, withCompression)
 {
 }
Exemple #31
0
 protected virtual ECFieldElement Four(ECFieldElement x)
 {
     return Two(Two(x));
 }
Exemple #32
0
        // B.3 pg 62
        public override ECPoint Add(ECPoint b)
        {
            if (this.IsInfinity)
                return b;
            if (b.IsInfinity)
                return this;
            if (this == b)
                return Twice();

            ECCurve curve = this.Curve;
            int coord = curve.CoordinateSystem;

            ECFieldElement X1 = this.RawXCoord, Y1 = this.RawYCoord;
            ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord;

            switch (coord)
            {
                case ECCurve.COORD_AFFINE:
                {
                    ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1);

                    if (dx.IsZero)
                    {
                        if (dy.IsZero)
                        {
                            // this == b, i.e. this must be doubled
                            return Twice();
                        }

                        // this == -b, i.e. the result is the point at infinity
                        return Curve.Infinity;
                    }

                    ECFieldElement gamma = dy.Divide(dx);
                    ECFieldElement X3 = gamma.Square().Subtract(X1).Subtract(X2);
                    ECFieldElement Y3 = gamma.Multiply(X1.Subtract(X3)).Subtract(Y1);

                    return new FpPoint(Curve, X3, Y3, IsCompressed);
                }

                case ECCurve.COORD_HOMOGENEOUS:
                {
                    ECFieldElement Z1 = this.RawZCoords[0];
                    ECFieldElement Z2 = b.RawZCoords[0];

                    bool Z1IsOne = Z1.IsOne;
                    bool Z2IsOne = Z2.IsOne;

                    ECFieldElement u1 = Z1IsOne ? Y2 : Y2.Multiply(Z1);
                    ECFieldElement u2 = Z2IsOne ? Y1 : Y1.Multiply(Z2);
                    ECFieldElement u = u1.Subtract(u2);
                    ECFieldElement v1 = Z1IsOne ? X2 : X2.Multiply(Z1);
                    ECFieldElement v2 = Z2IsOne ? X1 : X1.Multiply(Z2);
                    ECFieldElement v = v1.Subtract(v2);

                    // Check if b == this or b == -this
                    if (v.IsZero)
                    {
                        if (u.IsZero)
                        {
                            // this == b, i.e. this must be doubled
                            return this.Twice();
                        }

                        // this == -b, i.e. the result is the point at infinity
                        return curve.Infinity;
                    }

                    // TODO Optimize for when w == 1
                    ECFieldElement w = Z1IsOne ? Z2 : Z2IsOne ? Z1 : Z1.Multiply(Z2);
                    ECFieldElement vSquared = v.Square();
                    ECFieldElement vCubed = vSquared.Multiply(v);
                    ECFieldElement vSquaredV2 = vSquared.Multiply(v2);
                    ECFieldElement A = u.Square().Multiply(w).Subtract(vCubed).Subtract(Two(vSquaredV2));

                    ECFieldElement X3 = v.Multiply(A);
                    ECFieldElement Y3 = vSquaredV2.Subtract(A).MultiplyMinusProduct(u, u2, vCubed);
                    ECFieldElement Z3 = vCubed.Multiply(w);

                    return new FpPoint(curve, X3, Y3, new ECFieldElement[] { Z3 }, IsCompressed);
                }

                case ECCurve.COORD_JACOBIAN:
                case ECCurve.COORD_JACOBIAN_MODIFIED:
                {
                    ECFieldElement Z1 = this.RawZCoords[0];
                    ECFieldElement Z2 = b.RawZCoords[0];

                    bool Z1IsOne = Z1.IsOne;

                    ECFieldElement X3, Y3, Z3, Z3Squared = null;

                    if (!Z1IsOne && Z1.Equals(Z2))
                    {
                        // TODO Make this available as public method coZAdd?

                        ECFieldElement dx = X1.Subtract(X2), dy = Y1.Subtract(Y2);
                        if (dx.IsZero)
                        {
                            if (dy.IsZero)
                            {
                                return Twice();
                            }
                            return curve.Infinity;
                        }

                        ECFieldElement C = dx.Square();
                        ECFieldElement W1 = X1.Multiply(C), W2 = X2.Multiply(C);
                        ECFieldElement A1 = W1.Subtract(W2).Multiply(Y1);

                        X3 = dy.Square().Subtract(W1).Subtract(W2);
                        Y3 = W1.Subtract(X3).Multiply(dy).Subtract(A1);
                        Z3 = dx;

                        if (Z1IsOne)
                        {
                            Z3Squared = C;
                        }
                        else
                        {
                            Z3 = Z3.Multiply(Z1);
                        }
                    }
                    else
                    {
                        ECFieldElement Z1Squared, U2, S2;
                        if (Z1IsOne)
                        {
                            Z1Squared = Z1; U2 = X2; S2 = Y2;
                        }
                        else
                        {
                            Z1Squared = Z1.Square();
                            U2 = Z1Squared.Multiply(X2);
                            ECFieldElement Z1Cubed = Z1Squared.Multiply(Z1);
                            S2 = Z1Cubed.Multiply(Y2);
                        }

                        bool Z2IsOne = Z2.IsOne;
                        ECFieldElement Z2Squared, U1, S1;
                        if (Z2IsOne)
                        {
                            Z2Squared = Z2; U1 = X1; S1 = Y1;
                        }
                        else
                        {
                            Z2Squared = Z2.Square();
                            U1 = Z2Squared.Multiply(X1);
                            ECFieldElement Z2Cubed = Z2Squared.Multiply(Z2);
                            S1 = Z2Cubed.Multiply(Y1);
                        }

                        ECFieldElement H = U1.Subtract(U2);
                        ECFieldElement R = S1.Subtract(S2);

                        // Check if b == this or b == -this
                        if (H.IsZero)
                        {
                            if (R.IsZero)
                            {
                                // this == b, i.e. this must be doubled
                                return this.Twice();
                            }

                            // this == -b, i.e. the result is the point at infinity
                            return curve.Infinity;
                        }

                        ECFieldElement HSquared = H.Square();
                        ECFieldElement G = HSquared.Multiply(H);
                        ECFieldElement V = HSquared.Multiply(U1);

                        X3 = R.Square().Add(G).Subtract(Two(V));
                        Y3 = V.Subtract(X3).MultiplyMinusProduct(R, G, S1);

                        Z3 = H;
                        if (!Z1IsOne)
                        {
                            Z3 = Z3.Multiply(Z1);
                        }
                        if (!Z2IsOne)
                        {
                            Z3 = Z3.Multiply(Z2);
                        }

                        // Alternative calculation of Z3 using fast square
                        //X3 = four(X3);
                        //Y3 = eight(Y3);
                        //Z3 = doubleProductFromSquares(Z1, Z2, Z1Squared, Z2Squared).Multiply(H);

                        if (Z3 == H)
                        {
                            Z3Squared = HSquared;
                        }
                    }

                    ECFieldElement[] zs;
                    if (coord == ECCurve.COORD_JACOBIAN_MODIFIED)
                    {
                        // TODO If the result will only be used in a subsequent addition, we don't need W3
                        ECFieldElement W3 = CalculateJacobianModifiedW(Z3, Z3Squared);

                        zs = new ECFieldElement[] { Z3, W3 };
                    }
                    else
                    {
                        zs = new ECFieldElement[] { Z3 };
                    }

                    return new FpPoint(curve, X3, Y3, zs, IsCompressed);
                }

                default:
                {
                    throw new InvalidOperationException("unsupported coordinate system");
                }
            }
        }
Exemple #33
0
 protected virtual ECFieldElement Eight(ECFieldElement x)
 {
     return Four(Two(x));
 }
 public ScaleYPointMap(ECFieldElement scale)
 {
     this.scale = scale;
 }
Exemple #35
0
        public override ECPoint Twice()
        {
            if (base.IsInfinity)
            {
                return(this);
            }
            ECCurve        curve     = this.Curve;
            ECFieldElement rawXCoord = base.RawXCoord;

            if (rawXCoord.IsZero)
            {
                return(curve.Infinity);
            }
            int coordinateSystem = curve.CoordinateSystem;
            int num = coordinateSystem;

            switch (num)
            {
            case 0:
            {
                ECFieldElement rawYCoord      = base.RawYCoord;
                ECFieldElement eCFieldElement = rawYCoord.Divide(rawXCoord).Add(rawXCoord);
                ECFieldElement x = eCFieldElement.Square().Add(eCFieldElement).Add(curve.A);
                ECFieldElement y = rawXCoord.SquarePlusProduct(x, eCFieldElement.AddOne());
                return(new F2mPoint(curve, x, y, base.IsCompressed));
            }

            case 1:
            {
                ECFieldElement rawYCoord2      = base.RawYCoord;
                ECFieldElement eCFieldElement2 = base.RawZCoords[0];
                bool           isOne           = eCFieldElement2.IsOne;
                ECFieldElement eCFieldElement3 = isOne ? rawXCoord : rawXCoord.Multiply(eCFieldElement2);
                ECFieldElement b = isOne ? rawYCoord2 : rawYCoord2.Multiply(eCFieldElement2);
                ECFieldElement eCFieldElement4 = rawXCoord.Square();
                ECFieldElement eCFieldElement5 = eCFieldElement4.Add(b);
                ECFieldElement eCFieldElement6 = eCFieldElement3;
                ECFieldElement eCFieldElement7 = eCFieldElement6.Square();
                ECFieldElement eCFieldElement8 = eCFieldElement5.Add(eCFieldElement6);
                ECFieldElement eCFieldElement9 = eCFieldElement8.MultiplyPlusProduct(eCFieldElement5, eCFieldElement7, curve.A);
                ECFieldElement x2 = eCFieldElement6.Multiply(eCFieldElement9);
                ECFieldElement y2 = eCFieldElement4.Square().MultiplyPlusProduct(eCFieldElement6, eCFieldElement9, eCFieldElement8);
                ECFieldElement eCFieldElement10 = eCFieldElement6.Multiply(eCFieldElement7);
                return(new F2mPoint(curve, x2, y2, new ECFieldElement[]
                    {
                        eCFieldElement10
                    }, base.IsCompressed));
            }

            default:
            {
                if (num != 6)
                {
                    throw new InvalidOperationException("unsupported coordinate system");
                }
                ECFieldElement rawYCoord3       = base.RawYCoord;
                ECFieldElement eCFieldElement11 = base.RawZCoords[0];
                bool           isOne2           = eCFieldElement11.IsOne;
                ECFieldElement eCFieldElement12 = isOne2 ? rawYCoord3 : rawYCoord3.Multiply(eCFieldElement11);
                ECFieldElement eCFieldElement13 = isOne2 ? eCFieldElement11 : eCFieldElement11.Square();
                ECFieldElement a = curve.A;
                ECFieldElement eCFieldElement14 = isOne2 ? a : a.Multiply(eCFieldElement13);
                ECFieldElement eCFieldElement15 = rawYCoord3.Square().Add(eCFieldElement12).Add(eCFieldElement14);
                if (eCFieldElement15.IsZero)
                {
                    return(new F2mPoint(curve, eCFieldElement15, curve.B.Sqrt(), base.IsCompressed));
                }
                ECFieldElement eCFieldElement16 = eCFieldElement15.Square();
                ECFieldElement eCFieldElement17 = isOne2 ? eCFieldElement15 : eCFieldElement15.Multiply(eCFieldElement13);
                ECFieldElement b2 = curve.B;
                ECFieldElement eCFieldElement19;
                if (b2.BitLength < curve.FieldSize >> 1)
                {
                    ECFieldElement eCFieldElement18 = rawYCoord3.Add(rawXCoord).Square();
                    ECFieldElement b3;
                    if (b2.IsOne)
                    {
                        b3 = eCFieldElement14.Add(eCFieldElement13).Square();
                    }
                    else
                    {
                        b3 = eCFieldElement14.SquarePlusProduct(b2, eCFieldElement13.Square());
                    }
                    eCFieldElement19 = eCFieldElement18.Add(eCFieldElement15).Add(eCFieldElement13).Multiply(eCFieldElement18).Add(b3).Add(eCFieldElement16);
                    if (a.IsZero)
                    {
                        eCFieldElement19 = eCFieldElement19.Add(eCFieldElement17);
                    }
                    else if (!a.IsOne)
                    {
                        eCFieldElement19 = eCFieldElement19.Add(a.AddOne().Multiply(eCFieldElement17));
                    }
                }
                else
                {
                    ECFieldElement eCFieldElement20 = isOne2 ? rawXCoord : rawXCoord.Multiply(eCFieldElement11);
                    eCFieldElement19 = eCFieldElement20.SquarePlusProduct(eCFieldElement15, eCFieldElement12).Add(eCFieldElement16).Add(eCFieldElement17);
                }
                return(new F2mPoint(curve, eCFieldElement16, eCFieldElement19, new ECFieldElement[]
                    {
                        eCFieldElement17
                    }, base.IsCompressed));
            }
            }
        }