Lemma

第4章楕円曲線暗号

目安 9〜12 時間定理など 8演習 8 問
ここまでの道

この章の目標

  • 有限体上の楕円曲線の加法公式とハッセの定理を使って、小さい曲線で点の計算と群の位数の見積もりができる
  • 楕円曲線の離散対数問題に汎用的な攻撃しか知られていないことから、鍵が RSA より短くてすむ理由を説明できる
  • ECDH・ECDSA・EdDSA の手順を述べ、正しさを証明できる
  • ナンスの再利用・漏洩・偏りから秘密鍵が求まることを証明し、決定的なナンスの意味を説明できる
  • 公開鍵の検証を怠ったときの無効曲線攻撃・小部分群攻撃と、余因子の役割を説明できる
  • 安全な曲線の条件と、秘密に依存しない(定数時間の)実装の考え方を説明できる

前提:第2章、第3章、04-algebra 第2章。楕円曲線の群法則とハッセの定理は 21 第2章・21 第4章 の結果を証明なしで引用する。4.9 節では有限体 Fpk\mathbb{F}_{p^k}(04-algebra 第8章)を使う。

TLS 1.3 の規格 RFC 8446 は、用途ごとの別の定めがない限り、実装は鍵共有に楕円曲線 P-256 を使えなければならず(MUST)、X25519 にも対応すべき(SHOULD)としている。ビットコインの取引の署名には secp256k1 という曲線の上の ECDSA が使われ、米国の署名規格 FIPS 186-5(2023 年)が承認する 3 つの署名方式のうち 2 つ(ECDSA と EdDSA)は楕円曲線を使う。楕円曲線暗号が広く使われる理由は、第3章で見たとおり、同じ安全性を RSA よりずっと短い鍵で実現できることにある。

一方で、楕円曲線暗号は数学的には正しいのに実装で破れることが多い。署名のたびに選ぶ乱数(ナンス)を 2 回使えば秘密鍵が計算され、受け取った点が曲線上にあるかを確かめなければ秘密鍵が少しずつ漏れる。本章では、ECDH・ECDSA・EdDSA の手順とその正しさを証明したうえで、こうした落とし穴がなぜ鍵の漏洩につながるのかを数学で説明する。攻撃が成り立つ理由の数学的な詳細(MOV 帰着、アノマラス曲線、点の個数の計算など)は 21 第5章 で扱う。

4.1 有限体上の楕円曲線

p>3p > 3 を素数、A,B∈FpA, B \in \mathbb{F}_p を 4A3+27B2≠04A^3 + 27B^2 \neq 0 をみたす元とし、

E(Fp)={(x,y)∈Fp2∣y2=x3+Ax+B}∪{O}E(\mathbb{F}_p) = \lbrace (x, y) \in \mathbb{F}_p^2 \mid y^2 = x^3 + Ax + B \rbrace \cup \lbrace O \rbrace

とおく。OO は無限遠点である。条件 4A3+27B2≠04A^3 + 27B^2 \neq 0 は、右辺の 3 次式が重根をもたない(曲線が特異点をもたない)ことを表す。

定理 4.1(群法則と加法公式)E(Fp)E(\mathbb{F}_p) は OO を単位元とするアーベル群であり、(x,y)(x, y) の逆元は (x,−y)(x, -y) である。P1=(x1,y1)P_1 = (x_1, y_1), P2=(x2,y2)P_2 = (x_2, y_2) について、x1=x2x_1 = x_2 かつ y1=−y2y_1 = -y_2 なら P1+P2=OP_1 + P_2 = O、そうでなければ

