Square() public method

public Square ( ) : ECFieldElement
return ECFieldElement
Example #1
0
        /**
         * Decode a point on this curve from its ASN.1 encoding. The different
         * encodings are taken account of, including point compression for
         * <code>F<sub>p</sub><code> (X9.62 s 4.2.1 pg 17).
         * @return The decoded point.
         */
        public override ECPoint DecodePoint(
            byte[] encoded)
        {
            ECPoint p = null;

            switch (encoded[0])
            {
            // compressed
            case 0x02:
            case 0x03:
                int    ytilde = encoded[0] & 1;
                byte[] i      = new byte[encoded.Length - 1];

                Array.Copy(encoded, 1, i, 0, i.Length);

                ECFieldElement x     = new FpFieldElement(this.q, new BigInteger(1, i));
                ECFieldElement alpha = x.Multiply(x.Square()).Add(x.Multiply(a).Add(b));
                ECFieldElement beta  = alpha.Sqrt();

                //
                // if we can't find a sqrt we haven't got a point on the
                // curve - run!
                //
                if (beta == null)
                {
                    throw new ArithmeticException("Invalid point compression");
                }

                BigInteger betaValue = beta.ToBigInteger();
                int        bit0      = betaValue.TestBit(0) ? 1 : 0;

                if (bit0 != ytilde)
                {
                    // Use the other root
                    beta = new FpFieldElement(q, q.Subtract(betaValue));
                }

                p = new FpPoint(this, x, beta, true);
                break;

            case 0x04:
                byte[] xEnc = new byte[(encoded.Length - 1) / 2];
                byte[] yEnc = new byte[(encoded.Length - 1) / 2];

                Array.Copy(encoded, 1, xEnc, 0, xEnc.Length);
                Array.Copy(encoded, xEnc.Length + 1, yEnc, 0, yEnc.Length);

                p = new FpPoint(this,
                                new FpFieldElement(this.q, new BigInteger(1, xEnc)),
                                new FpFieldElement(this.q, new BigInteger(1, yEnc)));
                break;

            default:
                throw new FormatException("Invalid point encoding " + encoded[0]);
            }

            return(p);
        }
Example #2
0
		// D.1.4 91
		/**
		 * return a sqrt root - the routine verifies that the calculation
		 * returns the right value - if none exists it returns null.
		 */
		public override ECFieldElement Sqrt()
		{
			if (!q.TestBit(0))
				throw Platform.CreateNotImplementedException("even value of q");

			// p mod 4 == 3
			if (q.TestBit(1))
			{
				// TODO Can this be optimised (inline the Square?)
				// z = g^(u+1) + p, p = 4u + 3
				ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));

                return this.Equals(z.Square()) ? z : null;
			}

			// p mod 4 == 1
			BigInteger qMinusOne = q.Subtract(BigInteger.One);

			BigInteger legendreExponent = qMinusOne.ShiftRight(1);
			if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
				return null;

			BigInteger u = qMinusOne.ShiftRight(2);
			BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);

			BigInteger Q = this.x;
			BigInteger fourQ = Q.ShiftLeft(2).Mod(q);

			BigInteger U, V;
			do
			{
				Random rand = new Random();
				BigInteger P;
				do
				{
					P = new BigInteger(q.BitLength, rand);
				}
				while (P.CompareTo(q) >= 0
					|| !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne)));

				BigInteger[] result = fastLucasSequence(q, P, Q, k);
				U = result[0];
				V = result[1];

				if (V.Multiply(V).Mod(q).Equals(fourQ))
				{
					// Integer division by 2, mod q
					if (V.TestBit(0))
					{
						V = V.Add(q);
					}

					V = V.ShiftRight(1);

					Debug.Assert(V.Multiply(V).Mod(q).Equals(x));

					return new FpFieldElement(q, V);
				}
			}
			while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

			return null;


//			BigInteger qMinusOne = q.Subtract(BigInteger.One);
//
//			BigInteger legendreExponent = qMinusOne.ShiftRight(1);
//			if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
//				return null;
//
//			Random rand = new Random();
//			BigInteger fourX = x.ShiftLeft(2);
//
//			BigInteger r;
//			do
//			{
//				r = new BigInteger(q.BitLength, rand);
//			}
//			while (r.CompareTo(q) >= 0
//				|| !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
//
//			BigInteger n1 = qMinusOne.ShiftRight(2);
//			BigInteger n2 = n1.Add(BigInteger.One);
//
//			BigInteger wOne = WOne(r, x, q);
//			BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q);
//			BigInteger twoR = r.ShiftLeft(1);
//
//			BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q)
//				.Multiply(x).Mod(q)
//				.Multiply(wSum).Mod(q);
//
//			return new FpFieldElement(q, root);
		}
