アルゴリズム論特論(塩田)第8回 (3) 高速べき乗

前へ / 戻る / 次へ $\newcommand{\ol}[1]{\overline{#1}}$ $\newcommand{\znz}[1]{\mathbb{Z}/#1 \mathbb{Z}}$ $\newcommand{\znzc}[1]{(\mathbb{Z}/#1 \mathbb{Z})^{\times}}$ $\newcommand{\inv}[1]{\displaystyle{\frac{1}{#1}}}$

高速べき乗

 第3回で注意したように、 宇宙の年齢がおよそ 138億年 ≒ $4.35×10^{17}$ 秒であることに比べて、 2048 ビットの整数は $10^{600}$ 以上というとてつもなく巨大な数です。 そのような数に対して RSA 暗号では $x^e\, \%\, n$ を計算しなければなりません。
  1. Python なら x ** e % n と書く式ですが、 x ** e はおよそ $2048 \times 2^{2048}$ ビットの数なので、そもそもメモリに入りません。 ( 1TiB はたった $2^{43}$ ビット )
  2. 必要なのは $n$ で割った余りなので「 $x$ 倍して $\%\,n$ する」計算を $e$ 回繰り返せばメモリの問題は解決します。 しかし、反復回数 $e$ が巨大なので、これも現実的ではありません( 計算量としては $O(n\log^2 n)$ )。
 ところが、うまい手を考える人はいるもので
アイデア(反復2乗法) $163^{91} \,\%\, 307$ で説明しましょう。
  1. べき指数 $91$ を 2 べきの和として表します。
    $91=(1011011)_2$ $\Rightarrow$ $91=64+16+8+2+1$
  2. $x^2 % 307$ を繰り返して $163^{64}\,\%\,307$ まで計算します。
    $\begin{array}{lll} 163^2\,\%\,307 &&= 167 \\ 167^2\,\%\,307 &(\ = 163^4\,\%\,307\ ) &= 259 \\ 259^2\,\%\,307 &(\ = 163^8\,\%\,307\ ) &= 155 \\ 155^2\,\%\,307 &(\ = 163^{16}\,\%\,307\ ) &= 79 \\ 79^2\,\%\,307 &(\ = 163^{32}\,\%\,307\ ) &= 101 \\ 101^2\,\%\,307 &(\ = 163^{64}\,\%\,307\ ) &= 70 \\ \end{array} $
  3. 1° , 2° を組み合わせて \begin{align} 163^{91}\,\%\,307 &= 163^{64+16+8+2+1}\,\%\,307 \\ &= (163^{64} \times 163^{16} \times 163^{8} \times 163^{2} \times 163^{1})\,\%\,307 \\ &= (70 \times 79 \times 155 \times 167 \times 163)\,\%\,307 \\ &= 2 \\ \end{align}
Th.7 $x$, $e$ が $n$ と同じくらいのビット数であれば、 反復2乗法を用いた $x^e\,\%\, n$ の計算量は $O(\log^3 n)$.
証明 1° は $e$ の2進数表示を使うだけ。 2° , 3° はいずれも、乗算と除算を最大で ( $e$ のビット長 ) 回繰り返すので、 計算量は $O(\log e) \times O(\log^2 n)=O(\log^3 n)$. (証明終)

 Python 風に書けば、こんなにも簡単です:
Algorithm 8 (反復2乗法)
  • 入力:$x$, $e$, $n$
  • 出力:$x^e\,\%\,n$
def modpow(x, e, n):
    y = 1 
    while e > 0:
        if e % 2 == 1:
            y = (y * x) % n
        x = (x * x) % n
        e //= 2
    return y
Rem.9
  • Python には高速べき乗法が組み込まれていて、 pow(x, e, n) と書けば高速に $x^e\,\%\,n$ を計算してくれます。 ただし math モジュール内の pow は double 型対象で引数を 2 個しか取りませんので
    from math import *
    と書くとエラーを起こします。
  • $x^e\,\%\,n$ の計算は他にも、 素数判定・素数生成の確率的アルゴリズムや、 Th.5 (3) ⇒ (1) のアルゴリズム等、 色んな所で使われます。