λ={y2−y1x2−x1(x1≠x2)3x12+A2y1(P1=P2),x3=λ2−x1−x2,y3=λ(x1−x3)−y1\lambda = \begin{cases} \dfrac{y_2 - y_1}{x_2 - x_1} & (x_1 \neq x_2) \\[2ex] \dfrac{3x_1^2 + A}{2y_1} & (P_1 = P_2) \end{cases}, \qquad x_3 = \lambda^2 - x_1 - x_2, \qquad y_3 = \lambda(x_1 - x_3) - y_1

として P1+P2=(x3,y3)P_1 + P_2 = (x_3, y_3) である。

(主張のみ。λ\lambda は 2 点を通る直線または接線の傾きで、直線と曲線の 3 つ目の交点を xx 軸について折り返したものが和になる。公式の導出と結合法則の証明は 21 第2章 の定理 2.6(加法公式)と定理 2.10(群法則)を参照。)

整数 kk と点 PP について、PP を kk 回足したものを [k]P[k]P と書く([0]P=O[0]P = O, [−k]P=−[k]P[-k]P = -[k]P)。[k]P[k]P は反復二乗法(第1章)と同じ「2 倍と加算」で O(log⁡k)O(\log k) 回の群演算で計算できる。

定理 4.2(ハッセの定理)∣∣E(Fp)∣−(p+1)∣≤2p\bigl\lvert \lvert E(\mathbb{F}_p) \rvert - (p + 1) \bigr\rvert \leq 2\sqrt{p}。

(主張のみ。証明は 21 第4章 定理 4.7 を参照。)点の個数はおよそ pp で、ap=p+1−∣E(Fp)∣a_p = p + 1 - \lvert E(\mathbb{F}_p) \rvert をフロベニウスのトレースという。∣E(Fp)∣\lvert E(\mathbb{F}_p) \rvert そのものは、シューフのアルゴリズムとその改良により log⁡p\log p の多項式時間で計算でき(21 第5章 5.6 節)、暗号では位数が素数(またはその小さい倍数)になる曲線を選ぶ。

例 4.3(この章の小さい曲線)p=211p = 211, E ⁣:y2=x3+x+1E\colon y^2 = x^3 + x + 1 とする(4A3+27B2=31≠04A^3 + 27B^2 = 31 \neq 0)。各 xx について x3+x+1x^3 + x + 1 が平方剰余かどうかを調べて数えると ∣E(F211)∣=223\lvert E(\mathbb{F}_{211}) \rvert = 223 で、これは素数である。ap=212−223=−11a_p = 212 - 223 = -11 で、確かに ∣ap∣≤2211≈29.05\lvert a_p \rvert \leq 2\sqrt{211} \approx 29.05。ラグランジュの定理により OO 以外のすべての点は位数 223223 で、群を生成する。点 G=(0,1)G = (0, 1) をとると、[2]G[2]G は λ=1/2=106\lambda = 1/2 = 106(2⋅106=212≡12 \cdot 106 = 212 \equiv 1)より

x3=1062−0−0≡53,y3=106⋅(0−53)−1≡78(mod211)x_3 = 106^2 - 0 - 0 \equiv 53, \qquad y_3 = 106 \cdot (0 - 53) - 1 \equiv 78 \pmod{211}

で [2]G=(53,78)[2]G = (53, 78) である。同様に [3]G=(72,189)[3]G = (72, 189)。以下、この GG と n=223n = 223 を使う(数値はすべて計算機で確かめた)。

4.2 楕円曲線上の離散対数問題と鍵の長さ

暗号に使う曲線は、ドメインパラメータ (p,A,B,G,n,h)(p, A, B, G, n, h) で指定する。G∈E(Fp)G \in E(\mathbb{F}_p) は素数位数 nn の点(ベースポイント)、h=∣E(Fp)∣/nh = \lvert E(\mathbb{F}_p) \rvert / n は余因子 (cofactor) である。秘密鍵は整数 d∈[1,n−1]d \in [1, n - 1]、公開鍵は Q=[d]GQ = [d]G で、公開鍵から秘密鍵を求める問題が楕円曲線離散対数問題(ECDLP)である。

第3章の汎用的な攻撃はそのまま使える。ポーリッヒ–ヘルマン法があるので nn は大きな素数でなければならず、そのうえでベビーステップ・ジャイアントステップ法や ρ\rho 法で約 n\sqrt{n} 回の群演算がかかる(ρ\rho 法では PP と −P-P を同一視して約 πn/4\sqrt{\pi n/4} 回)。一方、素体上の一般の楕円曲線には、Fp×\mathbb{F}_p^\times の指数計算法にあたる準指数時間の方法が知られていない。そのため安全性ビット数は nn のビット数のほぼ半分になり、128 ビットの安全性に必要な大きさは、RSA の法の 3072 ビットに対し nn が 256 ビットである(NIST SP 800-57 Part 1 Rev. 5 の目安。表は第3章 3.11 節。推奨は改訂されうる)。

ただし、これはよく選んだ曲線についての話である。特別な性質をもつ曲線では ECDLP が易しくなる(4.9 節)。また鍵が短くても、実装を誤れば数学の安全性は意味を失う(4.4〜4.10 節)。

4.3 ECDH 鍵共有

ディフィー–ヘルマン鍵共有(第2章)を楕円曲線の群で行うのが ECDH である。アリスは秘密鍵 dAd_A を選んで QA=[dA]GQ_A = [d_A]G を、ボブは dBd_B を選んで QB=[dB]GQ_B = [d_B]G を送る。アリスは [dA]QB[d_A]Q_B、ボブは [dB]QA[d_B]Q_A を計算する。冪の法則 [a]([b]P)=[ab]P[a]\bigl([b]P\bigr) = [ab]P より

[dA]QB=[dAdB]G=[dB]QA[d_A]Q_B = [d_Ad_B]G = [d_B]Q_A

なので 2 人は同じ点 SS を得る。実際には SS の xx 座標だけを鍵導出関数(ハッシュ関数による変換)に入れて共通鍵を作る(TLS 1.3 で P-256 を使う場合も、共有される値は xx 座標である)。

例 4.4 例 4.3 の曲線で dA=37d_A = 37, dB=158d_B = 158 とすると QA=(169,115)Q_A = (169, 115), QB=(59,145)Q_B = (59, 145)。dAdB=5846≡48(mod223)d_Ad_B = 5846 \equiv 48 \pmod{223} で、2 人とも S=[48]G=(185,171)S = [48]G = (185, 171) を得る。

盗聴者が G,QA,QBG, Q_A, Q_B から SS を求める問題(楕円曲線版の計算ディフィー–ヘルマン問題)は、ECDLP が解ければ解ける。ECDH そのものは相手を認証しないので、中間者攻撃を防ぐには署名などと組み合わせる(第2章)。

4.4 公開鍵の検証と無効曲線攻撃

ECDH の実装は、相手から受け取った点 QQ に自分の秘密鍵を掛ける。QQ が本当に EE の点かどうかを確かめないと何が起こるか。鍵になるのは、定理 4.1 の公式が BB を含まないという観察である。

命題 4.5(BB を使わない計算)定理 4.1 の公式だけを使って [d]Q′[d]Q' を計算する実装に、EE 上にない点 Q′=(x0,y0)∈Fp2Q' = (x_0, y_0) \in \mathbb{F}_p^2 を与える。B′=y02−x03−Ax0B' = y_0^2 - x_0^3 - Ax_0 とおき、4A3+27B′2≠04A^3 + 27B'^2 \neq 0 とすると、実装の出力は曲線 E′ ⁣:y2=x3+Ax+B′E'\colon y^2 = x^3 + Ax + B' の群 E′(Fp)E'(\mathbb{F}_p) における [d]Q′[d]Q' である。

証明. Q′Q' は E′E' の点である。E′E' に定理 4.1 を適用すると、E′(Fp)E'(\mathbb{F}_p) の加法公式は AA だけを含み B′B' を含まないので、実装が使う式と文字どおり一致する。したがって実装が途中で計算する点はすべて E′(Fp)E'(\mathbb{F}_p) の中にあり、2 倍と加算を正しく行っている。帰納法により、出力は E′(Fp)E'(\mathbb{F}_p) での [d]Q′[d]Q' である。□\square

攻撃者は、∣E′(Fp)∣\lvert E'(\mathbb{F}_p) \rvert が小さい素因数 rr をもつような B′B' を探し、E′E' 上の位数 rr の点 Q′Q' を公開鍵として送る。被害者の計算結果 [d]Q′[d]Q' は ⟨Q′⟩\langle Q' \rangle の rr 個の元のどれかで、それは d mod rd \bmod r で決まる。被害者がこの結果から作った鍵で応答を暗号化すれば、攻撃者は rr 通りの候補を試して d mod rd \bmod r を知る(共有値が xx 座標だけなら、[j]Q′[j]Q' と [−j]Q′[-j]Q' の区別がつかず ±\pm を除いて)。異なる rr について繰り返し、中国剰余定理でまとめれば dd が求まる(±\pm が残る場合も、d2 mod rd^2 \bmod r は確定するので、rr の積が n2n^2 を超えるまで集めて d2d^2 を中国剰余定理で求め、その平方根をとればよい)。これを無効曲線攻撃 (invalid curve attack) という。手間は n\sqrt{n} ではなく、使う小さい素数 rr の和の程度である。

例 4.6 例 4.4 のボブの秘密鍵 dB=158d_B = 158 を、攻撃者が無効曲線攻撃で求める。B′=9B' = 9 の曲線 E′ ⁣:y2=x3+x+9E'\colon y^2 = x^3 + x + 9 は ∣E′(F211)∣=210=2⋅3⋅5⋅7\lvert E'(\mathbb{F}_{211}) \rvert = 210 = 2 \cdot 3 \cdot 5 \cdot 7 で、位数 2,3,5,72, 3, 5, 7 の点をもつ。それぞれをボブに送ると、ボブの計算結果は次のようになる。

送る点 Q′Q' 位数 ボブの計算 [158]Q′[158]Q' xx 座標からわかること
(112,0)(112, 0) 22 OO dB≡0(mod2)d_B \equiv 0 \pmod 2
(72,80)(72, 80) 33 (72,131)=[2]Q′(72, 131) = [2]Q' dB≡±1(mod3)d_B \equiv \pm 1 \pmod 3
(55,63)(55, 63) 55 (126,130)=[3]Q′(126, 130) = [3]Q' dB≡±2(mod5)d_B \equiv \pm 2 \pmod 5
(149,7)(149, 7) 77 (158,16)=[4]Q′(158, 16) = [4]Q' dB≡±3(mod7)d_B \equiv \pm 3 \pmod 7

(xx 座標が 126126 の点は [2]Q′[2]Q' と [3]Q′[3]Q'、xx 座標が 158158 の点は [3]Q′[3]Q' と [4]Q′[4]Q' である。)符号の組み合わせは 23=82^3 = 8 通りで、中国剰余定理で dB mod 210d_B \bmod 210 の候補 32,38,52,88,122,158,172,17832, 38, 52, 88, 122, 158, 172, 178 を得る。dB<223d_B < 223 なので候補はこれだけで、公開鍵 QB=[dB]GQ_B = [d_B]G と照合すると dB=158d_B = 158 が決まる。曲線の位数 223223 の総当たりに比べれば小さいが、実際の 256 ビットの曲線では、この差が 21282^{128} 回の計算と数十個の小さい素数の和との差になる。

対策は単純で、受け取った点を使う前に検証することである。NIST SP 800-56A Rev. 3 の「完全な公開鍵の検証」は次の 4 段階からなる。

  1. Q≠OQ \neq O を確かめる。
  2. 座標 xQ,yQx_Q, y_Q が 00 以上 p−1p - 1 以下の整数であることを確かめる。
  3. yQ2≡xQ3+AxQ+B(modp)y_Q^2 \equiv x_Q^3 + Ax_Q + B \pmod{p}(曲線上にあること)を確かめる。
  4. [n]Q=O[n]Q = O(正しい部分群にあること)を確かめる。

h=1h = 1 の曲線では 3 までで十分で(OO 以外の点はすべて位数 nn)、TLS 1.3 も P-256 などについて 1〜3 の検証を義務づけている。なお 4A3+27B′2=04A^3 + 27B'^2 = 0 となる B′B' を使われると、計算は特異 3 次曲線の非特異点の群(Fp\mathbb{F}_p の加法群、Fp×\mathbb{F}_p^\times、または Fp2×\mathbb{F}_{p^2}^\times の部分群と同型。21 第2章 定理 2.19)の中で行われ、そこでは離散対数がさらに易しい。これも 3 の検証で防げる。

4.5 余因子と小部分群

h>1h > 1 の曲線では、曲線上の点でも位数の小さい成分を含みうる。

命題 4.7(余因子による分解)∣E(Fp)∣=hn\lvert E(\mathbb{F}_p) \rvert = hn、nn は素数で n∤hn \nmid h とし、GG を位数 nn の点とする。

  1. [n]Q=O[n]Q = O となる点 QQ 全体は ⟨G⟩\langle G \rangle に一致する。
  2. すべての Q∈E(Fp)Q \in E(\mathbb{F}_p) は Q=Q1+TQ = Q_1 + T(Q1∈⟨G⟩Q_1 \in \langle G \rangle, [h]T=O[h]T = O)とただ一通りに書ける。
  3. h∣kh \mid k ならば [k]Q=[k]Q1[k]Q = [k]Q_1 である。特に [h]Q∈⟨G⟩[h]Q \in \langle G \rangle。

証明. (1) [n]Q=O[n]Q = O で Q∉⟨G⟩Q \notin \langle G \rangle となる QQ があるとする。QQ の位数は nn で、⟨G⟩∩⟨Q⟩\langle G \rangle \cap \langle Q \rangle は素数位数の群 ⟨Q⟩\langle Q \rangle の部分群で QQ を含まないので {O}\lbrace O \rbrace である。すると (U,V)↦U+V(U, V) \mapsto U + V は ⟨G⟩×⟨Q⟩\langle G \rangle \times \langle Q \rangle から E(Fp)E(\mathbb{F}_p) への単射となり、n2n^2 個の元の部分群ができる。ラグランジュの定理より n2∣hnn^2 \mid hn、すなわち n∣hn \mid h となって矛盾する。(2) uh+vn=1uh + vn = 1 となる整数 u,vu, v をとり、Q1=[uh]QQ_1 = [uh]Q, T=[vn]QT = [vn]Q とおくと Q=Q1+TQ = Q_1 + T である。[n]Q1=[u][hn]Q=O[n]Q_1 = [u][hn]Q = O なので (1) より Q1∈⟨G⟩Q_1 \in \langle G \rangle、また [h]T=[v][hn]Q=O[h]T = [v][hn]Q = O。一意性:Q1+T=Q1′+T′Q_1 + T = Q_1' + T' なら Q1−Q1′=T′−TQ_1 - Q_1' = T' - T は [n][n] でも [h][h] でも OO になり、gcd⁡(n,h)=1\gcd(n, h) = 1 より OO である。(3) [k]T=O[k]T = O による。□\square

攻撃者が正しい公開鍵 QQ の代わりに Q+TQ + T(TT は位数の小さい点)を送ると、被害者の結果 [d](Q+T)=[d]Q+[d]T[d](Q + T) = [d]Q + [d]T は d mod ord⁡(T)d \bmod \operatorname{ord}(T) に依存し、その情報が漏れうる(小部分群攻撃)。漏れるのは ord⁡(T)∣h\operatorname{ord}(T) \mid h の分だけで、命題 4.7 (3) により、スカラーを hh の倍数にすれば TT の成分は消える。SP 800-56A の ECDH(余因子つき ECDH)は P=[hdA]QBP = [hd_A]Q_B の xx 座標を共有値とし、P=OP = O なら中止する。

Curve25519(h=8h = 8)の ECDH である X25519(RFC 7748)は、秘密鍵の 32 バイトの整数の最下位 3 ビットと最上位ビットを 00、その次のビットを 11 にした値(22542^{254} に 88 の倍数を足した形)をスカラーとして使う。これをクランプ (clamping) という。スカラーが 88 の倍数なので、位数が 88 を割る点を送られると結果は OO になり、X25519 はそれを全ビット 00 の値として出力する。この共有値は受け取った側の秘密鍵に依存しないので、RFC 7748 はこれを確かめて中止してよい(MAY)とし、TLS 1.3(RFC 8446)は確かめて中止しなければならない(MUST)としている。

次のコードは RFC 7748 の手順を Python で書いたもので(安全な実装ではない)、規格のテストベクトルとの一致と、位数 2 の点 u=0u = 0 に対する出力が全ビット 00 になることを確かめる。

p = 2**255 - 19
A24 = 121665                                    # (486662 - 2) / 4

def x25519(k_bytes, u_bytes):
    k = bytearray(k_bytes)
    k[0] &= 248; k[31] &= 127; k[31] |= 64      # クランプ:8 の倍数、最上位は 2^254
    k = int.from_bytes(k, "little")
    u = int.from_bytes(u_bytes, "little") & ((1 << 255) - 1)
    x2, z2, x3, z3 = 1, 0, u, 1                  # (x2:z2) = O, (x3:z3) = P
    for t in reversed(range(255)):               # モンゴメリー・ラダー(4.10 節)
        bit = (k >> t) & 1
        if bit:                                  # 実装では定数時間の cswap にする
            x2, z2, x3, z3 = x3, z3, x2, z2
        a, b = (x2 + z2) % p, (x2 - z2) % p
        c, d = (x3 + z3) % p, (x3 - z3) % p
        da, cb = d * a % p, c * b % p
        x3, z3 = (da + cb) ** 2 % p, u * (da - cb) ** 2 % p      # 差が P の 2 点の和
        aa, bb = a * a % p, b * b % p
        x2, z2 = aa * bb % p, (aa - bb) * (aa + A24 * (aa - bb)) % p  # 2 倍
        if bit:
            x2, z2, x3, z3 = x3, z3, x2, z2
    return (x2 * pow(z2, p - 2, p) % p).to_bytes(32, "little")

k = bytes.fromhex("a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4")
u = bytes.fromhex("e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c")
print(x25519(k, u).hex())
print(x25519(k, (0).to_bytes(32, "little")).hex())   # u = 0 は位数 2 の点 (0, 0)
c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552
0000000000000000000000000000000000000000000000000000000000000000

1 行目は RFC 7748 のテストベクトルの出力と一致する。X25519 は uu 座標(xx 座標にあたる)だけで計算するので、どんな u∈Fpu \in \mathbb{F}_p も受け付け、uu が EE の点の座標でなければ二次ツイストと呼ばれる別の曲線の上で計算が進む(命題 4.5 と同じ現象)。Curve25519 はツイストの位数も 4×4 \times(素数)になるように選ばれており、ツイスト上で計算させても漏れうるのは d mod 4d \bmod 4 だけで、それもクランプで消える。この性質をツイスト安全性 (twist security) という。

4.6 ECDSA

ECDSA は DSA(第2章)を楕円曲線の群に移した署名方式で、FIPS 186-5 に定められている。メッセージのハッシュ値を nn のビット長に切り詰めた整数を zz とする。

  • 署名:秘密鍵 dd で署名するには、(1) ナンス (nonce) k∈[1,n−1]k \in [1, n - 1] を一様ランダムに選ぶ。(2) [k]G=(x1,y1)[k]G = (x_1, y_1) とし、r=x1 mod nr = x_1 \bmod n とする(x1x_1 は 0≤x1<p0 \leq x_1 < p の整数とみる)。(3) s=k−1(z+rd) mod ns = k^{-1}(z + rd) \bmod n とする。r=0r = 0 または s=0s = 0 なら (1) に戻る。署名は (r,s)(r, s) である。
  • 検証:公開鍵 Q=[d]GQ = [d]G について、(1) 1≤r,s≤n−11 \leq r, s \leq n - 1 を確かめる。(2) w=s−1w = s^{-1}, u1=zwu_1 = zw, u2=rwu_2 = rw(すべて  mod n\bmod n)とし、X=[u1]G+[u2]QX = [u_1]G + [u_2]Q を計算する。(3) X≠OX \neq O かつ XX の xx 座標を nn で割った余りが rr なら受理する。

定理 4.8(ECDSA の正しさ)正しく作られた署名は受理される。

証明. 1≤r,s≤n−11 \leq r, s \leq n - 1 は作り方から成り立ち、nn は素数なので w=s−1 mod nw = s^{-1} \bmod n が定まる。sk≡z+rd(modn)sk \equiv z + rd \pmod{n} より

u1+u2d≡w(z+rd)≡s−1sk=k(modn)u_1 + u_2d \equiv w(z + rd) \equiv s^{-1}sk = k \pmod{n}

GG の位数は nn なので X=[u1]G+[u2]([d]G)=[u1+u2d]G=[k]GX = [u_1]G + [u_2]\bigl([d]G\bigr) = [u_1 + u_2d]G = [k]G である。1≤k≤n−11 \leq k \leq n - 1 より X≠OX \neq O で、その xx 座標 x1x_1 について x1 mod n=rx_1 \bmod n = r だから受理される。□\square

例 4.9 例 4.3 の曲線で秘密鍵を d=97d = 97 とすると Q=[97]G=(95,38)Q = [97]G = (95, 38)。z=41z = 41 にナンス k=150k = 150 で署名すると、[150]G=(33,177)[150]G = (33, 177) より r=33r = 33、s=150−1(41+33⋅97) mod 223=90s = 150^{-1}(41 + 33 \cdot 97) \bmod 223 = 90。検証では w=90−1≡57w = 90^{-1} \equiv 57, u1=41⋅57≡107u_1 = 41 \cdot 57 \equiv 107, u2=33⋅57≡97u_2 = 33 \cdot 57 \equiv 97 で、[107]G+[97]Q=(33,177)[107]G + [97]Q = (33, 177) の xx 座標が r=33r = 33 に一致する。

これは正しさの証明であって、偽造できないこと(安全性)の証明ではない。正しく作られた署名 (r,s)(r, s) があれば (r,n−s)(r, n - s) も受理される(問題 4.3)ので、署名の値そのものを取引の識別子などに使う場合は、s≤n/2s \leq n/2 のものだけを受け付けるといった約束が要る。

4.7 ナンスの事故

ECDSA の安全性は、ナンス kk が秘密で、一様で、使い回されないことに全面的に依存している。

定理 4.10(ナンスの漏洩と再利用)(r,s)(r, s) をハッシュ値 zz に対する秘密鍵 dd の署名とする。

  1. その署名のナンス kk がわかれば、d≡r−1(sk−z)(modn)d \equiv r^{-1}(sk - z) \pmod{n} である。
  2. 同じ dd と同じ kk で、z1≢z2(modn)z_1 \not\equiv z_2 \pmod{n} に署名した (r,s1)(r, s_1), (r,s2)(r, s_2) があれば、s1≢s2s_1 \not\equiv s_2 であり、k≡(z1−z2)(s1−s2)−1(modn)k \equiv (z_1 - z_2)(s_1 - s_2)^{-1} \pmod{n} である。したがって (1) により dd が求まる。

証明. (1) sk≡z+rdsk \equiv z + rd を dd について解く。1≤r≤n−11 \leq r \leq n - 1 と nn が素数であることから rr は可逆である。(2) sik≡zi+rds_ik \equiv z_i + rd(i=1,2i = 1, 2)を辺々引くと (s1−s2)k≡z1−z2≢0(s_1 - s_2)k \equiv z_1 - z_2 \not\equiv 0。よって s1≢s2s_1 \not\equiv s_2 で、s1−s2s_1 - s_2 は可逆である。□\square

同じ kk なら同じ rr になるので、再利用は署名を見るだけでわかる。

例 4.11 例 4.9 の署名者が、同じ k=150k = 150 で z2=179z_2 = 179 にも署名したとする。s2=150−1(179+33⋅97) mod 223=82s_2 = 150^{-1}(179 + 33 \cdot 97) \bmod 223 = 82 である。攻撃者は公開された (33,90)(33, 90), (33,82)(33, 82) と z1,z2z_1, z_2 だけから

k≡(41−179)⋅(90−82)−1≡85⋅28≡150,d≡33−1(90⋅150−41)≡196⋅79≡97(mod223)k \equiv (41 - 179) \cdot (90 - 82)^{-1} \equiv 85 \cdot 28 \equiv 150, \qquad d \equiv 33^{-1}(90 \cdot 150 - 41) \equiv 196 \cdot 79 \equiv 97 \pmod{223}

を得る(8−1≡288^{-1} \equiv 28, 33−1≡19633^{-1} \equiv 196)。

これは机上の話ではない。2010 年末には、ある家庭用ゲーム機のソフトウェアの署名で毎回同じ kk が使われており、定理 4.10 (2) によって署名鍵が計算されたことが公表された。

ナンスは「使い回さない」だけでは足りない。

  • 範囲が狭い:点 R=[k]GR = [k]G は、検証と同じ計算 [u1]G+[u2]Q[u_1]G + [u_2]Q(定理 4.8 の証明)で誰でも求められる。kk が [0,K)[0, K) にあるとわかっていれば、範囲を制限したベビーステップ・ジャイアントステップ法で O(K)O(\sqrt{K}) 回の群演算で kk が求まり(第3章 問題 3.5)、定理 4.10 (1) で dd がわかる。kk を 64 ビットの乱数から作れば、群がどれほど大きくても約 2332^{33} 回で破られる。上位のビットの多くが 00 に偏ったナンスは、範囲の狭いナンスにほかならない。
  • 関係がある:連続する署名で k2=k1+1k_2 = k_1 + 1 のようにナンスが既知の関係にあれば、2 つの署名の式は (k1,d)(k_1, d) についての連立一次合同式になり、dd が求まる(問題 4.5)。
  • 偏りがある:ナンスの上位の数ビットが 00 に偏るだけでも、多数の署名から格子の手法(第7章の LLL アルゴリズム。隠れた数の問題と呼ばれる問題に帰着される)で秘密鍵が求まることが知られている。計算時間の差からナンスのビット長が漏れ、この方法で鍵が復元された実例も報告されている。kk を「256 ビットの乱数を nn で割った余り」として作るだけでもわずかな偏りが生じるので、FIPS 186-5 は 64 ビット以上余分に乱数をとってから余りをとるか、範囲外の値を捨てて選び直す方法を定めている。

決定的なナンス 乱数の質に依存しないように、ナンスを秘密鍵とメッセージから決定的に作る方法がある。RFC 6979 の決定的 ECDSA は、dd とハッシュ値を種とする、HMAC にもとづく擬似乱数生成器(HMAC_DRBG)から kk を作り、FIPS 186-5 でも承認されている。同じメッセージには同じ署名が出るが(それは無害である)、異なるメッセージのナンスは秘密鍵を知らない者には予測できず、一致することもまずない。秘密を含まずにメッセージだけから k=H(m)k = H(m) のように作るのは致命的な誤りである(問題 4.4)。

ヒント

実務では ナンスの生成を自作しない。署名は、決定的 ECDSA(RFC 6979)や EdDSA を実装した検証済みのライブラリで行う。乱数を使う場合も OS の暗号論的乱数源を使う(第1章)。決定的な署名は、計算途中に故障を起こさせる攻撃(故障注入)で同じナンスの署名を作られる危険があり、FIPS 186-5 もハードウェアや組み込み機器では特に注意するよう述べている。署名した直後に自分で検証してから出力するのは、故障への簡単な対策である。

4.8 EdDSA と Curve25519

曲線 Curve25519 は p=2255−19p = 2^{255} - 19 上のモンゴメリー形の曲線

v2=u3+486662u2+uv^2 = u^3 + 486662u^2 + u

で、∣E(Fp)∣=8n\lvert E(\mathbb{F}_p) \rvert = 8n, n=2252+27742317777372353535851937790883648493n = 2^{252} + 27742317777372353535851937790883648493(素数)、ベースポイントの uu 座標は 99 である(RFC 7748)。これはツイストエドワーズ形 (twisted Edwards form) の曲線 edwards25519

−x2+y2=1+dx2y2,d=−121665121666∈Fp-x^2 + y^2 = 1 + dx^2y^2, \qquad d = -\frac{121665}{121666} \in \mathbb{F}_p

と (u,v)=((1+y)/(1−y),−486664⋅u/x)(u, v) = \bigl((1 + y)/(1 - y), \sqrt{-486664} \cdot u/x\bigr) で双有理同値で(RFC 7748。この dd は ECDSA の秘密鍵とは別物)、ベースポイントは y=4/5y = 4/5 の点(u=(1+4/5)/(1−4/5)=9u = (1 + 4/5)/(1 - 4/5) = 9 に対応)である。エドワーズ形の加法公式は

(x1,y1)+(x2,y2)=(x1y2+x2y11+dx1x2y1y2, y1y2+x1x21−dx1x2y1y2)(x_1, y_1) + (x_2, y_2) = \left(\frac{x_1y_2 + x_2y_1}{1 + dx_1x_2y_1y_2}, \ \frac{y_1y_2 + x_1x_2}{1 - dx_1x_2y_1y_2}\right)

で、単位元は (0,1)(0, 1)、−(x,y)=(−x,y)-(x, y) = (-x, y) である(主張のみ。一般の ax2+y2=1+dx2y2ax^2 + y^2 = 1 + dx^2y^2 の場合が 21 第5章 5.5 節にある)。−1-1 が Fp\mathbb{F}_p の平方数(p≡1(mod4)p \equiv 1 \pmod 4)で dd が平方数でない(計算機で確認)ので、曲線上のどんな 2 点についても分母は 00 にならない(問題 4.8)。2 倍算も単位元も場合分けなしに同じ式で計算できる公式を完全な加法公式 (complete addition law) といい、秘密に依存する分岐をなくすのに役立つ。

Ed25519(RFC 8032)  HH を SHA-512 とし、ハッシュ値は 512 ビットの整数とみる。ベースポイントを GG(位数 nn)とする。

  • 鍵:秘密鍵は 32 バイトの乱数 k0k_0。H(k0)H(k_0) の前半を X25519 と同様にクランプした整数を秘密のスカラー ss、後半を prefix\mathit{prefix} とし、公開鍵を Q=[s]GQ = [s]G とする。
  • 署名:メッセージ MM に対し、r=H(prefix∥M) mod nr = H(\mathit{prefix} \mathbin{\Vert} M) \bmod n, R=[r]GR = [r]G, c=H(R∥Q∥M) mod nc = H(R \mathbin{\Vert} Q \mathbin{\Vert} M) \bmod n, S=(r+cs) mod nS = (r + cs) \bmod n とし、署名を (R,S)(R, S) とする(∥\Vert は連結。点はバイト列に符号化してから入れる)。
  • 検証:0≤S<n0 \leq S < n を確かめ、c=H(R∥Q∥M) mod nc = H(R \mathbin{\Vert} Q \mathbin{\Vert} M) \bmod n として [8][S]G=[8]R+[8][c]Q[8][S]G = [8]R + [8][c]Q が成り立てば受理する([S]G=R+[c]Q[S]G = R + [c]Q を確かめてもよい)。

(RFC 8032 では基点を BB、公開鍵を AA、位数を LL と書く。)

定理 4.12(EdDSA の正しさ)正しく作られた署名は受理される。

証明. S≡r+cs(modn)S \equiv r + cs \pmod{n} で GG の位数は nn なので、[S]G=[r]G+[c]([s]G)=R+[c]Q[S]G = [r]G + [c]\bigl([s]G\bigr) = R + [c]Q。両辺に [8][8] を施せば 2 つ目の式も成り立つ。0≤S<n0 \leq S < n は作り方から成り立つ。□\square

なぜナンスを決定的に作るのか EdDSA の rr も ECDSA の kk と同じ役割をもち、同じ rr で異なるメッセージに署名すると、c1≢c2c_1 \not\equiv c_2 のとき s≡(S1−S2)(c1−c2)−1(modn)s \equiv (S_1 - S_2)(c_1 - c_2)^{-1} \pmod{n} で秘密のスカラーが求まる(定理 4.10 と同じ計算)。EdDSA は rr を秘密の prefix\mathit{prefix} とメッセージのハッシュから作るので、(1) 署名のときに乱数が要らず、乱数生成器の欠陥の影響を受けない。(2) 同じメッセージなら同じ rr で、署名も同じになるので害はない。(3) 異なるメッセージで rr が一致するのは HH の出力が  mod n\bmod n で一致する場合に限られ、HH がランダムな関数のようにふるまうなら、その確率は 1 組あたり約 1/n1/n で無視できる。(4) prefix\mathit{prefix} を知らない者には rr が予測できない。RFC 8032 は「EdDSA の署名は決定的であり、質の悪い乱数で署名することから生じる攻撃を防ぐ」と述べている。

検証で S<nS < n を確かめるのは、S+nS + n も同じ式をみたしてしまい、同じメッセージに別の有効な署名が作れる(展性)のを防ぐためである。また余因子 88 を掛ける式と掛けない式は、位数の小さい成分を混ぜた悪意のある署名に対して判定が分かれうる。RFC 8032 はどちらを使ってもよいとしているが、複数の実装が同じ判定をしなければならない用途(合意形成など)ではどちらかに統一する必要がある。

4.9 安全な曲線の条件

ECDLP が易しくなる曲線の性質と、規格の曲線が満たしている条件をまとめる。ここで nn はベースポイントの位数、hh は余因子である。

  1. nn が大きな素数で、hh が小さい:ポーリッヒ–ヘルマン法と n\sqrt{n} の汎用攻撃への対策。hh は 1, 4, 8 程度にする(4.5 節)。
  2. 埋め込み次数が大きい:n∣pk−1n \mid p^k - 1 となる最小の kk を埋め込み次数という。ヴェイユ対などを使うと ECDLP は Fpk×\mathbb{F}_{p^k}^\times の離散対数問題に帰着され(MOV 帰着。主張のみ、21 第5章 定理 5.15)、kk が小さければ指数計算法系の方法で解ける。超特異曲線は kk が小さい(素体 Fp\mathbb{F}_p, p≥5p \geq 5 上では k≤2k \leq 2。同 命題 5.16。問題 4.7 は一例)。
  3. アノマラスでない:∣E(Fp)∣=p\lvert E(\mathbb{F}_p) \rvert = p の曲線(アノマラス曲線)では ECDLP が多項式時間で解ける(主張のみ、21 第5章 定理 5.18)。
  4. ツイスト安全性:xx 座標だけで計算する実装を想定するなら、二次ツイストの位数も大きな素因数をもつようにする(4.5 節)。NIST SP 800-186 は、P-224 のツイストの位数の最大の素因数が約 21172^{117} しかないので、ツイスト上で計算させられないよう検証が欠かせないと注意している。
  5. 作り方が検証できる:パラメータに意図的な弱点が仕込まれていないことを第三者が確かめられるようにする。P-256 の BB は公開された種から SHA-1 で導かれる(SEC 2 の「検証可能なランダム」。ただし種そのものがどう選ばれたかは公表されていない)。Curve25519 の係数 486662486662 は条件をみたす最小の値として決められている(RFC 7748 付録 A。そこではフロベニウスのトレースが 0,10, 1 でないこと、埋め込み次数が (n−1)/100(n - 1)/100 より大きいこと、虚数乗法の判別式が 21002^{100} より大きいことも条件にしている)。

実際に広く使われている 3 つの曲線のパラメータを、規格(SEC 2、FIPS 186-5 / SP 800-186、RFC 7748)と照合して示す。∣E(Fp)∣=hn\lvert E(\mathbb{F}_p) \rvert = hn と nn が素数であること、トレースが 0,10, 1 でないこと、埋め込み次数(それぞれ (n−1)/6(n - 1)/6, (n−1)/3(n - 1)/3, (n−1)/6(n - 1)/6)を PARI/GP で確かめた。

secp256k1(SEC 2):ビットコインなど
  p = 2^256 - 2^32 - 977,   y^2 = x^3 + 7,   h = 1
  n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141

P-256(FIPS 186-5 / SP 800-186。SEC 2 では secp256r1):TLS など
  p = 2^256 - 2^224 + 2^192 + 2^96 - 1,   y^2 = x^3 - 3x + B,   h = 1
  B = 5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B
  n = FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551

Curve25519(RFC 7748):X25519、Ed25519(edwards25519 として)
  p = 2^255 - 19,   v^2 = u^3 + 486662 u^2 + u,   h = 8
  n = 2^252 + 27742317777372353535851937790883648493

secp256k1 は jj 不変量が 00 の曲線で、位数 6 の自己同型(効率的に計算できる自己準同型)をもつ。これはスカラー倍の高速化に使える一方、ρ\rho 法も約 6\sqrt{6} 倍速くできることが知られているが、ビット数にして 1〜2 ビットの差で、128 ビット程度の安全性は保たれる。

4.10 秘密に依存しない実装

数学的に正しい計算も、計算のしかたが秘密に依存すると漏れる。2 倍と加算によるスカラー倍は、kk の 2 進表示の 11 のビットでだけ加算を行うので、処理時間や消費電力の波形から加算の有無、すなわち kk のビットが読み取れる。秘密に依存する分岐・メモリの参照位置・可変時間の命令をなくした実装を定数時間実装 (constant-time implementation) という。

命題 4.13(モンゴメリー・ラダー, Montgomery ladder)k=∑i=0tbi2ik = \sum_{i=0}^{t} b_i2^i(bi∈{0,1}b_i \in \lbrace 0, 1 \rbrace)とし、(R0,R1)=(O,P)(R_0, R_1) = (O, P) から始めて i=t,t−1,…,0i = t, t - 1, \dots, 0 の順に、bi=0b_i = 0 なら (R0,R1)←([2]R0,R0+R1)(R_0, R_1) \leftarrow ([2]R_0, R_0 + R_1)、bi=1b_i = 1 なら (R0,R1)←(R0+R1,[2]R1)(R_0, R_1) \leftarrow (R_0 + R_1, [2]R_1) とする。すると各段の後で R1−R0=PR_1 - R_0 = P であり、最後に R0=[k]PR_0 = [k]P となる。

証明. 段の始めに (R0,R1)=([u]P,[u+1]P)(R_0, R_1) = ([u]P, [u + 1]P) なら、段の後は bi=0b_i = 0 のとき ([2u]P,[2u+1]P)([2u]P, [2u + 1]P)、bi=1b_i = 1 のとき ([2u+1]P,[2u+2]P)([2u + 1]P, [2u + 2]P)、すなわち ([2u+bi]P,[2u+bi+1]P)([2u + b_i]P, [2u + b_i + 1]P) である。最初は u=0u = 0 で、uu は kk の上位のビットから順に 2 進数を読んだ値になるので、最後に u=ku = k である。□\square

ラダーでは、どの段でも加算 1 回と 2 倍 1 回を行い、bib_i で決まるのはどちらの変数に書き込むかだけである。そこで bib_i に応じて (R0,R1)(R_0, R_1) を入れ替える操作を、分岐ではなくビット演算(bib_i から全ビット 1 または全ビット 0 のマスクを作り、マスクと R0⊕R1R_0 \oplus R_1 の論理積を両方に排他的論理和で足す)で行えば、演算の並びは kk によらない(RFC 7748 の cswap)。さらに差 R1−R0=PR_1 - R_0 = P がいつも既知なので、モンゴメリー形では xx 座標だけの公式で計算でき(4.5 節のコード)、エドワーズ形なら完全な加法公式で例外処理の分岐もなくせる。ただし、これだけですべてのサイドチャネルが防げるわけではない。RFC 7748 も、メモリの参照パターンや分岐が秘密のビットに依存しないこと、さらに Fp\mathbb{F}_p の算術そのもの(環境によっては除算などの機械命令の実行時間)から情報が漏れないことにまで注意するよう求めている。

注意

「数学的に正しいコード」と「安全なコード」は別物である。テストベクトルに一致することは、定数時間であることも、無効な点を拒否することも保証しない。楕円曲線暗号は検証済みのライブラリで使い、自作の実装を本番で使わない。

まとめ

  • E ⁣:y2=x3+Ax+BE\colon y^2 = x^3 + Ax + B 上の点は弦と接線の公式で群をなし(BB は公式に現れない)、∣E(Fp)∣\lvert E(\mathbb{F}_p) \rvert は p+1±2pp + 1 \pm 2\sqrt{p} の範囲にある(ハッセの定理)。
  • ドメインパラメータ (p,A,B,G,n,h)(p, A, B, G, n, h) で、秘密鍵 dd、公開鍵 Q=[d]GQ = [d]G。よい曲線では汎用攻撃(約 n\sqrt{n})しか知られておらず、256 ビットの nn で 128 ビットの安全性になる。
  • ECDH は [dA]QB=[dB]QA[d_A]Q_B = [d_B]Q_A。受け取った点を検証しないと、BB の異なる曲線の小さい位数の点(無効曲線攻撃)や、小さい位数の成分(小部分群攻撃)から dd が漏れる。完全な検証は Q≠OQ \neq O、座標の範囲、曲線の方程式、[n]Q=O[n]Q = O の 4 段階。
  • 余因子 h>1h > 1 の曲線では、スカラーを hh の倍数にすれば小さい位数の成分が消える。X25519 はクランプでこれを行い、位数の小さい点に対しては全ビット 00 を出力する(TLS 1.3 では検出して中止)。
  • ECDSA の正しさは u1+u2d≡ku_1 + u_2d \equiv k から従う。ナンス kk が漏れる・再利用される・範囲が狭い・関係がある・偏っていると、秘密鍵が求まる。
  • EdDSA(Ed25519)はナンスを秘密の値とメッセージのハッシュから決定的に作り、完全な加法公式をもつエドワーズ曲線を使う。[S]G=R+[c]Q[S]G = R + [c]Q が正しさの式。
  • 安全な曲線の条件:大きな素数位数と小さい余因子、大きい埋め込み次数、アノマラスでないこと、ツイスト安全性、検証できる作り方。
  • 秘密に依存する分岐をなくす:モンゴメリー・ラダーと cswap、完全な加法公式。

演習問題

問題 4.1 ★ E ⁣:y2=x3+2x+4E\colon y^2 = x^3 + 2x + 4 を F13\mathbb{F}_{13} 上で考える。EE が楕円曲線であることを確かめ、∣E(F13)∣\lvert E(\mathbb{F}_{13}) \rvert を求めてハッセの定理の範囲にあることを確かめよ。また、OO 以外のどの点も群全体を生成することを示せ。

解答

4A3+27B2=32+432=464≡9≢0(mod13)4A^3 + 27B^2 = 32 + 432 = 464 \equiv 9 \not\equiv 0 \pmod{13} なので楕円曲線である。法 1313 の 00 でない平方は 1,3,4,9,10,121, 3, 4, 9, 10, 12 である。f(x)=x3+2x+4f(x) = x^3 + 2x + 4 の値は x=0,1,…,12x = 0, 1, \dots, 12 の順に 4,7,3,11,11,9,11,10,12,10,10,5,14, 7, 3, 11, 11, 9, 11, 10, 12, 10, 10, 5, 1 で、平方剰余になるのは x=0,2,5,7,8,9,10,12x = 0, 2, 5, 7, 8, 9, 10, 12 の 8 個(00 になる xx はない)。それぞれ yy が 2 個ずつあるので、OO と合わせて ∣E(F13)∣=16+1=17\lvert E(\mathbb{F}_{13}) \rvert = 16 + 1 = 17。∣17−14∣=3≤213≈7.2\lvert 17 - 14 \rvert = 3 \leq 2\sqrt{13} \approx 7.2 でハッセの定理の範囲にある。1717 は素数なので、ラグランジュの定理により OO 以外の点の位数は 1717 で、群全体を生成する。

問題 4.2 ★★ 例 4.3 の曲線(n=223n = 223, G=(0,1)G = (0, 1))で、ある署名者が同じナンスでハッシュ値 z1=12z_1 = 12, z2=99z_2 = 99 に署名し、署名 (130,54)(130, 54), (130,3)(130, 3) を公開した。秘密鍵 dd を求めよ。また、求めた dd が正しいことをどう確かめればよいか。

解答

定理 4.10 (2) より k≡(12−99)(54−3)−1≡136⋅51−1(mod223)k \equiv (12 - 99)(54 - 3)^{-1} \equiv 136 \cdot 51^{-1} \pmod{223}。51⋅35=1785=8⋅223+151 \cdot 35 = 1785 = 8 \cdot 223 + 1 より 51−1≡3551^{-1} \equiv 35 で、k≡136⋅35=4760≡77k \equiv 136 \cdot 35 = 4760 \equiv 77。次に d≡130−1(54⋅77−12)≡130−1⋅132d \equiv 130^{-1}(54 \cdot 77 - 12) \equiv 130^{-1} \cdot 132。130⋅211=27430=123⋅223+1130 \cdot 211 = 27430 = 123 \cdot 223 + 1 より 130−1≡211130^{-1} \equiv 211 で、d≡211⋅132=27852≡200(mod223)d \equiv 211 \cdot 132 = 27852 \equiv 200 \pmod{223}。確かめるには、[d]G[d]G が公開鍵 QQ に一致すること(ここでは Q=[200]G=(206,90)Q = [200]G = (206, 90))、あるいは [k]G[k]G の xx 座標が rr であること([77]G=(130,153)[77]G = (130, 153))を計算すればよい。

問題 4.3 ★★ (r,s)(r, s) がハッシュ値 zz に対する正しい ECDSA 署名なら、(r,n−s)(r, n - s) も検証に合格することを示せ。これはどんな場面で問題になるか。

解答

s′=n−s≡−ss' = n - s \equiv -s とおくと 1≤s′≤n−11 \leq s' \leq n - 1 で、w′=s′−1≡−ww' = s'^{-1} \equiv -w, u1′=zw′≡−u1u_1' = zw' \equiv -u_1, u2′=rw′≡−u2u_2' = rw' \equiv -u_2。よって X′=[u1′]G+[u2′]Q=−([u1]G+[u2]Q)=−XX' = [u_1']G + [u_2']Q = -([u_1]G + [u_2]Q) = -X である。定理 4.8 より X≠OX \neq O でその xx 座標を nn で割った余りは rr で、−X-X は XX と同じ xx 座標をもつ(yy 座標の符号だけが違う)ので、(r,s′)(r, s') も受理される。秘密鍵を知らない第三者が、同じメッセージに対する別の有効な署名を作れる(展性)ので、署名のバイト列を取引の識別子に使うシステムでは、識別子を書き換えられてしまう。s≤n/2s \leq n/2 の署名だけを受け付けるなど、表し方を一つに決める約束で防ぐ。

