Вычисление pow (a, b) mod n
blockquote>
- Ключевой проблемой с кодом OP является
a * a
. Этоint
переполнение (неопределенное поведение), когдаa
достаточно велико. Типres
не имеет значения при умноженииa * a
. Решение состоит в том, чтобы гарантировать: 1) умножение выполняется с использованием 2x широкой математики или 2) с модулемn
,n*n <= type_MAX + 1
- Нет причин возвращать более широкий тип, чем тип модуля , поскольку результат всегда представляет этот тип.
// unsigned long int decrypt2(int a,int b,int n) int decrypt2(int a,int b,int n)
- Использование математики unsigned , безусловно, более подходит для целей RSA в OP.
// (a^b)%n // n != 0 // Test if unsigned long long at least 2x values bits as unsigned #if ULLONG_MAX/UINT_MAX - 1 > UINT_MAX unsigned decrypt2(unsigned a, unsigned b, unsigned n) { unsigned long long result = 1u % n; // Insure result < n, even when n==1 while (b > 0) { if (b & 1) result = (result * a) % n; a = (1ULL * a * a) %n; b >>= 1; } return (unsigned) result; } #else unsigned decrypt2(unsigned a, unsigned b, unsigned n) { // Detect if UINT_MAX + 1 < n*n if (UINT_MAX/n < n-1) { return TBD_code_with_wider_math(a,b,n); } a %= n; unsigned result = 1u % n; while (b > 0) { if (b & 1) result = (result * a) % n; a = (a * a) % n; b >>= 1; } return result; } #endif