Модуль не возвращает правильное значение для неотрицательного ввода

Я работаю над уменьшенными методами RSA encryption и decryption, и все работает хорошо, пока я не пытаюсь взять модуль числа. Оператор модуля не возвращает ожидаемый результат.

        for(int k = 0; k < sA.length; k++){
            int value = Integer.parseInt(sA[k]);
            System.out.println("value : " + value);
            double mToE = Math.pow(value,e);
            System.out.println("mToE: " + mToE);
            double c = mToE % n;
            System.out.println("C: " + c);

sA — это массив, содержащий значения {06707708, 30670320, 50050050}.

mToE представляет M (в данном случае каждую строку в sA), возведенную в степень e(13).

C = M^e mod n где n вводится как параметр.

Эти конкретные строки выводят:

value : 6707708
mToE: 5.56498415666044E88
C: 5.2630797E7
0
value : 30670320
mToE: 2.1248975415575414E97
C: 8.973537E7
1
value : 50050050
mToE: 1.2366838911816623E100
C: 3.4150233E7
2

Например, первое значение c должно быть:

c: 3.2059734E7

or 32059734

Какая причина может быть для получения такого результата?

Заранее спасибо за все ваши советы.


person jm2rv    schedule 15.04.2015    source источник
comment
Каково ваше n в данном примере? Мое предположение состоит в том, что double mToE вызывает проблему, поскольку вам нужно пожертвовать точностью, чтобы представить такие большие числа.   -  person Turing85    schedule 15.04.2015


Ответы (1)


Тип double имеет большую точность, 53 бита, но этого недостаточно для хранения значений с точностью до единицы при очень высоких значениях, которые вы видите. Значения mToE — это значения double, наиболее близкие к истинным значениям расчета.

С методом Math.ulp (единица в последнем место), мы можем определить точность double значения величины 5.56498415666044E88.

System.out.println(Math.ulp(mToE));

Это выводит

7.067388259113537E72

Из-за этого ваше значение, скорее всего, будет отличаться на 72 цифры. Это, конечно, полностью испортит значение c, которое берется из операции mod %.

Для необходимой точности вам нужно будет использовать BigIntegers. Кроме того, BigInteger имеет собственный modPowметод, созданный специально для ваших целей.

person rgettman    schedule 15.04.2015