問題 4.4 ★★ (この実装のどこが危ないか)ある実装は「乱数生成器が信用できないので」と、ナンスを k=H(m) mod nk = H(m) \bmod n(HH は公開のハッシュ関数、mm は署名するメッセージ)として ECDSA の署名を作っている。(1) 署名が 1 つ公開されれば秘密鍵が求まることを示せ。(2) 別の実装は kk を 32 ビットの乱数としている。署名 1 つから秘密鍵を求める手間を見積もれ。(3) 正しい直し方を述べよ。

解答

(1) mm は署名とともに公開されるので、誰でも k=H(m) mod nk = H(m) \bmod n を計算できる。定理 4.10 (1) より d≡r−1(sk−z)(modn)d \equiv r^{-1}(sk - z) \pmod{n}。

(2) 点 R=[k]GR = [k]G は検証と同じ計算 R=[u1]G+[u2]QR = [u_1]G + [u_2]Q(u1=zs−1u_1 = zs^{-1}, u2=rs−1u_2 = rs^{-1})で求まる。0≤k<2320 \leq k < 2^{32} の範囲の離散対数 log⁡GR\log_G R を、範囲を制限したベビーステップ・ジャイアントステップ法(第3章 問題 3.5)で約 2⋅216=2172 \cdot 2^{16} = 2^{17} 回の群演算で求められる。kk がわかれば (1) と同様に dd が求まる。曲線が 256 ビットでも、手間は 21282^{128} ではなく 2172^{17} 程度である。

