tsujimotterのノートブック

日曜数学者 tsujimotter の「趣味で数学」実践ノート

RSA 暗号がようやく分かった気がしたのでまとめてみる

「RSA 暗号」を知ったのは私が大学の3年生の頃だったかと思います。学科の必修として「危機管理工学」という名の講義があって、そこで暗号理論を学んだのです。当時は、たいして数学を勉強していなかったこともあって、単位は習得したものの「なんだかよくわからないなあ」と苦手意識があったのを覚えています。

最近、RSA 暗号について知人から質問をされる機会があり、せっかくなので久しぶりに調べ直してみたのです。

するとどうでしょう。すらすら理解できる。これは驚きました。おそらく、最近「素数と2次体の整数論」を学ぶ過程で、初等整数論の基礎が身についてきたからでしょうか。「RSA暗号」はまさに初等整数論に立脚していますからね。基礎は大事なのだと言うことを改めて痛感しました。

「分かった!」という感覚を忘れないようにと考えて、現状の私の理解をまとめてみようと思います。残念ながら、まだ噛み砕いて説明できるまでには至って居ませんので、少なくとも初等整数論を一通り勉強した方向けに書いてみたいと思っています。そのため、まったくの初学者にはわかりづらいかも。「そんな文章、どこにニーズがあるのか」と思うかもしれませんが・・・。再確認のために使っていただければと思います。

それではいきましょう。

RSA 暗号の目的

暗号化したい元の文章(これを平文といいます)があって、それに暗号化を施して別の文章(これを暗号文といいます)を作ります。RSA暗号の目的は「暗号文から平文を得るための復号方法を求めること」に他なりません。「何を当たり前のことを」と思うかもしれませんが、これを忘れるとよくわからなくなります。


今述べたことを、整数論の言葉で表現し直すとこうなります。

平文を  P ,暗号文を  C とします。暗号鍵を  k,公開鍵を  m としたとき、平文  P から暗号文  C を得る操作(これを「暗号化 encryption」といいましょう)を、合同式によって次のように表します。

 P^k \equiv C \pmod m \tag{1}

逆に、復号鍵  u (ただし、 u>0) が存在して、暗号文  C から平文  P を得る操作(これを「復号化 decryption」と呼びます)が可能であると仮定すると、そのような復号化は次のように表せます。

 C^u \equiv P \pmod m \tag{2}

ここで、(1) を (2) に代入して、暗号文  C を消去すると、

 (P^k)^u \equiv P \pmod m \tag{3}
が得られます。

このとき、任意の  P に対して、(3) 式を満たすような、都合の良い  u を見つけることができれば、鍵  u を知っている人が暗号文を復号化できます。これこそが RSA 暗号の目的なのです。


RSA 暗号においては、ここで使った公開鍵  m は、素数  p, q を用いて

 m = pq
のように計算されるということを覚えておいてください。あとで登場します。

またRSA暗号は、「公開鍵暗号」と呼ばれる暗号方式ですが、 k, m は誰にでも分かるように公開してしまいます。ただし、 m を作るときに使った  p, q は誰にも公開してはいけません。これもポイントです。


ここで3点疑問が現れます。

  • そんな都合の良い「復号鍵  u」が存在するのか?
  • そのような「復号鍵  u」は「秘密鍵  p, q」から計算可能なのか?
  •  u が計算可能だとして、もし「復号鍵  u」が「公開鍵  k m」から計算できてしまえば、暗号文が他人に復号化されてしまうけれども、その心配はないのか

1つめの疑問は、すべての暗号における共通の疑問です。復号鍵  u が存在しないと、復号化ができないので、そもそも暗号として成立していません。

2つめの疑問も同様。復号鍵  u が計算できなければ、暗号化された情報を誰も復号できないことになります。これでは暗号化しても仕方ありません。

3つめの疑問は、暗号の安全性についての疑問ですね。公開鍵暗号方式、固有の問題です。今回の場合、暗号化においても復号化においても、鍵  k m を用います。つまり、暗号化する側に鍵を渡さないといけないわけです。もし、秘密鍵暗号方式であれば、特に問題にはならないでしょう。つまり、暗号文を送ってもらう相手だけに、こっそりと秘密の  k,  m を渡してしまえば、それらが他人にばれない限り暗号は解読されませんから。しかしながら、今回の RSA 暗号は、公開鍵暗号方式です。この方式では  k m を、誰にも分かるような方法で公開してしまうので、誰でも暗号化できます。一方で、もしも  k m から復号鍵  u が簡単にばれてしまうようなことがあっては、暗号化の意味がありません。そんなことができないような工夫が必要です。


というわけで、以降では順番にこの問題を解決していきましょう。まずは、1つめの復号鍵  u が存在するか、という問題から。

1. 復号鍵  u > 0 は存在するか?

