Esempio n. 1
0
        public BigInteger modPow(BigInteger exponent, BigInteger m)
        {
            if (m.sign <= 0)
            {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            BigInteger _base = this;

            if (m.isOne() | (exponent.sign > 0 & _base.sign == 0))
            {
                return(BigInteger.ZERO);
            }
            if (_base.sign == 0 && exponent.sign == 0)
            {
                return(BigInteger.ONE);
            }
            if (exponent.sign < 0)
            {
                _base    = modInverse(m);
                exponent = exponent.negate();
            }
            // From now on: (m > 0) and (exponent >= 0)
            BigInteger res = (m.testBit(0)) ? Division.oddModPow(_base.abs(),
                                                                 exponent, m) : Division.evenModPow(_base.abs(), exponent, m);

            if ((_base.sign < 0) && exponent.testBit(0))
            {
                // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m
                res = m.subtract(BigInteger.ONE).multiply(res).mod(m);
            }
            // else exponent is even, so base^exp is positive
            return(res);
        }
Esempio n. 2
0
        public BigInteger modInverse(BigInteger m)
        {
            if (m.sign <= 0)
            {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            // If both are even, no inverse exists
            if (!(testBit(0) || m.testBit(0)))
            {
                throw new ArithmeticException("BigInteger not invertible.");
            }
            if (m.isOne())
            {
                return(ZERO);
            }

            // From now on: (m > 1)
            BigInteger res = Division.modInverseMontgomery(abs().mod(m), m);

            if (res.sign == 0)
            {
                throw new ArithmeticException("BigInteger not invertible.");
            }

            res = ((sign < 0) ? m.subtract(res) : res);
            return(res);
        }
Esempio n. 3
0
        public BigInteger divide(BigInteger divisor)
        {
            if (divisor.sign == 0)
            {
                throw new ArithmeticException("BigInteger divide by zero");
            }
            int divisorSign = divisor.sign;

            if (divisor.isOne())
            {
                return((divisor.sign > 0) ? this : this.negate());
            }
            int thisSign   = sign;
            int thisLen    = numberLength;
            int divisorLen = divisor.numberLength;

            if (thisLen + divisorLen == 2)
            {
                long val = (digits[0] & 0xFFFFFFFFL)
                           / (divisor.digits[0] & 0xFFFFFFFFL);
                if (thisSign != divisorSign)
                {
                    val = -val;
                }
                return(valueOf(val));
            }
            int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
                       : Elementary.compareArrays(digits, divisor.digits, thisLen));

            if (cmp == EQUALS)
            {
                return((thisSign == divisorSign) ? ONE : MINUS_ONE);
            }
            if (cmp == LESS)
            {
                return(ZERO);
            }
            int resLength = thisLen - divisorLen + 1;

            int[] resDigits = new int[resLength];
            int   resSign   = ((thisSign == divisorSign) ? 1 : -1);

            if (divisorLen == 1)
            {
                Division.divideArrayByInt(resDigits, digits, thisLen,
                                          divisor.digits[0]);
            }
            else
            {
                Division.divide(resDigits, resLength, digits, thisLen,
                                divisor.digits, divisorLen);
            }
            BigInteger result = new BigInteger(resSign, resLength, resDigits);

            result.cutOffLeadingZeroes();
            return(result);
        }
Esempio n. 4
0
        private static bool millerRabin(BigInteger n, int t)
        {
            // PRE: n >= 0, t >= 0
            BigInteger x;                                      // x := UNIFORM{2...n-1}
            BigInteger y;                                      // y := x^(q * 2^j) mod n
            BigInteger n_minus_1 = n.subtract(BigInteger.ONE); // n-1
            int        bitLength = n_minus_1.bitLength();      // ~ log2(n-1)
            // (q,k) such that: n-1 = q * 2^k and q is odd
            int        k   = n_minus_1.getLowestSetBit();
            BigInteger q   = n_minus_1.shiftRight(k);
            Random     rnd = new Random();

            for (int i = 0; i < t; i++)
            {
                // To generate a witness 'x', first it use the primes of table
                if (i < primes.Length)
                {
                    x = BIprimes[i];
                }
                else    /*
                         * It generates random witness only if it's necesssary. Note
                         * that all methods would call Miller-Rabin with t <= 50 so
                         * this part is only to do more robust the algorithm
                         */
                {
                    do
                    {
                        x = new BigInteger(bitLength, rnd);
                    } while ((x.compareTo(n) >= BigInteger.EQUALS) || (x.sign == 0) ||
                             x.isOne());
                }
                y = x.modPow(q, n);
                if (y.isOne() || y.Equals(n_minus_1))
                {
                    continue;
                }
                for (int j = 1; j < k; j++)
                {
                    if (y.Equals(n_minus_1))
                    {
                        continue;
                    }
                    y = y.multiply(y).mod(n);
                    if (y.isOne())
                    {
                        return(false);
                    }
                }
                if (!y.Equals(n_minus_1))
                {
                    return(false);
                }
            }
            return(true);
        }
Esempio n. 5
0
        private static bool millerRabin(BigInteger n, int t)
        {
            // PRE: n >= 0, t >= 0
            BigInteger x; // x := UNIFORM{2...n-1}
            BigInteger y; // y := x^(q * 2^j) mod n
            BigInteger n_minus_1 = n.subtract(BigInteger.ONE); // n-1
            int bitLength = n_minus_1.bitLength(); // ~ log2(n-1)
            // (q,k) such that: n-1 = q * 2^k and q is odd
            int k = n_minus_1.getLowestSetBit();
            BigInteger q = n_minus_1.shiftRight(k);
            Random rnd = new Random();

            for (int i = 0; i < t; i++) {
                // To generate a witness 'x', first it use the primes of table
                if (i < primes.Length) {
                    x = BIprimes[i];
                } else {/*
                         * It generates random witness only if it's necesssary. Note
                         * that all methods would call Miller-Rabin with t <= 50 so
                         * this part is only to do more robust the algorithm
                         */
                    do {
                        x = new BigInteger(bitLength, rnd);
                    } while ((x.compareTo(n) >= BigInteger.EQUALS) || (x.sign == 0)
                             || x.isOne());
                }
                y = x.modPow(q, n);
                if (y.isOne() || y.Equals(n_minus_1)) {
                    continue;
                }
                for (int j = 1; j < k; j++) {
                    if (y.Equals(n_minus_1)) {
                        continue;
                    }
                    y = y.multiply(y).mod(n);
                    if (y.isOne()) {
                        return false;
                    }
                }
                if (!y.Equals(n_minus_1)) {
                    return false;
                }
            }
            return true;
        }
Esempio n. 6
0
        public BigInteger modPow(BigInteger exponent, BigInteger m)
        {
            if (m.sign <= 0) {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            BigInteger _base = this;

            if (m.isOne() | (exponent.sign > 0 & _base.sign == 0)) {
                return BigInteger.ZERO;
            }
            if (_base.sign == 0 && exponent.sign == 0) {
                return BigInteger.ONE;
            }
            if (exponent.sign < 0) {
                _base = modInverse(m);
                exponent = exponent.negate();
            }
            // From now on: (m > 0) and (exponent >= 0)
            BigInteger res = (m.testBit(0)) ? Division.oddModPow(_base.abs(),
                                                                 exponent, m) : Division.evenModPow(_base.abs(), exponent, m);
            if ((_base.sign < 0) && exponent.testBit(0)) {
                // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m
                res = m.subtract(BigInteger.ONE).multiply(res).mod(m);
            }
            // else exponent is even, so base^exp is positive
            return res;
        }
Esempio n. 7
0
        public BigInteger modInverse(BigInteger m)
        {
            if (m.sign <= 0) {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            // If both are even, no inverse exists
            if (!(testBit(0) || m.testBit(0))) {
                throw new ArithmeticException("BigInteger not invertible.");
            }
            if (m.isOne()) {
                return ZERO;
            }

            // From now on: (m > 1)
            BigInteger res = Division.modInverseMontgomery(abs().mod(m), m);
            if (res.sign == 0) {
                throw new ArithmeticException("BigInteger not invertible.");
            }

            res = ((sign < 0) ? m.subtract(res) : res);
            return res;
        }
Esempio n. 8
0
 public BigInteger divide(BigInteger divisor)
 {
     if (divisor.sign == 0) {
         throw new ArithmeticException("BigInteger divide by zero");
     }
     int divisorSign = divisor.sign;
     if (divisor.isOne()) {
         return ((divisor.sign > 0) ? this : this.negate());
     }
     int thisSign = sign;
     int thisLen = numberLength;
     int divisorLen = divisor.numberLength;
     if (thisLen + divisorLen == 2) {
         long val = (digits[0] & 0xFFFFFFFFL)
             / (divisor.digits[0] & 0xFFFFFFFFL);
         if (thisSign != divisorSign) {
             val = -val;
         }
         return valueOf(val);
     }
     int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
                : Elementary.compareArrays(digits, divisor.digits, thisLen));
     if (cmp == EQUALS) {
         return ((thisSign == divisorSign) ? ONE : MINUS_ONE);
     }
     if (cmp == LESS) {
         return ZERO;
     }
     int resLength = thisLen - divisorLen + 1;
     int[] resDigits = new int[resLength];
     int resSign = ((thisSign == divisorSign) ? 1 : -1);
     if (divisorLen == 1) {
         Division.divideArrayByInt(resDigits, digits, thisLen,
                                   divisor.digits[0]);
     } else {
         Division.divide(resDigits, resLength, digits, thisLen,
                         divisor.digits, divisorLen);
     }
     BigInteger result = new BigInteger(resSign, resLength, resDigits);
     result.cutOffLeadingZeroes();
     return result;
 }