(3) ナンスは nn と同程度のビット数をもち、秘密鍵を知らない者には予測できなければならない。決定的にするなら RFC 6979 のように秘密鍵 dd を入力に含めた、HMAC にもとづく擬似乱数から作るか、EdDSA を使う。乱数を使うなら OS の暗号論的乱数源から、nn のビット長より 64 ビット以上多く取って nn で割った余り(または範囲外を捨てて選び直す方法)で作る。

問題 4.5 ★★ 例 4.3 の曲線(n=223n = 223)で、ある実装は署名のたびにナンスを 1 ずつ増やしていた。ハッシュ値 z1=50z_1 = 50 への署名 (123,81)(123, 81) と、その次の z2=60z_2 = 60 への署名 (157,221)(157, 221) から、秘密鍵 dd を求めよ。一般に、k2=k1+1k_2 = k_1 + 1 のとき dd が求まる条件を述べよ。

解答

s1k1≡z1+r1ds_1k_1 \equiv z_1 + r_1d, s2(k1+1)≡z2+r2ds_2(k_1 + 1) \equiv z_2 + r_2d である。1 つ目から k1≡s1−1(z1+r1d)k_1 \equiv s_1^{-1}(z_1 + r_1d) を 2 つ目に代入し、t=s2s1−1t = s_2s_1^{-1} とおくと t(z1+r1d)+s2≡z2+r2dt(z_1 + r_1d) + s_2 \equiv z_2 + r_2d、すなわち

