【図解】楕円曲線暗号(ECC)とは?中学数学でわかる「点の足し算」と安全な理由

HTTPS で Web サイトを開くと、裏側では楕円曲線暗号(ECC:Elliptic Curve Cryptography)が動いています。TLS 1.3 の鍵交換、サーバ証明書の署名、SSH の鍵、IPsec の DH グループ 19 や 20 など、インフラの設定でもよく目にする名前です。

この記事では、中学〜高校初級の数学(代入、2乗と3乗、割り算の余り)だけを使って、楕円曲線暗号の仕組みを順番にたどります。それより先の数学が必要なところは、計算に深入りせず「こういうものです」と割り切って、図とイメージで説明します。

先に読んでおくとわかりやすい記事

鍵を安全に受け渡す仕組み(DH 鍵交換)は Diffie-Hellman 鍵交換をイメージで解説、公開鍵と署名の全体像は 公開鍵暗号、認証局、デジタル署名をイメージで解説 で説明しています。この記事は、その DH や署名の「中身の計算」を楕円曲線に置き換えたものです。

この記事でわかること
  1. 楕円曲線とはどんな式で、どんな形をしているのか
  2. 曲線の上の「点の足し算」と、同じ点を何回も足す計算
  3. 「足すのは速いが、何回足したかは当てられない」ことが安全性の土台になっていること
  4. 鍵交換(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 = 11 と −1
00 − 0 + 1 = 11 と −1
11 − 1 + 1 = 11 と −1
28 − 2 + 1 = 7√7 と −√7(約 2.65 と −2.65)
327 − 3 + 1 = 255 と −5
5125 − 5 + 1 = 12111 と −11

たとえば x = 3 のとき右辺は 25 で、2乗して 25 になる数は 5 と −5 の2つです。そのため、(3, 5) と (3, −5) の2点が曲線の上にあります。

正の数も負の数も、2乗すると同じ値になります。そのため y と −y は必ずセットで出てきて、グラフは x 軸を境に上下対称になります。この性質は、次の「点の足し算」で使います。

xyO(−1, 1)(−1, −1)(0, 1)(0, −1)(1, 1)(1, −1)(3, 5)(3, −5)x 軸について上下対称
図1 y² = x³ − x + 1 のグラフ(見やすくするため、縦と横の目盛りの幅を変えています)
補足

「楕円」という名前ですが、形は楕円(だ円)ではありません。楕円の周の長さを求める研究の中でこの形の式が出てきたことから、この名前が付いています。

また、暗号で使う曲線は、とがった点や自分自身と交わる点がないものに限られます(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 です。

xyy = 2x − 1P (0, −1)Q (3, 5)
図2 STEP 1:P と Q を通る直線を引く

直線と曲線が交わる3つ目の点を探す

3乗の式で表される曲線と直線は、ふつう3か所で交わります。P と Q 以外の交点を R とします。

この例では、直線の式 y = 2x − 1 に x = 1 を入れると y = 1 になり、表の (1, 1) と一致します。つまり (1, 1) は直線の上にも曲線の上にもある点で、これが3つ目の交点 R です。

xyy = 2x − 1P (0, −1)Q (3, 5)R (1, 1)3つ目の交点
図3 STEP 2:直線と曲線の3つ目の交点 R = (1, 1) を見つける

R を上下にひっくり返す

R の y の符号を変えた点(x 軸について反対側の点)を、P + Q の答えにします。曲線は上下対称なので、この点も必ず曲線の上にあります。この例では、R = (1, 1) をひっくり返して P + Q = (1, −1) です。

xyy = 2x − 1ひっくり返すP (0, −1)Q (3, 5)R (1, 1)3つ目の交点P+Q (1, −1)
図4 STEP 3:R を上下にひっくり返した点が P + Q

最後にひっくり返すのは、そう決めておくと「足す順番を入れ替えても答えが同じ」など、足し算らしい性質が成り立つからです。その証明は高校の範囲を超えるので、ここでは「そういうルール」として進めます。

式で確かめる:(−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 の直線と交わる)ことを確かめられます。

xyy = 1P (−1, 1)Q (0, 1)R (1, 1)ひっくり返すP+Q (1, −1)
図5 (−1, 1) + (0, 1):直線 y = 1 と曲線の3つ目の交点 R = (1, 1) をひっくり返して (1, −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)。

xy接線 y = xP (1, 1)R (−1, −1)2P (−1, 1)ひっくり返す
図6 (1, 1) + (1, 1):接線 y = x と曲線の3つ目の交点 R = (−1, −1) をひっくり返して (−1, 1)

同じ点を何回も足す(スカラー倍)

点 P を k 回足した点を kP と書きます(2P、3P、4P …)。k は普通の整数で、この計算を「スカラー倍」と呼びます。楕円曲線暗号で実際に使うのは、このスカラー倍です。

何回も足すといっても、1回ずつ足す必要はありません。「2倍」を繰り返すと、少ない回数で大きな倍数に届きます。たとえば 100P は、次のように8回の計算で求められます。

×2P×22P×24P×28P×216P×232P64P64P + 32P + 4P = 100P2倍を6回 + 足し算を2回 = 8回の計算(1回ずつ足すと99回)
図7 100P を8回の計算で求める(太枠の3つを足す)

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 の目盛りで止まります。

いつもの時計(12 で一周)12123456789101113 時 → 1 時13 ÷ 12 = 1 余り 1(1 周して 1)17 で一周する時計(0〜16)012345678910111213141516137 → 1137 ÷ 17 = 8 余り 1(8 周して 1)
図8 余りの計算は時計の針と同じ(137 は 17 の時計で 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 です。

yy²17 で割った余りyy²17 で割った余り
00098113
1111010015
244111212
399121448
416161316916
5258141969
6362152254
74915162561
86413

表を見ると、余りは 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曲線の上の点
00 + 0 + 2 = 20 余り 26、11(0, 6)、(0, 11)
11 + 2 + 2 = 50 余り 5なし―
28 + 4 + 2 = 140 余り 14なし―
327 + 6 + 2 = 352 余り 11、16(3, 1)、(3, 16)
464 + 8 + 2 = 744 余り 6なし―
5125 + 10 + 2 = 1378 余り 11、16(5, 1)、(5, 16)
6216 + 12 + 2 = 23013 余り 93、14(6, 3)、(6, 14)
7343 + 14 + 2 = 35921 余り 26、11(7, 6)、(7, 11)
8512 + 16 + 2 = 53031 余り 3なし―
9729 + 18 + 2 = 74944 余り 11、16(9, 1)、(9, 16)
101000 + 20 + 2 = 102260 余り 26、11(10, 6)、(10, 11)
111331 + 22 + 2 = 135579 余り 12なし―
121728 + 24 + 2 = 1754103 余り 3なし―
132197 + 26 + 2 = 2225130 余り 157、10(13, 7)、(13, 10)
142744 + 28 + 2 = 2774163 余り 3なし―
153375 + 30 + 2 = 3407200 余り 7なし―
164096 + 32 + 2 = 4130242 余り 164、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 軸について上下対称」が、余りの世界ではこういう形で残っています。

普通の数:なめらかな曲線線の上の点は無数にある17 で割った余り:マス目の上の点00881616折り返しの線点は全部で 18 個だけ
図9 同じ式でも、普通の数では曲線(左)、17 で割った余りではマス目の上の点(右)になる

点の足し算を式にする

余りの世界では曲線が点の集まりなので、定規で直線を引いて交点を探すことはできません。そこで、「点の足し算」の章で図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 … と続けた結果が次の表です。

kkGkkG
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)20G に戻る (5, 1)

この順番を、図9 のマス目に番号で書き込んだのが図10 です。1 → 2 → 3 → 4 と追うと、(5, 1) → (6, 3) → (10, 6) → (3, 1) と、近くの点に順に進むのではなく、あちこちに飛び回っていて規則が見えません。ここが暗号に使えるポイントです。

001122334455667788991010111112121313141415151616xy1234567891011121314151617181= G (5, 1)数字は G を何回足した点か点線:1→2→3→4の順に結んだ線19回目:無限遠点20回目:G に戻る
図10 図9 の 18 個の点に、G = (5, 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 を足すたびに1つ進む19無限遠点(0 の役)122G = 21G3456789101112131415161718数字は G を何回足したか1G, 2G, … 18G と進み、19 回目で無限遠点に戻る20G = G(1周して 1)21G = 2G(1周して 2)
図11 G を足すたびに1つ進み、19 回で一周する

なぜ安全なのか:何回足したかを当てられない

楕円曲線暗号の安全性は、次の問題が難しいことに支えられています。

楕円曲線の離散対数問題

出発点 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大きな数(1つ)公開鍵 Q = kG曲線の上の点G を k 回足す2倍と足し算で数百回 → 一瞬Q と G から k を求める最速の方法でも約 2¹²⁸ 回 → 現実的には無理
図12 k から Q は一瞬で計算できるが、Q から k は求められない

一方、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 の鍵など)を作ります。

公開:y² = x³ + 2x + 2(17で割った余り)、出発点 G = (5, 1)3G = (10, 6)7G = (0, 6)アリスボブイブ秘密の数:3秘密の数:73 × (0, 6)= 21G = (6, 3)7 × (10, 6)= 21G = (6, 3)見える:G、(10, 6)、(0, 6)3 と 7 は見えない → (6, 3) を作れない
図13 小さな曲線で見る ECDH。イブに見えるのは G と2つの公開鍵だけ

イブは 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 ビットと同じ強さ。鍵が短く計算が軽い
今後量子コンピュータに備え、耐量子暗号と組み合わせたハイブリッド方式が広がっている

コメント