Есть ли погрешность при работе с большими числами в python?

Реализую алгоритм шифрования rsa. Шифрую сообщение следующим образом

for i in range(len(dig_text)):
    dig_text[i] = (dig_text[i]**e) % n

Расшифровываю:

for i in range(len(crypt)):
    crypt[i] = pow(crypt[i], d) % n

Проблема в расшифровке. Для небольших чисел вычисляется корректный результат, но с большими числами d и n результат некорректный. Есть предположения, что при больших e, d и n теряется точность вычислений. Если проблема в этом, то как её решить? А если не в этом, то в чем тогда?


Ответы (1 шт):

Автор решения: CrazyElf

У встроенной функции pow есть третий аргумент как-раз для вашего случая. Попробуйте использовать вместо ваших конструкций такие:

  • (dig_text[i]**e)%n --> pow(dig_text[i], e, n)

  • pow(crypt[i],d) % n --> pow(crypt[i], d, n)

Пишут, что такой вариант работает гораздо быстрее и эффективнее для больших чисел (для маленьких чисел всё наоборот).

Но вообще, если вы используете целочисленные данные и встроенную функцию pow, а не math.pow, то проблем с округлением/представлением чисел быть не должно - int в питоне не ограничен. А вот math.pow всегда использует тип float, имеющий ограниченную точность, поэтому у него такие проблемы могут быть.

Если же вам нужны обязательно вычисления с плавающей точкой, то можно посмотреть в сторону более точного представления чисел numpy.float128 а лучше на числа с плавающей точкой без потери точности decimal.Decimal.

→ Ссылка