(tr1−r2)d≡z2−s2−tz1(modn)(tr_1 - r_2)d \equiv z_2 - s_2 - tz_1 \pmod{n}

である。81−1≡21281^{-1} \equiv 212(81⋅212=17172=77⋅223+181 \cdot 212 = 17172 = 77 \cdot 223 + 1)より t≡221⋅212≡22t \equiv 221 \cdot 212 \equiv 22、tr1−r2=22⋅123−157=2549≡96tr_1 - r_2 = 22 \cdot 123 - 157 = 2549 \equiv 96、z2−s2−tz1=60−221−1100≡77z_2 - s_2 - tz_1 = 60 - 221 - 1100 \equiv 77。96−1≡15196^{-1} \equiv 151(96⋅151=14496=65⋅223+196 \cdot 151 = 14496 = 65 \cdot 223 + 1)なので d≡77⋅151=11627≡31(mod223)d \equiv 77 \cdot 151 = 11627 \equiv 31 \pmod{223}。検算:[31]G=(100,159)[31]G = (100, 159) が公開鍵に一致する。

一般には (k1,d)(k_1, d) についての連立一次合同式 s1k1−r1d≡z1s_1k_1 - r_1d \equiv z_1, s2k1−r2d≡z2−s2s_2k_1 - r_2d \equiv z_2 - s_2 の係数行列式 r1s2−r2s1r_1s_2 - r_2s_1 が nn で割り切れなければ(tr1−r2≢0tr_1 - r_2 \not\equiv 0 と同値)、dd がただ一つ定まる。ナンスどうしに既知の一次関係 k2=ak1+bk_2 = ak_1 + b があれば、同じように解ける。

