BigIntegers в степени BigInteger (подпись Шнорра)

Я пытаюсь реализовать алгоритм подписи Шнорра на Java. Я столкнулся с проблемой расчета мощности с большим показателем (например, хеш-числом MD5).

Есть ли способ получить BigInteger в силе BigInteger?

Мне нужно вычислить (a^x*b^y)% z, где y — чрезвычайно большое число. Есть ли способ вычисления таких выражений?

Спасибо


person Sergey Pekar    schedule 20.11.2013    source источник
comment
Связано: math.stackexchange.com/q/176252   -  person Luiggi Mendoza    schedule 21.11.2013
comment
Есть одна очевидная причина, по которой у вас проблемы. Даже такое маленькое число, как, скажем, 42, заняло бы больше памяти, чем существует на планете, если бы вы возвели его в (2^127)-ю степень.   -  person cHao    schedule 21.11.2013
comment
@cHao Поскольку $z$ относительно мал, вам нужно всего несколько сотен байтов.   -  person CodesInChaos    schedule 21.11.2013
comment
Это явно не дубликат связанного вопроса. Подписи Шнорра используют модульную арифметику, в заголовке связанного вопроса указано, что речь идет не о модульной арифметике.   -  person CodesInChaos    schedule 21.11.2013
comment
@CodesInChaos: Модуль не упоминался в вопросе, когда его впервые задали.   -  person cHao    schedule 21.11.2013
comment
@cHao Даже в первой версии упоминались подписи Шнорра, которые обычно реализуются в простом конечном поле с несколькими тысячами бит. Но понятно, что кто-то, кто не является криптографом, упускает эту часть.   -  person CodesInChaos    schedule 21.11.2013
comment
Так что явно не дубликат.   -  person Dawood ibn Kareem    schedule 22.11.2013


Ответы (3)


Для алгоритма подписи Шнорра вам действительно нужна комбинированная операция мощности и модуля. Простое выполнение силовой операции само по себе не имеет смысла из-за потенциально огромного размера задействованных чисел.

Вам нужно использовать метод modPow класса BigInteger.

person Dawood ibn Kareem    schedule 20.11.2013

Наконец-то я нашел решение. Я могу очень быстро вычислить свое выражение, используя эту технику:

(a * b) % p = ((a % p) * (b % p)) % p

Итак, мой пример будет выглядеть так:

(a^x * b^y) % z = ( ((a^x) % z) * ((b^y) % z) ) % z;

или, используя BigInteger в Java:

BigInteger result = a.modPow(x, z).multiply( b.modPow(y, z) ).mod(z);
person Sergey Pekar    schedule 20.11.2013
comment
+1 за решение собственной проблемы и за описание решения. Честно говоря, я никогда бы не понял, что проблема была настолько простой — прошло слишком много времени с тех пор, как я впервые изучил модульную арифметику. - person Ilmari Karonen; 21.11.2013

Нет. Максимальное значение, поддерживаемое BigInteger, равно 2Integer.MAX_VALUE-1. Это уточняющее предложение было добавлено в BigInteger javadoc в Java. 8, но реализация остается неизменной уже довольно давно.

BigInteger должен поддерживать значения в диапазоне от -2Integer.MAX_VALUE (исключительно) до +2Integer.MAX_VALUE (исключительно) и может поддерживать значения за пределами этого диапазона.

Как указывали другие, вы можете использовать modPow вместо вычисления промежуточных значений.

Для сравнения: примерно 10 80 (или 2265) атомов во Вселенной.

person ntoskrnl    schedule 20.11.2013
comment
Мне нужно вычислить (a^x*b^y)% z, где y — чрезвычайно большое число. Есть ли способ вычисления таких выражений? - person Sergey Pekar; 21.11.2013