コード例 #1
0
		public ECDomainParameters(
            ECCurve     curve,
            ECPoint     g,
            BigInteger  n)
			: this(curve, g, n, BigInteger.One)
        {
        }
コード例 #2
0
        public ECDomainParameters(
            ECCurve     curve,
            ECPoint     g,
            BigInteger  n,
            BigInteger  h)
			: this(curve, g, n, h, null)
		{
        }
コード例 #3
0
		protected internal ECPoint(
			ECCurve			curve,
			ECFieldElement	x,
			ECFieldElement	y,
			bool			withCompression)
		{
			if (curve == null)
				throw new ArgumentNullException("curve");

			this.curve = curve;
			this.x = x;
			this.y = y;
			this.withCompression = withCompression;
		}
コード例 #4
0
		public ECDomainParameters(
            ECCurve     curve,
            ECPoint     g,
            BigInteger  n,
            BigInteger  h,
            byte[]      seed)
        {
			if (curve == null)
				throw new ArgumentNullException("curve");
			if (g == null)
				throw new ArgumentNullException("g");
			if (n == null)
				throw new ArgumentNullException("n");
			if (h == null)
				throw new ArgumentNullException("h");

			this.curve = curve;
            this.g = g;
            this.n = n;
            this.h = h;
            this.seed = (seed == null ? null : (byte[])seed.Clone());
        }
コード例 #5
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) || (x == null && y != null))
				throw new ArgumentException("Exactly one of the field elements is null");
		}
コード例 #6
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)
		{
		}
コード例 #7
0
		protected internal ECPointBase(
			ECCurve			curve,
			ECFieldElement	x,
			ECFieldElement	y,
			bool			withCompression)
			: base(curve, x, y, withCompression)
		{
		}
コード例 #8
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)
 {
 }
コード例 #9
0
 public static int GetByteLength(
     ECCurve c)
 {
     return((c.FieldSize + 7) / 8);
 }
コード例 #10
0
        public override ECPoint TwicePlus(ECPoint b)
        {
            if (this == b)
            {
                return(ThreeTimes());
            }
            if (this.IsInfinity)
            {
                return(b);
            }
            if (b.IsInfinity)
            {
                return(Twice());
            }

            ECFieldElement Y1 = this.RawYCoord;

            if (Y1.IsZero)
            {
                return(b);
            }

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

            switch (coord)
            {
            case ECCurve.COORD_AFFINE:
            {
                ECFieldElement X1 = this.RawXCoord;
                ECFieldElement X2 = b.RawXCoord, Y2 = b.RawYCoord;

                ECFieldElement dx = X2.Subtract(X1), dy = Y2.Subtract(Y1);

                if (dx.IsZero)
                {
                    if (dy.IsZero)
                    {
                        // this == b i.e. the result is 3P
                        return(ThreeTimes());
                    }

                    // this == -b, i.e. the result is P
                    return(this);
                }

                /*
                 * Optimized calculation of 2P + Q, as described in "Trading Inversions for
                 * Multiplications in Elliptic Curve Cryptography", by Ciet, Joye, Lauter, Montgomery.
                 */

                ECFieldElement X = dx.Square(), Y = dy.Square();
                ECFieldElement d = X.Multiply(Two(X1).Add(X2)).Subtract(Y);
                if (d.IsZero)
                {
                    return(Curve.Infinity);
                }

                ECFieldElement D  = d.Multiply(dx);
                ECFieldElement I  = D.Invert();
                ECFieldElement L1 = d.Multiply(I).Multiply(dy);
                ECFieldElement L2 = Two(Y1).Multiply(X).Multiply(dx).Multiply(I).Subtract(L1);
                ECFieldElement X4 = (L2.Subtract(L1)).Multiply(L1.Add(L2)).Add(X2);
                ECFieldElement Y4 = (X1.Subtract(X4)).Multiply(L2).Subtract(Y1);

                return(new FpPoint(Curve, X4, Y4, IsCompressed));
            }

            case ECCurve.COORD_JACOBIAN_MODIFIED:
            {
                return(TwiceJacobianModified(false).Add(b));
            }

            default:
            {
                return(Twice().Add(b));
            }
            }
        }