問題 4.6 ★★ Curve25519 の群 E(Fp)E(\mathbb{F}_p) は位数 8n8n(nn は奇素数)の巡回群である。(1) クランプされたスカラー kk について、任意の点 PP に対し [k]P[k]P は位数 nn の部分群に入ることを示せ。(2) 位数が 88 を割る点 TT を相手から送られたとき、X25519 の出力が自分の秘密鍵によらない値になることを示し、全ビット 00 の出力を確かめて中止すること(RFC 7748 では任意、TLS 1.3 では必須)の意味を説明せよ。

解答

(1) クランプされた kk は 88 の倍数である。命題 4.7(h=8h = 8)の (3) より、P=P1+TP = P_1 + T(P1P_1 は位数 nn の部分群の元、[8]T=O[8]T = O)と分解すると [k]P=[k]P1[k]P = [k]P_1 で、これは位数 nn の部分群に入る。

(2) [8]T=O[8]T = O なので [k]T=[k/8]([8]T)=O[k]T = [k/8]\bigl([8]T\bigr) = O。X25519 は OO を u=0u = 0(全ビット 00)として出力する(4.5 節のコードでは z2=0z_2 = 0 になり、0p−2=00^{p - 2} = 0)。この値は受け取った側の秘密鍵 kk にまったく依存しないので、TT を送った攻撃者は、秘密鍵を何も使わずに「共有された秘密」を知っていることになる。両者の秘密鍵が共有値に寄与するという性質(RFC 7748 のいう contributory behaviour)を前提にするプロトコルでは、これが脆弱性になる。全ビット 00 を検出して中止すれば防げる(TLS 1.3 では必須)。

