Функция Java XpowYmodN, DiffieHellman

Мне нужно для протокола Диффи-Хеллмана создать функцию XpowYmodN. Я нашел в Интернете следующую функцию:

    public long XpowYmodN(long x, long y, long N) {
    long result = 1;
    final long oneShift63 = ((long) 1) << 63;

    for (int i = 0; i < 64; y <<= 1, i++) {
        result = result * result % N;
        if ((y & oneShift63) != 0)
            result = result * x % N;
    }
    return result;
}

Для этого примера: XpowYmodN(29,83,53) результат равен 43. По подсчетам производителя устройства, результат должен быть 50. Может ли кто-нибудь указать мне, где я делаю это неправильно? Я попробовал с Math.pow(X,Y) % N, для этого примера, и я получил результат 28. Я настроен и хотел бы несколько советов о том, как это исправить. Спасибо.

3 ответа

Ваш ответ правильный. Но ценность, которую предоставляет калькулятор, - это не расчет, а обменный ключ. И ваш ответ относится к общедоступной ценности, которую видит отправитель или получатель.

Я проверил различные числа в этой функции, и она отлично работала. Затем я создал дублирующую функцию, которая использовала следующий код, основанный на ответе Уве Плонуса:

public long XpowYmodN(long x, long y, long N) {
    return BigInteger.valueOf(x).modPow(BigInteger.valueOf(y), BigInteger.valueOf(N)).longValue();
}

Я проверил ваши цифры и получил 43, как и эта функция; так что эта функция, кажется, работает отлично. Человек, который опубликовал 29,83,53 числа, в результате чего 50, кажется, не так. Правильный ответ для 29,83,53 - 43.

Вот полный код, который я использовал:

public class Main {
    public static long XpowYmodN_(long x, long y, long N) {
        long result = 1;
        final long oneShift63 = ((long) 1) << 63;

        for (int i = 0; i < 64; y <<= 1, i++) {
            result = result * result % N;
            if ((y & oneShift63) != 0)
                result = result * x % N;
        }
        return result;
    }

    public static long XpowYmodN(long x, long y, long N) {
        return BigInteger.valueOf(x).modPow(BigInteger.valueOf(y), BigInteger.valueOf(N)).longValue();
    }

    public static void main(String[] args)
    {
        System.out.println("BEGIN main");


        System.out.println(Main.XpowYmodN_(29,83,53));
        System.out.println(Main.XpowYmodN(29,83,53));
    }
}

который дал вывод:

НАЧАТЬ основной
43
43

Почему вы не используете класс java.math.BigInteger? Этот класс имеет метод с именем modPow() который предназначен для использования криптографии.

Использование будет

BigInteger result = BigInteger.valueOf(x).modPow(BigInteger.valueof(y), BigInteger.valueOf(n));

Кстати переменные именованные строчными буквами (n в моем случае).

Другие вопросы по тегам