コード例 #11
0
        // B.3 pg 62
        public override ECPoint Twice()
        {
            if (this.IsInfinity)
            {
                return(this);
            }

            ECCurve curve = this.Curve;

            ECFieldElement Y1 = this.RawYCoord;

            if (Y1.IsZero)
            {
                return(curve.Infinity);
            }

            int coord = curve.CoordinateSystem;

            ECFieldElement X1 = this.RawXCoord;

            switch (coord)
            {
            case ECCurve.COORD_AFFINE:
            {
                ECFieldElement X1Squared = X1.Square();
                ECFieldElement gamma     = Three(X1Squared).Add(this.Curve.A).Divide(Two(Y1));
                ECFieldElement X3        = gamma.Square().Subtract(Two(X1));
                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];

                bool Z1IsOne = Z1.IsOne;

                // TODO Optimize for small negative a4 and -3
                ECFieldElement w = curve.A;
                if (!w.IsZero && !Z1IsOne)
                {
                    w = w.Multiply(Z1.Square());
                }
                w = w.Add(Three(X1.Square()));

                ECFieldElement s   = Z1IsOne ? Y1 : Y1.Multiply(Z1);
                ECFieldElement t   = Z1IsOne ? Y1.Square() : s.Multiply(Y1);
                ECFieldElement B   = X1.Multiply(t);
                ECFieldElement _4B = Four(B);
                ECFieldElement h   = w.Square().Subtract(Two(_4B));

                ECFieldElement _2s        = Two(s);
                ECFieldElement X3         = h.Multiply(_2s);
                ECFieldElement _2t        = Two(t);
                ECFieldElement Y3         = _4B.Subtract(h).Multiply(w).Subtract(Two(_2t.Square()));
                ECFieldElement _4sSquared = Z1IsOne ? Two(_2t) : _2s.Square();
                ECFieldElement Z3         = Two(_4sSquared).Multiply(s);

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

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

                bool Z1IsOne = Z1.IsOne;

                ECFieldElement Y1Squared = Y1.Square();
                ECFieldElement T         = Y1Squared.Square();

                ECFieldElement a4    = curve.A;
                ECFieldElement a4Neg = a4.Negate();

                ECFieldElement M, S;
                if (a4Neg.ToBigInteger().Equals(BigInteger.ValueOf(3)))
                {
                    ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square();
                    M = Three(X1.Add(Z1Squared).Multiply(X1.Subtract(Z1Squared)));
                    S = Four(Y1Squared.Multiply(X1));
                }
                else
                {
                    ECFieldElement X1Squared = X1.Square();
                    M = Three(X1Squared);
                    if (Z1IsOne)
                    {
                        M = M.Add(a4);
                    }
                    else if (!a4.IsZero)
                    {
                        ECFieldElement Z1Squared = Z1IsOne ? Z1 : Z1.Square();
                        ECFieldElement Z1Pow4    = Z1Squared.Square();
                        if (a4Neg.BitLength < a4.BitLength)
                        {
                            M = M.Subtract(Z1Pow4.Multiply(a4Neg));
                        }
                        else
                        {
                            M = M.Add(Z1Pow4.Multiply(a4));
                        }
                    }
                    //S = two(doubleProductFromSquares(X1, Y1Squared, X1Squared, T));
                    S = Four(X1.Multiply(Y1Squared));
                }

                ECFieldElement X3 = M.Square().Subtract(Two(S));
                ECFieldElement Y3 = S.Subtract(X3).Multiply(M).Subtract(Eight(T));

                ECFieldElement Z3 = Two(Y1);
                if (!Z1IsOne)
                {
                    Z3 = Z3.Multiply(Z1);
                }

                // Alternative calculation of Z3 using fast square
                //ECFieldElement Z3 = doubleProductFromSquares(Y1, Z1, Y1Squared, Z1Squared);

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

            case ECCurve.COORD_JACOBIAN_MODIFIED:
            {
                return(TwiceJacobianModified(true));
            }

            default:
            {
                throw new InvalidOperationException("unsupported coordinate system");
            }
            }
        }
コード例 #12
0
 protected ECPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, bool withCompression)
     : this(curve, x, y, GetInitialZCoords(curve), withCompression)
 {
 }
コード例 #13
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).Multiply(u).Subtract(vCubed.Multiply(u2));
                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).Multiply(R).Subtract(S1.Multiply(G));

                    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");
            }
            }
        }
コード例 #14
0
 internal FpPoint(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
     : base(curve, x, y, zs, withCompression)
 {
 }
コード例 #15
0
		protected bool Equals(
			ECCurve other)
		{
			return a.Equals(other.a) && b.Equals(other.b);
		}
コード例 #16
0
		public static int GetByteLength(
			ECCurve c)
		{
			return (c.FieldSize + 7) / 8;
		}
コード例 #17
0
 protected internal ECPointBase(ECCurve curve, ECFieldElement x, ECFieldElement y, ECFieldElement[] zs, bool withCompression)
     : base(curve, x, y, zs, withCompression)
 {
 }