Как изменить размер ArrayList

Вычисление pow (a, b) mod n

  1. Ключевой проблемой с кодом OP является a * a. Это int переполнение (неопределенное поведение), когда a достаточно велико. Тип res не имеет значения при умножении a * a. Решение состоит в том, чтобы гарантировать: 1) умножение выполняется с использованием 2x широкой математики или 2) с модулем n, n*n <= type_MAX + 1
  2. Нет причин возвращать более широкий тип, чем тип модуля , поскольку результат всегда представляет этот тип.
    // unsigned long int decrypt2(int a,int b,int n)
    int decrypt2(int a,int b,int n)
    
  3. Использование математики 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
16
задан FunctionR 10 May 2014 в 18:58
поделиться