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