В математике и компьютерном программировании возведение в степень путем возведения в степень является общим методом быстрого вычисления больших положительных целых степеней числа или , в более общем смысле , элемента полугруппы , такого как многочлен или квадратная матрица . Некоторые варианты обычно называют алгоритмами квадрата и умножения или двоичным возведением в степень . Они могут иметь весьма общее применение, например, в модульной арифметике или возведении матриц в степень. Для полугрупп, для которых обычно используется аддитивная запись , например эллиптических кривых, используемых в криптографии , этот метод также называется двойным и сложенным .
Метод основан на наблюдении, что для любого целого числа имеет место:
Если показатель степени равен нулю, то ответ равен 1, а если показатель степени отрицательный, мы можем повторно использовать предыдущую формулу, переписав значение, используя положительный показатель степени. То есть,
Вместе они могут быть реализованы непосредственно как следующий рекурсивный алгоритм :
In: целое число x; целое число n Вышел: х н exp_by_squaring(x, n) если n < 0, то return exp_by_squaring(1 / x, -n); иначе, если n = 0, то возврат 1; иначе, если n четно, то return exp_by_squaring(x * x, n/2); иначе, если n нечетное, то return x * exp_by_squaring(x * x, (n - 1)/2); конечная функция
При каждом рекурсивном вызове младшие цифры двоичного представления числа n удаляются. Отсюда следует, что количество рекурсивных вызовов равно количеству бит двоичного представления n . Таким образом, этот алгоритм вычисляет это количество квадратов и меньшее количество умножений, которое равно числу 1 в двоичном представлении n . Это логарифмическое количество операций необходимо сравнить с тривиальным алгоритмом, требующим n - 1 умножений.
Этот алгоритм не является хвостовой рекурсией . Это означает, что для этого требуется объем вспомогательной памяти, который примерно пропорционален количеству рекурсивных вызовов — или, возможно, больше, если объем данных на итерацию увеличивается.
Алгоритмы следующего раздела используют другой подход, и полученные алгоритмы требуют того же количества операций, но используют вспомогательную память, примерно такую же, как память, необходимая для хранения результата.
Варианты, описанные в этом разделе, основаны на формуле
Если применить эту формулу рекурсивно, начав с y = 1 , в конечном итоге получим показатель степени, равный 0 , и тогда желаемым результатом будет левый множитель.
Это может быть реализовано как функция хвостовой рекурсии:
Функция exp_by_squaring ( x , n ) возвращает exp_by_squaring2 ( 1 , x , n ) Функция exp_by_squaring2 ( y , x , n ) если n < 0 , то возвращает exp_by_squaring2 ( y , 1 / x , -n ) ; иначе , если n = 0 , вернуть y ; иначе , если n четно , верните exp_by_squaring2 ( y , x * x , n / 2 ) ; иначе , если n нечетно , верните exp_by_squaring2 ( x * y , x * x , ( n - 1 ) / 2 ) .
Итерационная версия алгоритма также использует ограниченное вспомогательное пространство и имеет вид
Функция exp_by_squaring_iterative ( x , n ) , если n < 0 , то x := 1 / x ; п := - п ; если n = 0 , то вернуть 1 y := 1 ; в то время как n > 1 , если n нечетно, то y : = x * y ; п := п - 1 ; х := х * х ; п := п / 2 ; вернуть х * у
Корректность алгоритма обусловлена тем, что он инвариантен во время вычислений; это в начале; и это в конце.
Эти алгоритмы используют точно такое же количество операций, что и алгоритм предыдущего раздела, но умножения выполняются в другом порядке.
Краткий анализ показывает, что такой алгоритм использует возведение в квадрат и не более чем умножение, где обозначает функцию пола . Точнее, количество умножений на единицу меньше , чем количество единиц, присутствующих в двоичном представлении n . Для n больше примерно 4 это в вычислительном отношении более эффективно, чем наивное многократное умножение основания само на себя.
Каждое возведение в квадрат приводит примерно к удвоению количества цифр по сравнению с предыдущим, и поэтому, если умножение двух d -значных чисел реализуется за O( d k ) операций для некоторого фиксированного k , то сложность вычисления x n определяется выражением
Этот алгоритм вычисляет значение x n после расширения показателя степени по основанию 2 k . Впервые он был предложен Брауэром в 1939 году. В приведенном ниже алгоритме мы используем следующие функции f (0) = ( k , 0) и f ( m ) = ( s , u ), где m = u · 2 s с ты странный.
Алгоритм:
у := 1; i := l - 1 , пока i ≥ 0, делать (s, u) := f(n i ) for j := 1 до k - s do y := y 2 y := y * x u for j := 1 до s do y := y 2 я := я - 1вернуть y
Для оптимальной эффективности k должно быть наименьшим целым числом, удовлетворяющим [1]
Этот метод является эффективным вариантом 2 k -арного метода. Например, чтобы вычислить показатель степени 398, который имеет двоичное разложение (110 001 110) 2 , мы берем окно длиной 3 с помощью алгоритма 2 k -арного метода и вычисляем 1, x 3 , x 6 , x 12 , x 24 , х 48 , х 49 , х 98 , х 99 , х 198 , х 199 , х 398 . Но мы также можем вычислить 1, x 3 , x 6 , x 12 , x 24 , x 48 , x 96 , x 192 , x 199 , x 398 , что экономит одно умножение и эквивалентно вычислению (110 001 110) 2
Вот общий алгоритм:
Алгоритм:
Алгоритм:
у := 1; i := l - 1 while i > -1 делать if n i = 0 then y := y 2 ' i := i - 1 else s := max{i - k + 1, 0} в то время как n s = 0 do s := s + 1 [примечания 1] для h := 1 до i - s + 1 do y := y 2 u := (n i , n i-1 , ..., n s ) 2 y := y * x u я := с - 1вернуть y
Многие алгоритмы возведения в степень не обеспечивают защиту от атак по побочным каналам . А именно, злоумышленник, наблюдающий за последовательностью возведения в квадрат и умножения, может (частично) восстановить показатель степени, участвующий в вычислении. Это проблема, если показатель степени должен оставаться секретным, как во многих криптосистемах с открытым ключом . Эта проблема решается с помощью метода, называемого « лестница Монтгомери » [2] .
Учитывая двоичное разложение положительного, ненулевого целого числа n = ( n k −1 ... n 0 ) 2 с n k−1 = 1, мы можем вычислить x n следующим образом:
х 1 = х; x 2 = x 2 для i = k - 2 до 0 сделать , если n i = 0 , то x 2 = x 1 * x 2 ; Икс 1 = Икс 1 2 еще Икс 1 = Икс 1 * Икс 2 ; х 2 = х 2 2 вернуть х 1
Алгоритм выполняет фиксированную последовательность операций ( до log n ): умножение и возведение в квадрат происходит для каждого бита экспоненты, независимо от конкретного значения бита. Аналогичный алгоритм умножения на удвоение существует.
Эта конкретная реализация лестницы Монтгомери еще не защищена от атак по времени кэширования : злоумышленник все еще может наблюдать задержки доступа к памяти, поскольку доступ к различным переменным осуществляется в зависимости от значения битов секретного показателя степени. Современные криптографические реализации используют технику «разброса», чтобы гарантировать, что процессор всегда пропускает более быстрый кэш. [3]
Существует несколько методов, которые можно использовать для вычисления x n , когда основание фиксировано, а показатель степени меняется. Как можно видеть, предварительные вычисления играют ключевую роль в этих алгоритмах.
Метод Яо ортогонален 2 k -арному методу, где показатель степени разлагается по основанию b = 2 k , а вычисления выполняются так же, как в алгоритме выше. Пусть n , n i , b и b i — целые числа.
Пусть показатель степени n запишется как
где для всех .
Пусть Икс я = Икс б я .
Тогда алгоритм использует равенство
Учитывая элемент x из G и показатель степени n , записанный в приведенной выше форме, а также заранее вычисленные значения x b 0 ... x b w −1 , элемент x n вычисляется с использованием приведенного ниже алгоритма:
y = 1, u = 1, j = h - 1, в то время как j > 0 делать для i = 0 до w - 1 делать , если n i = j , то u = u × x b i у = у × ты j = j - 1вернуть y
Если мы установим h = 2 k и b i = h i , то значения n i будут просто цифрами n по основанию h . Метод Яо собирает в u сначала те xi , которые кажутся наивысшей степени ; в следующем раунде те, у кого есть мощность, также собираются в u и т. д. Переменная y умножается на начальную u , на следующую по величине степень и так далее. Алгоритм использует умножение, и элементы должны быть сохранены для вычисления x n . [1]
Евклидов метод был впервые представлен в книге «Эффективное возведение в степень с использованием предварительных вычислений и цепочек сложения векторов» П.Д. Руиджа.
Этот метод вычислений в группе G , где n — натуральное целое число, алгоритм которого приведен ниже, рекурсивно использует следующее равенство:
где . Другими словами, евклидово деление показателя n 1 на n 0 используется для получения частного q и остатка n 1 mod n 0 .
Учитывая базовый элемент x в группе G и показатель степени , записанный как в методе Яо, элемент рассчитывается с использованием заранее вычисленных значений , а затем алгоритма, приведенного ниже.
Начать цикл Найти , такой, что . Найдите , такой, что . Разорвите цикл, если . Пусть , и тогда пусть . Вычислите рекурсивно , а затем позвольте . Конец цикла ;Возвращаться .
Алгоритм сначала находит наибольшее значение среди n i , а затем верхнюю границу в наборе { n i \ i ≠ M } . Затем он возводит x M в степень q , умножает это значение на x N , а затем присваивает x N результат этого вычисления и n M значение n M по модулю n N.
Этот подход также работает с полугруппами , которые не имеют нулевой характеристики , например, позволяя быстро вычислять большие показатели степени по модулю числа. Особенно в криптографии полезно вычислять степени в кольце целых чисел по модулю q . Например, оценка
потребовалось бы очень много времени и много места для хранения, если бы использовался простой метод вычисления 13789 722341 и последующего получения остатка при делении на 2345. Даже использование более эффективного метода займет много времени: возведите в квадрат 13789, возьмите остаток от деления на 2345, умножьте результат на 13789 и так далее.
Применение описанного выше алгоритма exp-by-square , где "*" интерпретируется как x * y = xy mod 2345 (то есть умножение, за которым следует деление с остатком), приводит только к 27 умножениям и делениям целых чисел, которые все могут быть сохранены. в одном машинном слове. Как правило, любой из этих подходов требует менее 2log 2 (722340) ≤ 40 модульных умножений.
Этот подход также можно использовать для вычисления целочисленных степеней в группе , используя любое из правил:
Этот подход также работает в некоммутативных полугруппах и часто используется для вычисления степеней матриц .
В более общем смысле, этот подход работает с положительными целочисленными показателями в каждой магме , для которой бинарная операция является степенно-ассоциативной .
В некоторых вычислениях может быть более эффективно разрешить отрицательные коэффициенты и, следовательно, использовать обратную базу, при условии, что инверсия в G является «быстрой» или была предварительно вычислена. Например, при вычислении x 2 k -1 бинарный метод требует k -1 умножений и k -1 возведения в квадрат. Однако можно выполнить k возведений в квадрат, чтобы получить x 2 k , а затем умножить на x −1 и получить x 2 k −1 .
С этой целью мы определяем знаковое представление целого числа n в системе счисления b как
Знаковое двоичное представление соответствует конкретному выбору b = 2 и . Это обозначается . Существует несколько методов вычисления этого представления. Представление не уникально. Например, возьмем n = 478 : два различных знаково-двоичных представления задаются как и , где используется для обозначения −1 . Поскольку бинарный метод вычисляет умножение для каждой ненулевой записи в представлении n по основанию 2 , мы заинтересованы в поиске знаково-двоичного представления с наименьшим количеством ненулевых записей, то есть с минимальным числом Хэмминга . масса . Один из способов сделать это — вычислить представление в несмежной форме , или сокращенно NAF, которое удовлетворяет условиям и обозначается . Например, представление числа 478 в NAF равно . Это представление всегда имеет минимальный вес Хэмминга. Простой алгоритм вычисления представления NAF заданного целого числа следующий :
для i = 0 до l - 1 верните
Другой алгоритм Коямы и Цуруока не требует условия, что ; он по-прежнему минимизирует вес Хэмминга.
Возведение в степень путем возведения в степень можно рассматривать как неоптимальный алгоритм возведения в степень с помощью цепочки сложения : он вычисляет показатель с помощью цепочки сложения , состоящей из повторяющихся удвоений показателя (возведения в квадрат) и/или увеличения показателя степени только на единицу (умножения на x ). В более общем смысле, если кто-то позволяет суммировать любые ранее вычисленные показатели степени (путем умножения этих степеней x ), иногда можно выполнить возведение в степень, используя меньшее количество умножений (но обычно используя больше памяти). Наименьшая степень, при которой это происходит, соответствует n = 15:
В общем, поиск оптимальной цепочки сложения для заданного показателя степени является сложной задачей, для которой не известны эффективные алгоритмы, поэтому оптимальные цепочки обычно используются только для малых показателей степени (например, в компиляторах , где цепочки для малых степеней предварительно сведены в таблицы). ). Однако существует ряд эвристических алгоритмов, которые, хотя и не являются оптимальными, имеют меньше умножений, чем возведение в степень путем возведения в квадрат, за счет дополнительной бухгалтерской работы и использования памяти. Несмотря на это, количество умножений никогда не растет медленнее, чем Θ (log n ), поэтому эти алгоритмы асимптотически улучшаются при возведении в степень за счет возведения в квадрат в лучшем случае только с постоянным коэффициентом.