(3) 式を再掲しましょう。

 (P^k)^u \equiv P \pmod m \tag{3}

この式の左辺をちょちょっと、計算しましょう。

 P^{k\cdot u} \equiv P \pmod m


ここで問題となるのは、べき乗して余りをとると「都合良く」元の形に戻るような、そんな  k\cdot u が存在するのか、ということですね。

それがなんと存在するんですよ、奥さん!
オイラーの定理の出番です。

オイラーの定理は、いわゆる初等整数論の代表的な成果ですが、以下ような定理です。

定理:オイラーの定理
正整数  a, m に対して, a, m が互いに素であるとき,以下が成り立つ.
 a^{\varphi(m)} \equiv 1 \pmod m \tag{4}

ただし, \varphi(m)オイラー関数を表す.


ここでオイラー関数  \varphi(m) という関数が出てきました。知らない方のために説明すると、オイラー関数  \varphi(m) は「 m より小さい正の整数のうち, m と互いに素な数の個数」を表す関数です。

たとえば、 m=10 を考えると、 10 と互いに素な  10 より小さい数は、 \{1, 3, 7, 9\} 4 個なので、 \varphi(10) = 4 となります。

一方で、たとえば  m が素数  p であれば、 p と互いに素な  p より小さい数は、 \{1, \ldots, p-1\} p-1 個なので、 \varphi(p) = p-1 です。したがって、上に述べたオイラーの定理は、このブログでよく登場する「フェルマーの小定理」の拡張版になっています。もし、 m が素数  p であれば、そのオイラー関数は  \varphi(p) = p-1 より、 a^{p-1} \equiv 1 \pmod p が成り立つわけです。


「オイラーの定理」については、tsujimotter の旧ブログのこちらの記事も参考になります:
オイラーの定理を導くまで



さてここで、オイラーの定理の式 (4) の  a P を代入した後、さらに両辺を  v 乗します。ただし  v は整数です。

 P^{\varphi(m) \cdot v} \equiv 1 \pmod m

この式の両辺に  P をかけましょう。

 P^{\varphi(m) \cdot v+1} \equiv P \pmod m \tag{5}