問題 4.7 ★★ p≡3(mod4)p \equiv 3 \pmod{4} を素数とし、E ⁣:y2=x3+xE\colon y^2 = x^3 + x を Fp\mathbb{F}_p 上で考える。(1) ∣E(Fp)∣=p+1\lvert E(\mathbb{F}_p) \rvert = p + 1 を示せ。(2) nn を ∣E(Fp)∣\lvert E(\mathbb{F}_p) \rvert を割る奇素数とすると、埋め込み次数は 2 以下であることを示し、この曲線が暗号に向かない理由を説明せよ。

解答

(1) f(x)=x3+xf(x) = x^3 + x は f(−x)=−f(x)f(-x) = -f(x) をみたす。p≡3(mod4)p \equiv 3 \pmod 4 より −1-1 は平方非剰余(04-algebra 第1章 系 1.50 (2))なので、x2+1=0x^2 + 1 = 0 は解をもたず、f(x)=0f(x) = 0 となるのは x=0x = 0 だけである。x≠0x \neq 0 なら f(x)≠0f(x) \neq 0 で、(f(−x)p)=(−1p)(f(x)p)=−(f(x)p)\left(\frac{f(-x)}{p}\right) = \left(\frac{-1}{p}\right)\left(\frac{f(x)}{p}\right) = -\left(\frac{f(x)}{p}\right) なので、組 {x,−x}\lbrace x, -x \rbrace のうちちょうど一方で ff が平方剰余になり、その xx に点が 2 個ある。組は (p−1)/2(p - 1)/2 個なので、x≠0x \neq 0 の点は p−1p - 1 個。これに (0,0)(0, 0) と OO を加えて ∣E(Fp)∣=p+1\lvert E(\mathbb{F}_p) \rvert = p + 1。

