Exemplo n.º 1
0
 protected bool Equals(FPFieldElement other)
 {
     return(_q.Equals(other._q) && base.Equals(other));
 }
 protected bool Equals(FPFieldElement other)
 {
     return _q.Equals(other._q) && base.Equals(other);
 }
Exemplo n.º 3
0
        /// <summary>
        /// D.1.4 91
        /// return a sqrt root - the routine verifies that the calculation
        /// returns the right value - if none exists it returns null.
        /// </summary>
        /// <returns></returns>
        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
                var z = new FPFieldElement(_q, _x.ModPow(_q.ShiftRight(2).Add(BigInteger.One), _q));

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

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

            var legendreExponent = qMinusOne.ShiftRight(1);

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

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

            var Q     = _x;
            var fourQ = Q.ShiftLeft(2).Mod(_q);

            IBigInteger U;
            IBigInteger V;

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

                var result = FastLucasSequence(_q, P, Q, k);
                U = result[0];
                V = result[1];

                if (!V.Multiply(V).Mod(_q).Equals(fourQ))
                {
                    continue;
                }

                // 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);
        }
        /// <summary>
        /// D.1.4 91
        /// return a sqrt root - the routine verifies that the calculation
        /// returns the right value - if none exists it returns null.
        /// </summary>
        /// <returns></returns>
        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
                var z = new FPFieldElement(_q, _x.ModPow(_q.ShiftRight(2).Add(BigInteger.One), _q));

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

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

            var legendreExponent = qMinusOne.ShiftRight(1);
            if (!(_x.ModPow(legendreExponent, _q).Equals(BigInteger.One)))
                return null;

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

            var Q = _x;
            var fourQ = Q.ShiftLeft(2).Mod(_q);

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

                var result = FastLucasSequence(_q, P, Q, k);
                U = result[0];
                V = result[1];

                if (!V.Multiply(V).Mod(_q).Equals(fourQ))
                    continue;

                // 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;
        }