するとどうでしょう。式 (3') と全く同じ形になりましたね。同じ式の形になっていますので、左辺の指数を比較しましょう。すると、

 k\cdot u = \varphi(m)\cdot v + 1 \tag{6}

となります。すなわち、式 (6) を満たすような、整数  u, v が存在して  u > 0 であれば、暗号文  P^k は復号できる、というわけですね。


「そんな都合良く  u, v はいつでも存在するのか」と思うわけです。ここでは、整数論を勉強していると必ず出てくる、以下のようなロジックを使うのですが、その前にちょっとだけ式 (6) を変形します。

 k\cdot u - \varphi(m)\cdot v = 1 \tag{6'}

移項しただけですね。しかしこうすることで、次のような定理に見えてきます。


定理:一次不定方程式の整数解
 a, b を互いに素な整数としたとき,以下の方程式を満たすような整数解  u, v が存在する.

 au + bv = 1


 a = k,  b = \varphi(m) とおいて、 -v \to v とすれば、完全に同じ式ですね。同じ式に見せるために、わざわざ  u, v を使っていたわけです。

ここで、もし  a, b が互いに素、すなわち、 k, \varphi(m) が互いに素であるならば、定理より整数  u, v が存在します。もちろん、暗号鍵  k は適当に選んだ数なので、 \varphi(m) と互いに素になるようにうまく選べば良いわけですから、整数  u, v は必ず存在することが保証されました。


これで復号鍵  u が存在することが示せました!やったー!

・・・と言いたいところですが、まだ十分ではありません。


一次不定方程式の整数解  u, v は存在することは示せました。が、しかし、まだ整数であって、正の整数とは限らない。つまり、 u \leq 0 である可能性があるわけです。どうにかして、 u > 0 となるような整数解  u, v の組を求める方法はないのだろうか。その方法はもちろんあります。


こう考えればよいです。たとえば、整数解  u_0, v_0 が見つかったとします。ただし、 u_0 \leq 0 とします。これは、一次不定方程式  au + bv = 1 を満たしますから、

 au_0 + bv_0 = 1

この式が成り立っているとすると、整数  k を用いて、以下の式も成り立ちます。

 a(u_0 + bk) + b(v_0 - ak) = 1

展開するとわかりますが、 abk がプラスマイナスで打ち消し合って消えると、上の式が成立します。

よく見ると、この  (u_0 + bk), (v_0 - ak) も、 au+bv=1 の解になっていることがわかります。ここで  k を適切に選べば、 (u_0 + bk) > 0 にすることが可能ですね。したがって、 u > 0 となるような、 au+bv=1 を満たす整数解  u, v が必ず存在することを示せました。

長かったですが、これにて復号鍵  u の存在が証明できました。

2. 復号鍵  u は計算可能か?

存在は示せましたが、じゃあ計算は可能なのか、という疑問に答えていきましょう。

結局、1. の議論から、式 (6') を満たすような整数解  u, v を求める方法はあるのか、という問題です。ここでは、 u の符号にはこだわらないで、単に整数解を求める方法で十分です。

この問題は、ユークリッドの互除法で解決です。ユークリッドの互除法による一次不定方程式の解法は、わざわざここで解説せずとも、いろんなところで解説がありますので、そちらに投げましょう。(単に解説するのが面倒なだけですが・・・。)

とにかく、ここでは  k \varphi(m) さえ分かれば、整数解  u, v を求める方法が存在することが言えました。整数解さえ求まれば、1. の方法を使って  u を正にすることは容易です。

3. 他人に復号されてしまわないのか?

最後は RSA 暗号の安全性の話です。

RSA 暗号は冒頭で述べた通り「公開鍵暗号方式」なので、 k,  m は公開されています。ここで、もし  \varphi(m) が計算できてしまえば、 k が分かっているわけですから、2. の方法により即座に復号鍵  u が求まってしまいます。

もちろん、鍵を公開した本人であれば、復号化できるのはよいことですが、誰もが復号できてしまったらまずいです。そこで結局、鍵を公開した本人だけが  \varphi(m) を計算できるようなトリックが必要になります。果たしてそんなことは可能なのか。

鍵を公開した本人が、それ以外の人と違う点はどこでしょう。それは、 p, q を知っていることです。

ポイントになるのは、オイラー関数は、 p, q を知らないと計算できないという点です。冒頭で述べた通り  m が素数  p, q を使って、 m = pq で表されます。このとき、オイラー関数  \varphi(m) は、次のように計算できます。

 \varphi(m) = (p-1)(q-1) \tag{7}

右辺が  p, q を使った積で得られることに注目してください。


結局、復号鍵  u を得るためには、オイラー関数  \varphi(m) の計算が必要です。一方で、オイラー関数  \varphi(m) を計算するためには、あらかじめ  p, q を知っているか、 m を素因数分解する必要があります。素因数分解を経ないで  m から直接  \varphi(m) を計算する方法はありません。

ここで、鍵を作った本人とそれ以外の人に、奇妙な非対称性が生まれます。すなわち、鍵を作った本人は  p, q を知っているので復号鍵を作成可能、そうでない人は  m を素因数分解できない限り復号鍵を作成できないのです。


これによって、RSA 暗号の安全性が素因数分解と結びつきました。

素因数  p, q があらかじめ分かっていて、そこから  m を計算する処理は積1回で可能ですが、逆に  m を素因数分解するような効率的な方法は存在しません。十分大きな桁数の  p, q を用いて、公開鍵  m を生成すれば、現存するどんなコンピュータを用いたとしても  m の素因数分解は困難となります。

したがって、公開鍵を生成した  p, q を漏らさなければ、その鍵を元にした暗号は安全である、といえるわけです。


結局以上をまとめるとこの図のようになります。

f:id:tsujimotter:20150118111251j:plain:w400

まとめ

今回の記事では、初等整数論の言葉を使って RSA 暗号についてまとめてみました。
結局、以下の点がポイントでしたね。

  •  m でべき乗したときに任意の  P が元に戻ってくるような「都合のいい指数  k\cdot u」が存在し、計算できる
  • 「都合のいい指数」の計算には、オイラー関数  \varphi(m) の計算が必要だが、これには  m の素因数分解  p, q が不可欠

ここに至るまでに「合同式」「オイラーの定理」「一次不定方程式の整数解」「ユークリッドの互除法」「オイラー関数」と、初等整数論の基本的な内容が1通り登場しましたね。やはり基礎は大事だなと実感しました。

逆に、整数論の基礎的な部分を押さえないで、表面的な説明をしたところで、私の学部3年の頃のように「分かったような分かっていないような」な感じになってしまうのでは、と思いました。

RSA暗号に限らず、世の中にはこういった「分かった気にさせる」解説が多々存在しますが、そのような解説の功罪を考えずにはいられません。


2015/01/20 追記:
練習問題作りました!

RSA暗号からの脱出 - tsujimotterのノートブック


2015/01/20 さらに追記:
オイラー関数が合成数の場合についての参考記事を書きました!

オイラー関数についての補足 - tsujimotterのノートブック


2015/01/21 またまた追記:
一次不定方程式の理解のための補足記事を書きました!

一次不定方程式と油分け算 - tsujimotterのノートブック

参考サイト

上でいろいろ文句を言ったばかりですが、そのようなサイトの中でも、こちらは特に丁寧に説明してくれている「よい解説サイト」です。tsujimotter の話はよくわからん、という方はまずはこちらをご覧になることをおすすめします。

はじめに | サルにも分かるRSA暗号