(2) n∣p+1n \mid p + 1 なので n∣(p+1)(p−1)=p2−1n \mid (p + 1)(p - 1) = p^2 - 1 で、埋め込み次数は 2 以下である(gcd⁡(p+1,p−1)=2\gcd(p + 1, p - 1) = 2 なので奇素数 nn は p−1p - 1 を割らず、ちょうど 2 である)。MOV 帰着により、⟨G⟩\langle G \rangle の ECDLP は Fp2×\mathbb{F}_{p^2}^\times の離散対数問題に帰着され、そこでは準指数時間の方法が使える(この曲線で帰着を実際に計算した例が 21 第5章 例 5.17 にある)。Fp2×\mathbb{F}_{p^2}^\times の離散対数を難しくするには p2p^2 が数千ビット必要になり、楕円曲線を使う利点(鍵の短さ)が失われる。

問題 4.8 ★★★ 標数が 2 でない体 KK 上で、aa は 00 でない平方数、dd は平方数でないとし、曲線 ax2+y2=1+dx2y2ax^2 + y^2 = 1 + dx^2y^2 を考える。曲線上の任意の 2 点 (x1,y1),(x2,y2)(x_1, y_1), (x_2, y_2)(座標は KK の元)について 1±dx1x2y1y2≠01 \pm dx_1x_2y_1y_2 \neq 0 であることを示せ(4.8 節の加法公式の分母は決して 00 にならない)。

解答

ε∈{1,−1}\varepsilon \in \lbrace 1, -1 \rbrace について dx1x2y1y2=εdx_1x_2y_1y_2 = \varepsilon と仮定して矛盾を導く。このとき x1,x2,y1,y2≠0x_1, x_2, y_1, y_2 \neq 0 で、ε2=1\varepsilon^2 = 1 より (dx12y12)(dx22y22)=1(dx_1^2y_1^2)(dx_2^2y_2^2) = 1。α2=a\alpha^2 = a となる α∈K\alpha \in K をとる。曲線の方程式と合わせると

dx12y12(ax22+y22)=dx12y12(1+dx22y22)=dx12y12+1=ax12+y12dx_1^2y_1^2(ax_2^2 + y_2^2) = dx_1^2y_1^2(1 + dx_2^2y_2^2) = dx_1^2y_1^2 + 1 = ax_1^2 + y_1^2

であり、2αεx1y1=2αx1y1⋅dx1x2y1y2=dx12y12⋅2αx2y22\alpha\varepsilon x_1y_1 = 2\alpha x_1y_1 \cdot dx_1x_2y_1y_2 = dx_1^2y_1^2 \cdot 2\alpha x_2y_2 なので、2 つを辺々足して

(αx1+εy1)2=dx12y12(αx2+y2)2(\alpha x_1 + \varepsilon y_1)^2 = dx_1^2y_1^2(\alpha x_2 + y_2)^2

を得る。αx2+y2≠0\alpha x_2 + y_2 \neq 0 なら d=((αx1+εy1)/(x1y1(αx2+y2)))2d = \bigl((\alpha x_1 + \varepsilon y_1)/(x_1y_1(\alpha x_2 + y_2))\bigr)^2 は平方数となり矛盾する。α\alpha を −α-\alpha に取り替えても同じ議論ができるので、−αx2+y2≠0-\alpha x_2 + y_2 \neq 0 でも矛盾する。両方が 00 なら 2y2=02y_2 = 0、標数が 2 でないので y2=0y_2 = 0 となり、y2≠0y_2 \neq 0 に反する。□\square

(21 第5章 問題 5.7 は、a=1a = 1 の場合を示してから座標の取り替えで一般の aa に帰着させている。座標が dd の平方根を含む拡大体の点では分母が 00 になりうるので、「KK の元」という仮定は外せない。)

この章を読み終えたら

「読了」にすると、学習記録と地図に反映されます。

この章の誤りを報告GitHub で見る