Example #3
0
        /**
         * Decode a point on this curve from its ASN.1 encoding. The different
         * encodings are taken account of, including point compression for
         * <code>F<sub>p</sub></code> (X9.62 s 4.2.1 pg 17).
         * @return The decoded point.
         */
        public override ECPoint DecodePoint(
			byte[] encoded)
        {
            ECPoint p = null;

            switch (encoded[0])
            {
                // compressed
                case 0x02:
                case 0x03:
                    int ytilde = encoded[0] & 1;
                    byte[] i = new byte[encoded.Length - 1];

                    Array.Copy(encoded, 1, i, 0, i.Length);

                    ECFieldElement x = new FpFieldElement(this.q, new BigInteger(1, i));
                    ECFieldElement alpha = x.Multiply(x.Square()).Add(x.Multiply(a).Add(b));
                    ECFieldElement beta = alpha.Sqrt();

                    //
                    // if we can't find a sqrt we haven't got a point on the
                    // curve - run!
                    //
                    if (beta == null)
                        throw new ArithmeticException("Invalid point compression");

                    BigInteger betaValue = beta.ToBigInteger();
                    int bit0 = betaValue.TestBit(0) ? 1 : 0;

                    if (bit0 != ytilde)
                    {
                        // Use the other root
                        beta = new FpFieldElement(q, q.Subtract(betaValue));
                    }

                    p = new FpPoint(this, x, beta, true);
                    break;
                case 0x04:
                    byte[] xEnc = new byte[(encoded.Length - 1) / 2];
                    byte[] yEnc = new byte[(encoded.Length - 1) / 2];

                    Array.Copy(encoded, 1, xEnc, 0, xEnc.Length);
                    Array.Copy(encoded, xEnc.Length + 1, yEnc, 0, yEnc.Length);

                    p = new FpPoint(this,
                        new FpFieldElement(this.q, new BigInteger(1, xEnc)),
                        new FpFieldElement(this.q, new BigInteger(1, yEnc)));
                    break;
                default:
                    throw new FormatException("Invalid point encoding " + encoded[0]);
            }

            return p;
        }
        // D.1.4 91

        /**
         * return a sqrt root - the routine verifies that the calculation
         * returns the right value - if none exists it returns null.
         */
        public override ECFieldElement Sqrt()
        {
            if (!q.TestBit(0))
            {
                throw Platform.CreateNotImplementedException("even value of q");
            }

            // p mod 4 == 3
            if (q.TestBit(1))
            {
                // TODO Can this be optimised (inline the Square?)
                // z = g^(u+1) + p, p = 4u + 3
                ECFieldElement z = new FpFieldElement(q, x.ModPow(q.ShiftRight(2).Add(BigInteger.One), q));

                return(z.Square().Equals(this) ? z : null);
            }

            // p mod 4 == 1
            BigInteger qMinusOne = q.Subtract(BigInteger.One);

            BigInteger legendreExponent = qMinusOne.ShiftRight(1);

            if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
            {
                return(null);
            }

            BigInteger u = qMinusOne.ShiftRight(2);
            BigInteger k = u.ShiftLeft(1).Add(BigInteger.One);

            BigInteger Q     = this.x;
            BigInteger fourQ = Q.ShiftLeft(2).Mod(q);

            BigInteger U, V;

            do
            {
                Random     rand = new Random();
                BigInteger P;
                do
                {
                    P = new BigInteger(q.BitLength, rand);
                }while (P.CompareTo(q) >= 0 ||
                        !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, q).Equals(qMinusOne)));

                BigInteger[] result = fastLucasSequence(q, P, Q, k);
                U = result[0];
                V = result[1];

                if (V.Multiply(V).Mod(q).Equals(fourQ))
                {
                    // Integer division by 2, mod q
                    if (V.TestBit(0))
                    {
                        V = V.Add(q);
                    }

                    V = V.ShiftRight(1);

                    Debug.Assert(V.Multiply(V).Mod(q).Equals(x));

                    return(new FpFieldElement(q, V));
                }
            }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne));

            return(null);


//			BigInteger qMinusOne = q.Subtract(BigInteger.One);
//
//			BigInteger legendreExponent = qMinusOne.ShiftRight(1);
//			if (!(x.ModPow(legendreExponent, q).Equals(BigInteger.One)))
//				return null;
//
//			Random rand = new Random();
//			BigInteger fourX = x.ShiftLeft(2);
//
//			BigInteger r;
//			do
//			{
//				r = new BigInteger(q.BitLength, rand);
//			}
//			while (r.CompareTo(q) >= 0
//				|| !(r.Multiply(r).Subtract(fourX).ModPow(legendreExponent, q).Equals(qMinusOne)));
//
//			BigInteger n1 = qMinusOne.ShiftRight(2);
//			BigInteger n2 = n1.Add(BigInteger.One);
//
//			BigInteger wOne = WOne(r, x, q);
//			BigInteger wSum = W(n1, wOne, q).Add(W(n2, wOne, q)).Mod(q);
//			BigInteger twoR = r.ShiftLeft(1);
//
//			BigInteger root = twoR.ModPow(q.Subtract(BigInteger.Two), q)
//				.Multiply(x).Mod(q)
//				.Multiply(wSum).Mod(q);
//
//			return new FpFieldElement(q, root);
        }