HTTPS で Web サイトを開くと、裏側では楕円曲線暗号(ECC:Elliptic Curve Cryptography)が動いています。TLS 1.3 の鍵交換、サーバ証明書の署名、SSH の鍵、IPsec の DH グループ 19 や 20 など、インフラの設定でもよく目にする名前です。
この記事では、中学〜高校初級の数学(代入、2乗と3乗、割り算の余り)だけを使って、楕円曲線暗号の仕組みを順番にたどります。それより先の数学が必要なところは、計算に深入りせず「こういうものです」と割り切って、図とイメージで説明します。
鍵を安全に受け渡す仕組み(DH 鍵交換)は Diffie-Hellman 鍵交換をイメージで解説、公開鍵と署名の全体像は 公開鍵暗号、認証局、デジタル署名をイメージで解説 で説明しています。この記事は、その DH や署名の「中身の計算」を楕円曲線に置き換えたものです。
- 楕円曲線とはどんな式で、どんな形をしているのか
- 曲線の上の「点の足し算」と、同じ点を何回も足す計算
- 「足すのは速いが、何回足したかは当てられない」ことが安全性の土台になっていること
- 鍵交換(ECDH)と署名(ECDSA・EdDSA)での使われ方と、RSA との違い
公開鍵暗号は「片道だけ簡単な計算」でできている
公開鍵暗号や DH 鍵交換は、「一方向には簡単に計算できるのに、逆向きにたどるのはとても難しい」計算を土台にしています。
たとえば RSA 暗号は、掛け算と素因数分解を使います。37 × 53 = 1961 は筆算ですぐに出ますが、「1961 はどの2つの数の掛け算か」と聞かれると、小さい数から順に割ってみるしかありません。RSA ではこの数が 2048 ビット(10 進数で約 617 桁)もあるので、逆向きの計算が現実的な時間では終わりません。
楕円曲線暗号も考え方は同じで、使う計算が違います。素数の掛け算の代わりに、「曲線の上の点の足し算」を使います。ここからは、その曲線と足し算を順に見ていきます。
楕円曲線とは
暗号で使う楕円曲線は、次の形の式で表される曲線です。
楕円曲線の式
y² = x³ + ax + b (a と b は決まった数)
左辺は y の2乗(y × y)、右辺は x の3乗(x × x × x)に「x の a 倍」と「b」を足したものです。a と b に具体的な数を入れると、1本の曲線が決まります。ここでは計算しやすいように、a = −1、b = 1 の曲線を例にします。
例に使う曲線
y² = x³ − x + 1
x に数を入れて、曲線の上の点を探す
x にいくつか数を入れて、右辺を計算してみます。右辺の値が y² なので、「2乗してその値になる数」が y です。
| x | 右辺 x³ − x + 1 の計算 | y(2乗すると右辺になる数) |
|---|---|---|
| −1 | (−1)³ − (−1) + 1 = −1 + 1 + 1 = 1 | 1 と −1 |
| 0 | 0 − 0 + 1 = 1 | 1 と −1 |
| 1 | 1 − 1 + 1 = 1 | 1 と −1 |
| 2 | 8 − 2 + 1 = 7 | √7 と −√7(約 2.65 と −2.65) |
| 3 | 27 − 3 + 1 = 25 | 5 と −5 |
| 5 | 125 − 5 + 1 = 121 | 11 と −11 |
たとえば x = 3 のとき右辺は 25 で、2乗して 25 になる数は 5 と −5 の2つです。そのため、(3, 5) と (3, −5) の2点が曲線の上にあります。
正の数も負の数も、2乗すると同じ値になります。そのため y と −y は必ずセットで出てきて、グラフは x 軸を境に上下対称になります。この性質は、次の「点の足し算」で使います。
「楕円」という名前ですが、形は楕円(だ円)ではありません。楕円の周の長さを求める研究の中でこの形の式が出てきたことから、この名前が付いています。
また、暗号で使う曲線は、とがった点や自分自身と交わる点がないものに限られます(a と b に条件があります)。ここでは「なめらかな曲線を使う」とだけ押さえておけば十分です。
曲線の上の「点の足し算」
楕円曲線暗号のいちばんの特徴は、曲線の上の2つの点から、同じ曲線の上にある3つ目の点を作る「足し算」が決められていることです。数の足し算とは違い、図形を使って次の3ステップで求めます。
2つの点を直線で結ぶ
曲線の上の点 P と点 Q を通る直線を引きます。ここでは、先ほどの表にある P = (0, −1) と Q = (3, 5) を例にします。
2点を通る直線の式は、中学2年の一次関数で求められます。傾きは (5 − (−1)) ÷ (3 − 0) = 2、x = 0 のとき y = −1 なので、直線は y = 2x − 1 です。
直線と曲線が交わる3つ目の点を探す
3乗の式で表される曲線と直線は、ふつう3か所で交わります。P と Q 以外の交点を R とします。
この例では、直線の式 y = 2x − 1 に x = 1 を入れると y = 1 になり、表の (1, 1) と一致します。つまり (1, 1) は直線の上にも曲線の上にもある点で、これが3つ目の交点 R です。
R を上下にひっくり返す
R の y の符号を変えた点(x 軸について反対側の点)を、P + Q の答えにします。曲線は上下対称なので、この点も必ず曲線の上にあります。この例では、R = (1, 1) をひっくり返して P + Q = (1, −1) です。
最後にひっくり返すのは、そう決めておくと「足す順番を入れ替えても答えが同じ」など、足し算らしい性質が成り立つからです。その証明は高校の範囲を超えるので、ここでは「そういうルール」として進めます。
式で確かめる:(−1, 1) + (0, 1)
もう1つ、P = (−1, 1)、Q = (0, 1) の場合を式で計算してみます。2つの点は y がどちらも 1 なので、P と Q を通る直線は y = 1 の横一直線です。曲線の式に y = 1 を代入すると、交点の x がわかります。
計算
y² = x³ − x + 1 ← y = 1 を代入する 1 = x³ − x + 1 0 = x³ − x ← 両辺から 1 を引く 0 = x(x + 1)(x − 1) ← 因数分解 x = 0, −1, 1
x = −1 が P、x = 0 が Q なので、残りの x = 1 が3つ目の交点 R = (1, 1) です。これを上下にひっくり返して、P + Q = (1, −1) になります(図5)。
因数分解がわからなくても、先ほどの表を見れば、x = −1、0、1 のどれも右辺が 1 になる(y = 1 の直線と交わる)ことを確かめられます。
同じ点どうしを足す(2倍)
P + P のように同じ点を足すときは、2点を結ぶ直線が引けません。この場合は、P で曲線に接する直線(接線)を引き、あとは同じように3つ目の交点を探してひっくり返します。
接線の傾きを求めるには「微分」という高校2年以降の内容が必要なので、ここでは結果だけを使います。P = (1, 1) での接線は y = x です。これを曲線の式に代入すると x² = x³ − x + 1 になり、x = −1 のとき左辺も右辺も 1 になるので、(−1, −1) が3つ目の交点です。ひっくり返して、2P = (−1, 1) になります(図6)。
同じ点を何回も足す(スカラー倍)
点 P を k 回足した点を kP と書きます(2P、3P、4P …)。k は普通の整数で、この計算を「スカラー倍」と呼びます。楕円曲線暗号で実際に使うのは、このスカラー倍です。
何回も足すといっても、1回ずつ足す必要はありません。「2倍」を繰り返すと、少ない回数で大きな倍数に届きます。たとえば 100P は、次のように8回の計算で求められます。
100 = 64 + 32 + 4 なので、2倍を6回繰り返して 64P まで作り、途中で作った 32P と 4P を足せば 100P になります。1回ずつ足すと99回かかる計算が、8回で済みます。
実際の暗号では k に 256 ビット(10 進数で約 78 桁)の数を使いますが、この方法なら2倍と足し算を合わせても多くて 500 回程度です。コンピュータなら一瞬で終わります。
実際の暗号は「時計の世界」で計算する
ここまでは普通の数(実数)で計算してきました。ただ、このまま足し算を続けると、数がすぐに扱いにくくなります。(0, 1) を何回か足すと、次のようになります。
| 点 | 座標 |
|---|---|
| P | (0, 1) |
| 2P | (1/4, −7/8) |
| 3P | (56, 419) |
| 4P | (−223/784, 24655/21952) |
分数になったり急に大きな数になったりして、桁数がどんどん増えていきます。これではコンピュータで正確に計算し続けるのも大変です。
そこで実際の暗号では、「ある数で割った余り」だけを使って計算します。時計と同じ考え方です。時計では 12 時の次は 13 時ではなく 1 時に戻ります。13 を 12 で割った余りが 1 だからです。割る数には素数を使い、実際によく使われる P-256 という曲線では約 78 桁の素数で割った余りを使います。
「17 で割った余りの世界」は、目盛りが 0〜16 の 17 個ある時計だと考えるとイメージしやすくなります。どんなに大きな数も、この時計の上では 0〜16 のどこかの目盛りに止まります。たとえば 137 は、17 ずつ 8 周して 1 の目盛りで止まります。
ここからは、この「17 の時計」の上で楕円曲線を考えます。例として、次の式を使います。先ほどとは別の曲線ですが、考え方は同じです。
17 の時計の上で考える曲線
y² = x³ + 2x + 2
普通の数では、左辺と右辺がぴったり同じになる (x, y) が曲線の上の点でした。17 の時計の世界では、ルールが次の2つに変わります。
| ルール | 普通の数 | 17 の時計の世界 |
|---|---|---|
| x と y に使える数 | どんな数でもよい(小数や分数も) | 0〜16 の整数だけ(時計の 17 個の目盛り) |
| 曲線の上にある条件 | 左辺と右辺がぴったり同じ | 左辺と右辺を 17 で割った余りが同じ(時計の同じ目盛りに止まる) |
x も y も 17 通りしかないので、曲線の上の点はすべて数え上げられます。次の3ステップで探します。
左辺 y² の余りを表にする
y = 0〜16 について y² を計算し、17 で割った余りを出します。たとえば y = 6 なら 6² = 36 で、36 ÷ 17 = 2 余り 2 なので、余りは 2 です。
| y | y² | 17 で割った余り | y | y² | 17 で割った余り |
|---|---|---|---|---|---|
| 0 | 0 | 0 | 9 | 81 | 13 |
| 1 | 1 | 1 | 10 | 100 | 15 |
| 2 | 4 | 4 | 11 | 121 | 2 |
| 3 | 9 | 9 | 12 | 144 | 8 |
| 4 | 16 | 16 | 13 | 169 | 16 |
| 5 | 25 | 8 | 14 | 196 | 9 |
| 6 | 36 | 2 | 15 | 225 | 4 |
| 7 | 49 | 15 | 16 | 256 | 1 |
| 8 | 64 | 13 |
表を見ると、余りは 0、1、2、4、8、9、13、15、16 のどれかしか出てきません。また、y = 1 と y = 16、y = 6 と y = 11 のように、足して 17 になる2つの y は同じ余りになります。これは、普通の数で「y と −y は2乗すると同じ」になるのと同じ性質です。
右辺 x³ + 2x + 2 の余りを計算して、同じ余りの y を探す
次に、x = 0〜16 について右辺を計算し、17 で割った余りを出します。その余りが STEP 1 の表に出てくれば、その y と組み合わせた点が曲線の上の点です。
たとえば x = 5 なら、右辺は 125 + 10 + 2 = 137 で、137 ÷ 17 = 8 余り 1 です(図8の右の時計で 1 に止まる数です)。STEP 1 の表で余りが 1 になるのは y = 1 と y = 16 なので、(5, 1) と (5, 16) が曲線の上の点です。これを x = 0〜16 のすべてで行ったのが次の表です。
| x | 右辺 x³ + 2x + 2 | ÷ 17 | 余りが同じになる y | 曲線の上の点 |
|---|---|---|---|---|
| 0 | 0 + 0 + 2 = 2 | 0 余り 2 | 6、11 | (0, 6)、(0, 11) |
| 1 | 1 + 2 + 2 = 5 | 0 余り 5 | なし | ― |
| 2 | 8 + 4 + 2 = 14 | 0 余り 14 | なし | ― |
| 3 | 27 + 6 + 2 = 35 | 2 余り 1 | 1、16 | (3, 1)、(3, 16) |
| 4 | 64 + 8 + 2 = 74 | 4 余り 6 | なし | ― |
| 5 | 125 + 10 + 2 = 137 | 8 余り 1 | 1、16 | (5, 1)、(5, 16) |
| 6 | 216 + 12 + 2 = 230 | 13 余り 9 | 3、14 | (6, 3)、(6, 14) |
| 7 | 343 + 14 + 2 = 359 | 21 余り 2 | 6、11 | (7, 6)、(7, 11) |
| 8 | 512 + 16 + 2 = 530 | 31 余り 3 | なし | ― |
| 9 | 729 + 18 + 2 = 749 | 44 余り 1 | 1、16 | (9, 1)、(9, 16) |
| 10 | 1000 + 20 + 2 = 1022 | 60 余り 2 | 6、11 | (10, 6)、(10, 11) |
| 11 | 1331 + 22 + 2 = 1355 | 79 余り 12 | なし | ― |
| 12 | 1728 + 24 + 2 = 1754 | 103 余り 3 | なし | ― |
| 13 | 2197 + 26 + 2 = 2225 | 130 余り 15 | 7、10 | (13, 7)、(13, 10) |
| 14 | 2744 + 28 + 2 = 2774 | 163 余り 3 | なし | ― |
| 15 | 3375 + 30 + 2 = 3407 | 200 余り 7 | なし | ― |
| 16 | 4096 + 32 + 2 = 4130 | 242 余り 16 | 4、13 | (16, 4)、(16, 13) |
x = 1 のように、右辺の余り(5)が STEP 1 の表に出てこない x では、y が見つからないので点がありません。見つかった点は全部で 18 個です。
見つかった点をマス目に打つ
18 個の点を、横を x、縦を y として 0〜16 のマス目に打ったのが図9の右です。同じ式でも、余りの世界ではグラフが1本の線にならず、マス目の上に点が散らばった形になります。
STEP 1 で見た「y と 17 − y は同じ余り」の性質から、点は y = 8.5 の線をはさんで上下のペアになります。(5, 1) と (5, 16) がその例です。普通の数のときの「x 軸について上下対称」が、余りの世界ではこういう形で残っています。
点の足し算を式にする
余りの世界では曲線が点の集まりなので、定規で直線を引いて交点を探すことはできません。そこで、「点の足し算」の章で図2〜図4に描いた作図(直線を引く → 3つ目の交点を探す → ひっくり返す)を、計算の手順に置き換えます。
点の足し算の式(点 (x1, y1) + 点 (x2, y2) = 点 (x3, y3))
① 傾き λ(ラムダ)を求める
違う2点:λ = (y2 − y1) ÷ (x2 − x1)
同じ点 :λ = (3 × x1² + a) ÷ (2 × y1) ← 接線の傾き。a は式の x の係数
② 答えの x:x3 = λ² − x1 − x2
③ 答えの y:y3 = λ × (x1 − x3) − y1
①の「違う2点」は、中学2年の一次関数で習う「傾き = y の増えた量 ÷ x の増えた量」と同じです。②と③は「3つ目の交点を探して、ひっくり返す」を式にしたものです。同じ点のときの傾きの式と、②③の導き方は高校以上の内容なので、ここでは「こういう式」として使います。
この式で本当に作図と同じ答えになるか、図2〜図4 で使った P = (0, −1)、Q = (3, 5) で確かめます。
普通の数で確かめる:(0, −1) + (3, 5)
① λ = (5 − (−1)) ÷ (3 − 0) = 6 ÷ 3 = 2 ← 図2 の直線 y = 2x − 1 の傾き ② x3 = 2² − 0 − 3 = 4 − 3 = 1 ③ y3 = 2 × (0 − 1) − (−1) = −2 + 1 = −1 → P + Q = (1, −1) ← 図4 と同じ答え
余りの世界で計算するときの2つの約束
17 の時計の世界でこの式を使うときは、計算のたびに 17 で割った余りに直して、答えを 0〜16 に収めます。そのとき気を付けるのは、次の2つです。
| 場面 | どうするか | 例 |
|---|---|---|
| 負の数 | 17 を足して 0〜16 に戻す(時計の針を逆向きに回すのと同じ) | −14 → −14 + 17 = 3 |
| 割り算 | 「掛けると余りが 1 になる数」を掛ける | 2 × 9 = 18 は 17 で割ると余り 1 なので、「÷ 2」の代わりに「× 9」 |
余りの世界には分数がないので、割り算は掛け算に置き換えます。17 の時計では 2 × 9 = 18 が「1 周して 1」になるので、9 が「2 の逆数」の役目をします。普通の数で 2 × ½ = 1 になるのと同じ関係です。
出発点 G から 2G、3G、4G を計算する
表にある (5, 1) を出発点 G にして、G を順に足していきます。式の a は、y² = x³ + 2x + 2 の x の係数なので 2 です。
2G = G + G(同じ点なので、①は接線の傾きの式)
① λ = (3 × 5² + 2) ÷ (2 × 1) = 77 ÷ 2
= 9 ÷ 2 ← 77 ÷ 17 = 4 余り 9
= 9 × 9 = 81 ← 「÷ 2」は「× 9」
→ 13 ← 81 ÷ 17 = 4 余り 13
② x3 = 13² − 5 − 5 = 169 − 10 = 159
→ 6 ← 159 ÷ 17 = 9 余り 6
③ y3 = 13 × (5 − 6) − 1 = −13 − 1 = −14
→ 3 ← −14 + 17 = 3
→ 2G = (6, 3)
3G = 2G + G = (6, 3) + (5, 1)(違う2点)
① λ = (1 − 3) ÷ (5 − 6) = (−2) ÷ (−1) = 2
② x3 = 2² − 6 − 5 = 4 − 11 = −7
→ 10 ← −7 + 17 = 10
③ y3 = 2 × (6 − 10) − 3 = −8 − 3 = −11
→ 6 ← −11 + 17 = 6
→ 3G = (10, 6)
4G = 3G + G = (10, 6) + (5, 1)(違う2点)
① λ = (1 − 6) ÷ (5 − 10) = (−5) ÷ (−5) = 1
② x3 = 1² − 10 − 5 = −14
→ 3 ← −14 + 17 = 3
③ y3 = 1 × (10 − 3) − 6 = 7 − 6 = 1
→ 4G = (3, 1)
答えの (6, 3)、(10, 6)、(3, 1) は、どれも STEP 2 の表で見つけた 18 個の点に入っています。足し算の答えは、必ず曲線の上の点になります。
足し続けると、点はどう動くか
同じ計算を 5G、6G … と続けた結果が次の表です。
| k | kG | k | kG |
|---|---|---|---|
| 1 | (5, 1) | 11 | (13, 10) |
| 2 | (6, 3) | 12 | (0, 11) |
| 3 | (10, 6) | 13 | (16, 4) |
| 4 | (3, 1) | 14 | (9, 1) |
| 5 | (9, 16) | 15 | (3, 16) |
| 6 | (16, 13) | 16 | (10, 11) |
| 7 | (0, 6) | 17 | (6, 14) |
| 8 | (13, 7) | 18 | (5, 16) |
| 9 | (7, 6) | 19 | 無限遠点 |
| 10 | (7, 11) | 20 | G に戻る (5, 1) |
この順番を、図9 のマス目に番号で書き込んだのが図10 です。1 → 2 → 3 → 4 と追うと、(5, 1) → (6, 3) → (10, 6) → (3, 1) と、近くの点に順に進むのではなく、あちこちに飛び回っていて規則が見えません。ここが暗号に使えるポイントです。
19 回で一周する
18G = (5, 16) は、G = (5, 1) の上下のペアです。この2点を足そうとすると、x が同じなので2点を結ぶ直線が真っすぐ縦になり、3つ目の交点が見つかりません(①の式でも x2 − x1 = 0 で割ることになります)。この場合の答えを「無限遠点」という特別な点と決めておきます。無限遠点は、数の 0 のような役目をする点だと考えてください(座標では書けない点ですが、こういうものとして扱います)。
つまり 19G が無限遠点で、もう1回足すと 20G = G に戻ります。18 個の点と無限遠点を合わせた 19 個の点を、G から1回ずつすべて通って一周するわけです。この一周に必要な回数(ここでは 19)を「位数」と呼びます。
図11 は、この一周を時計の文字盤のように並べたものです。一周すると元に戻るので、20G は G、21G は 2G と同じ点になります。この性質は、後の ECDH の例で使います。
なぜ安全なのか:何回足したかを当てられない
楕円曲線暗号の安全性は、次の問題が難しいことに支えられています。
出発点 G と、G を k 回足した点 Q がわかっていても、k(何回足したか)を求めるのは難しい。
図10の小さな曲線なら、G から順に足していけば、多くても 19 回で k が見つかります。点が規則なく飛び回るので、基本的には1つずつ試すしかありません。
実際の暗号で使う曲線は、桁がまったく違います。P-256 では、一周に必要な回数(位数)が約 1.16 × 1077 です。1 の後ろに 0 が 77 個並ぶほどの大きさです。
1つずつ試すよりは速い解き方も知られていますが、今知られているいちばん速い方法でも約 2128 回(約 3.4 × 1038 回)の計算が必要とされています。この方法の中身は高度な数学なので省略します。仮に1秒間に1兆回の計算ができたとしても、終わるまでに約 1 × 1019 年かかります。宇宙の年齢(約 138 億年)のおよそ 8 億倍です。
一方、k から Q = kG を計算するのは、図7のやり方で数百回の計算で済みます。「足すのは一瞬、何回足したかを当てるのは不可能に近い」という差が、楕円曲線暗号の「片道だけ簡単な計算」です。
鍵の作り方と鍵交換(ECDH)
秘密鍵と公開鍵
楕円曲線暗号の鍵は、次のように作ります。
| 項目 | 中身 | 公開してよいか |
|---|---|---|
| 曲線と出発点 G | 規格で決まった曲線と点(P-256、Curve25519 など) | 公開(みんなが同じものを使う) |
| 秘密鍵 | ランダムに選んだ大きな数 k | 秘密 |
| 公開鍵 | 曲線の上の点 Q = kG | 公開 |
公開鍵 Q を見られても、前の章の理由で k はわかりません。だから Q は公開してよく、k だけを手元で守ればよい、という仕組みになります。秘密鍵は「数」、公開鍵は「点」という違いがあることも押さえておくと、後の話が読みやすくなります。
ECDH で共通の鍵を作る
DH 鍵交換を楕円曲線で行うのが ECDH(楕円曲線ディフィー・ヘルマン)です。図10の小さな曲線を使って、アリスとボブが共通の鍵を作る流れを見てみます。曲線と G = (5, 1) は、2人とも知っている公開の情報です。
それぞれ秘密の数を選ぶ
アリスは 3、ボブは 7 を秘密の数として選びます。この数は誰にも送りません。
公開鍵を計算して相手に送る
アリスは 3G = (10, 6)、ボブは 7G = (0, 6) を計算し、相手に送ります(上の kG の表で確かめられます)。この2つの点は、途中でイブに見られてもかまいません。
受け取った点を、自分の秘密の数だけ足す
アリスはボブから届いた点 (0, 6) を3倍し、ボブはアリスから届いた点 (10, 6) を7倍します。
計算
アリス:3 ×(ボブの点 7G)= 21G
ボブ :7 ×(アリスの点 3G)= 21G
21G は一周(19 回)を超えるので、21 − 19 = 2 → 2G = (6, 3)
2人とも同じ点 (6, 3) にたどり着きます。実際の TLS 1.3 では、この共通の点の x 座標を材料にして、通信の暗号化に使う共通鍵(AES の鍵など)を作ります。
イブは G、(10, 6)、(0, 6) を見ていますが、そこから 3 や 7 を求めるには「何回足したか」を当てる必要があります。実際の曲線ではこれができないので、イブは共通の点を作れません。絵の具で説明した DH と同じで、秘密の数そのものは一度もネットワークに流れません。
ECDH だけでは、通信相手が本物かどうかはわかりません。途中の第三者が相手になりすます攻撃は、次の章の署名と証明書を組み合わせて防ぎます。詳しくは Diffie-Hellman 鍵交換の記事 の「DH だけでは防げないこと」を参照してください。
署名(ECDSA・EdDSA)
楕円曲線はデジタル署名にも使います。代表的な方式が ECDSA と EdDSA(Ed25519 など)です。署名の計算式は少し複雑なので、ここでは役割だけを押さえます。
| 誰が | 使う鍵 | すること |
|---|---|---|
| 送る側 | 秘密鍵 k | データと秘密鍵から「署名」(数の組)を作る |
| 受け取る側 | 公開鍵 Q | データ、署名、公開鍵を使って、秘密鍵の持ち主が作った署名かを確かめる |
署名を作れるのは秘密鍵を持っている人だけですが、確かめるのは公開鍵があれば誰でもできます。公開鍵から秘密鍵を逆算できないので、他人が署名を偽造することはできません。TLS では、サーバ証明書の署名や、サーバが証明書の持ち主本人であることを示す署名にこの仕組みが使われます。公開鍵暗号、認証局、署名の関係は PKI の記事 で説明しています。
ECDSA では、署名を作るたびに秘密の乱数を1つ使います。この乱数を使い回したり、予測できる値にしたりすると、署名から秘密鍵を計算できてしまいます。実際に、この誤りが原因で秘密鍵を割り出された製品もありました。EdDSA は、この値を秘密鍵とデータから決まった手順で作るので、この種の失敗が起きにくい設計になっています。
RSA と比べると何がうれしいのか
楕円曲線暗号のいちばんの利点は、同じ強さを短い鍵で実現できることです。NIST(米国国立標準技術研究所)の SP 800-57 では、強さの目安を次のように対応付けています。
| 強さの目安 | RSA | 楕円曲線暗号 | 共通鍵暗号の目安 |
|---|---|---|---|
| 112 ビット | 2048 ビット | 224 ビット | 3DES(3 鍵) |
| 128 ビット | 3072 ビット | 256 ビット | AES-128 |
| 192 ビット | 7680 ビット | 384 ビット | AES-192 |
| 256 ビット | 15360 ビット | 512 ビット以上 | AES-256 |
256 ビットの楕円曲線暗号は、3072 ビットの RSA と同じ 128 ビット相当です。「128 ビット相当」は、前の章の約 2128 回の計算が必要になる強さ、という意味です。鍵が短いぶん計算が軽く、証明書や通信でやり取りするデータも小さくなります。スマートフォンや IoT 機器、大量の接続をさばくサーバで楕円曲線暗号がよく使われるのはこのためです。
どこで使われているのか
| 場面 | 使われ方 | 設定などで見かける名前 |
|---|---|---|
| TLS 1.3(HTTPS) | 鍵交換(ECDHE) | x25519、secp256r1(P-256) |
| TLS 1.3(HTTPS) | 証明書と署名 | ecdsa_secp256r1_sha256、ed25519 |
| SSH | ホスト鍵・ユーザ鍵、鍵交換 | ssh-ed25519、ecdsa-sha2-nistp256、curve25519-sha256 |
| IPsec(IKE) | 鍵交換(DH グループ) | グループ 19(256 ビット)、20(384 ビット)、21(521 ビット)、31(Curve25519) |
| 暗号資産(ビットコインなど) | 取引の署名 | secp256k1 |
TLS 1.3 の仕様(RFC 8446)では、P-256 での鍵交換は実装必須、X25519 での鍵交換は実装推奨とされています。OpenSSH では、9.5 から ssh-keygen が作る鍵の既定が Ed25519 になりました。
機器の設定で「ECDHE」「ECDSA」「P-256」「Curve25519」「DH グループ 19」などを見かけたら、どれも楕円曲線暗号を使っていると読み替えてかまいません。DH グループの選び方は、Diffie-Hellman 鍵交換の記事 の「鍵長(DH グループ)の選び方」にまとめています。
これからの注意点:量子コンピュータ
楕円曲線暗号にも弱点があります。十分に大きな量子コンピュータが実現すると、「ショアのアルゴリズム」という方法で「何回足したか」を現実的な時間で求められることがわかっています。RSA も同じ方法で破られます。
今のところ、実際の楕円曲線暗号を破れる量子コンピュータはありません。ただ、暗号化された通信を今のうちに保存しておき、将来解読するという攻撃が考えられるため、量子コンピュータでも解けないとされる新しい方式(耐量子暗号)への移行が始まっています。
鍵交換では、楕円曲線の X25519 と、耐量子暗号の ML-KEM(2024 年に米国の標準 FIPS 203 になった方式)を組み合わせた X25519MLKEM768 が、Chrome や Firefox などのブラウザで既定で使われています。どちらか一方が破られても安全が保たれるように、楕円曲線暗号を捨てるのではなく、新しい方式と一緒に使う形です。
まとめ
| 項目 | ポイント |
|---|---|
| 楕円曲線 | y² = x³ + ax + b の形の曲線。x 軸について上下対称 |
| 点の足し算 | 2点を通る直線と曲線の3つ目の交点を、上下にひっくり返す |
| スカラー倍 | 同じ点を k 回足す。2倍を繰り返すので、k が大きくても速い |
| 時計の世界 | 実際は素数で割った余りで計算する。点は規則なく飛び回る |
| 安全な理由 | G と Q = kG から k を求めることが、現実的な時間ではできない |
| 鍵 | 秘密鍵は数 k、公開鍵は点 Q = kG |
| 使い道 | 鍵交換(ECDH)と署名(ECDSA・EdDSA)。TLS、SSH、IPsec などで使う |
| RSA との違い | 256 ビットで RSA 3072 ビットと同じ強さ。鍵が短く計算が軽い |
| 今後 | 量子コンピュータに備え、耐量子暗号と組み合わせたハイブリッド方式が広がっている |
コメント