Я работал над проблемой вычисления модульной инверсии большого целого числа, то есть a ^ -1 mod n. и использовал встроенную функцию BigInteger modInverse, чтобы проверить мою работу.
Я кодировал алгоритм, как показано в «Руководстве по прикладной криптографии» Menezes, et al. К сожалению для меня, я не получаю правильный результат для всех целых чисел.
Я думаю, что строка q = a.divide (b) - моя проблема, поскольку функция деления плохо документирована (IMO) (мой код страдает аналогично). BigInteger.divide (val) округляет или усекает? Мое предположение - усечение, так как документы говорят, что оно имитирует поведение int. Любые другие идеи приветствуются.
Это код, с которым я работал:
private static BigInteger modInverse(BigInteger a, BigInteger b) throws ArithmeticException {
//trivial case: b = 0 => a^-1 = 1
if (b.equals(BigInteger.ZERO)) {
return BigInteger.ONE;
}
//all other cases
BigInteger x2 = BigInteger.ONE;
BigInteger x1 = BigInteger.ZERO;
BigInteger y2 = BigInteger.ZERO;
BigInteger y1 = BigInteger.ONE;
BigInteger x, y, q, r;
while (b.compareTo(BigInteger.ZERO) == 1) {
q = a.divide(b);
r = a.subtract(q.multiply(b));
x = x2.subtract(q.multiply(x1));
y = y2.subtract(q.multiply(y1));
a = b;
b = r;
x2 = x1;
x1 = x;
y2 = y1;
y1 = y;
}
if (!a.equals(BigInteger.ONE))
throw new ArithmeticException("a and n are not coprime");
return x2;
}
Пример ввода, который дает неправильный ввод:
а: 123456789
б: 2 ^ 809 - 1
Пример ввода, который дает ожидаемые результаты:
а: 123456789
б: 2 ^ 807 - 1