Если кто-то прибывает позже, вот еще несколько актуальных алгоритмов (с ошибками ... читайте внимательно)
https://eprint.iacr.org/2014/755.pdf
На самом деле существует два основных типа формул сокращения: Баретт и Монтгомери. Бумаги из eprint повторяются в разных версиях (алгоритмы 1-3) и дают «улучшенную» версию в алгоритме 4.
Обзор
Теперь я даю обзор алгоритма 4.
1.) Вычислите «A * B» и сохраните весь продукт в «C», чтобы C и модуль $ p $ были входными данными для этого алгоритма.
2.) Вычислите длину в битах $ p $, скажем: функция «Width (p)» возвращает именно это значение.
3.) Разбейте входные данные $ C $ на N «блоков» размером «Ширина (p)» и сохраните каждый в G. Начните с G [0] = lsb (p) и завершите в G [N-1 ] = msb (p). (Описание действительно неисправно из бумаги)
4.) Запустите цикл while:
Установите N = N-1 (чтобы добраться до последнего элемента)
предварительно вычислить $ b: = 2 ^ {Width (p)} \ bmod p $
while N>0 do:
T = G[N]
for(i=0; i<Width(p); i++) do: //Note: that counter doesn't matter, it limits the loop)
T = T << 1 //leftshift by 1 bit
while is_set( bit( T, Width(p) ) ) do // (N+1)-th bit of T is 1
unset( bit( T, Width(p) ) ) // unset the (N+1)-th bit of T (==0)
T += b
endwhile
endfor
G[N-1] += T
while is_set( bit( G[N-1], Width(p) ) ) do
unset( bit( G[N-1], Width(p) ) )
G[N-1] += b
endwhile
N -= 1
endwhile
Это очень много. Не нужно только рекурсивно уменьшать G [0]:
while G[0] > p do
G[0] -= p
endwhile
return G[0]// = C mod p
Остальные три алгоритма четко определены, но в них отсутствует некоторая информация или они действительно ошибочны. Но это работает для любого размера;)