BigInteger.Jacobi C# (CSharp) Method

Jacobi() public static method

public static Jacobi ( BigInteger a, BigInteger b ) : int
a BigInteger
b BigInteger
return int
        public static int Jacobi(BigInteger a, BigInteger b)
        {
                // Jacobi defined only for odd integers
                if((b.data[0] & 0x1) == 0)
                        throw (new ArgumentException("Jacobi defined only for odd integers."));

                if(a >= b)      a %= b;
                if(a.dataLength == 1 && a.data[0] == 0)      return 0;  // a == 0
                if(a.dataLength == 1 && a.data[0] == 1)      return 1;  // a == 1

                if(a < 0)
                {
                        if( (((b-1).data[0]) & 0x2) == 0)       //if( (((b-1) >> 1).data[0] & 0x1) == 0)
                                return Jacobi(-a, b);
                        else
                                return -Jacobi(-a, b);
                }

                int e = 0;
                for(int index = 0; index < a.dataLength; index++)
                {
                        uint mask = 0x01;

                        for(int i = 0; i < 32; i++)
                        {
                                if((a.data[index] & mask) != 0)
                                {
                                        index = a.dataLength;      // to break the outer loop
                                        break;
                                }
                                mask <<= 1;
                                e++;
                        }
                }

                BigInteger a1 = a >> e;

                int s = 1;
                if((e & 0x1) != 0 && ((b.data[0] & 0x7) == 3 || (b.data[0] & 0x7) == 5))
                        s = -1;

                if((b.data[0] & 0x3) == 3 && (a1.data[0] & 0x3) == 3)
                        s = -s;

                if(a1.dataLength == 1 && a1.data[0] == 1)
                        return s;
                else
                        return (s * Jacobi(b % a1, a1));
        }

Usage Example

        private BigInteger Sqrt(BigInteger val, BigInteger field)
        {
            if ((field & 3) == 3)
            {
                return(BigInteger.Pow(val, (field + 1) >> 2, field));
            }

            BigInteger root  = 0;
            BigInteger delta = ((field - 4) * (field - val)) % field;
            BigInteger temp  = 1;
            BigInteger qnr   = 0;
            BigInteger buf   = 0;
            int        ID    = 1;

            switch (ID)
            {
            case 1:

                root = TonelliShanks(val, field);

                if (val == (root * root) % field)
                {
                    return(root);
                }
                goto case 2;

            case 2:

                qnr = BigInteger.Next(rand, 2, field - 1);

                if (BigInteger.Jacobi(qnr, field) != -1)
                {
                    goto case 2;
                }

                BigInteger square = (qnr * qnr) % field;
                delta = (delta * square) % field;
                temp  = (temp * qnr) % field;
                buf   = TonelliShanks(delta, field);

                if (delta != (buf * buf) % field)
                {
                    goto case 2;
                }
                goto case 3;

            case 3:

                BigInteger vtemp = (2 * temp) % field;
                BigInteger inv   = vtemp.Inverse(field);

                root = (buf * inv) % field;
                break;
            }

            return(root);
        }
All Usage Examples Of BigInteger::Jacobi