Lemma

第2章公開鍵暗号

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

この章の目標

  • 共通鍵暗号の鍵配送問題と、公開鍵暗号・デジタル署名が何を解決するのかを説明できる
  • RSA 暗号と RSA 署名の正しさを(平文が nn と互いに素でない場合も含めて)証明し、秘密鍵から nn が素因数分解できることを示せる
  • 教科書的 RSA の危険(準同型性、小さい指数と同報攻撃、共通法)を小さい数で実演し、パディングの役割を説明できる
  • ディフィー–ヘルマン鍵共有・エルガマル暗号・DSA の正しさを証明し、安全性がどの計算問題に依存するかを述べられる
  • 中間者攻撃と公開鍵基盤の役割、安全性の定義(一方向性・識別不可能性)の考え方を説明できる

前提:第1章、04-algebra 第1章(中国剰余定理・原始根・オイラーの規準)、04-algebra 第2章(巡回群・元の位数)。

初めて訪れる通販サイトにカード番号を送るとき、その通信は暗号化されている。しかし、サイトとあなたは事前に秘密の鍵を打ち合わせていない。見知らぬ相手と、盗聴されている通信路の上で、どうやって秘密を共有するのか――これが公開鍵暗号の解いた問題である。

本章では、RSA 暗号、ディフィー–ヘルマン鍵共有、エルガマル暗号、DSA の仕組みを扱う。それぞれについて、証明できること(正しく復号・検証できること、ある計算ができれば別の計算もできるという帰着)と、仮定していること(素因数分解や離散対数が難しいこと)を区別する。また、教科書に載っている素朴な形(教科書的 RSA)が実際にはどう破れるか、規格がそれをどう防いでいるかを、小さい数で確かめる。

2.1 共通鍵暗号と鍵配送問題

送信者と受信者が同じ鍵 kk を共有し、暗号化 c=Ek(m)c = E_k(m) と復号 m=Dk(c)m = D_k(c) に使う方式を共通鍵暗号 (symmetric-key encryption) という。最も単純な例は、長さ ℓ\ell のビット列 mm と鍵 kk のビットごとの排他的論理和 c=m⊕kc = m \oplus k である。

命題 2.1(ワンタイムパッド, one-time pad)鍵 KK を {0,1}ℓ\lbrace 0, 1 \rbrace^\ell から一様に、平文 MM と独立に選び、C=M⊕KC = M \oplus K とする。このとき CC は {0,1}ℓ\lbrace 0, 1 \rbrace^\ell 上の一様分布に従い、MM と独立である。

証明. 任意の m,cm, c について P(C=c,M=m)=P(K=c⊕m,M=m)=2−ℓP(M=m)P(C = c, M = m) = P(K = c \oplus m, M = m) = 2^{-\ell}P(M = m)。mm について和をとると P(C=c)=2−ℓP(C = c) = 2^{-\ell} なので、P(C=c,M=m)=P(C=c)P(M=m)P(C = c, M = m) = P(C = c)P(M = m)。□\square

つまり暗号文からは平文について何の情報も得られない(シャノンの完全秘匿性)。ただし鍵は平文と同じ長さが必要で、一度しか使えない。同じ鍵で 2 つの平文を暗号化すると c1⊕c2=m1⊕m2c_1 \oplus c_2 = m_1 \oplus m_2 となり、平文の関係が漏れる。実用の共通鍵暗号は AES(FIPS 197、鍵は 128・192・256 ビット)などで、安全性は証明されていないが、長年の解析に耐えてきたことが根拠である。

共通鍵暗号の弱点は、鍵を事前に安全に共有しなければならないことである(鍵配送問題)。NN 人が互いに通信するには N(N−1)/2N(N - 1)/2 個の鍵が必要になる。1976 年にディフィーとヘルマンは、暗号化の鍵を公開してしまう公開鍵暗号 (public-key cryptography) の考え方を示し、翌 1977 年にリベスト・シャミア・エーデルマンが RSA 暗号を発表した(英国の政府通信本部ではそれ以前に同様の方式が考案されていたことが 1997 年に公表されている)。実際の通信では、公開鍵暗号や鍵共有で共通鍵を共有し、データ本体は高速な共通鍵暗号で暗号化する(ハイブリッド暗号)。

2.2 一方向性関数と落とし戸

定義 2.2(一方向性関数と落とし戸, 非形式的)多項式時間で計算できる関数 ff で、ランダムな xx に対して f(x)f(x) だけから f(y)=f(x)f(y) = f(x) となる yy を求めることが、どんな多項式時間のアルゴリズムでも無視できる確率(2.10 節)でしかできないものを一方向性関数 (one-way function) という。ある秘密の情報(落とし戸, trapdoor)を知っていれば逆算が易しくなるものを、落とし戸つき一方向性関数という。

候補は、(p,q)↦pq(p, q) \mapsto pq(逆算は素因数分解)、x↦gx mod px \mapsto g^x \bmod p(逆算は離散対数)、x↦xe mod nx \mapsto x^e \bmod n(落とし戸は nn の素因数分解)などである。

一方向性関数の存在は証明されていない(存在を証明すれば P ≠ NP も証明されることになる)。公開鍵暗号の安全性は、「数十年にわたって多くの研究者が攻撃を試みても、効率的な逆算法が見つかっていない」という経験的な根拠に支えられた仮定である。たとえば 2020 年に、829 ビット(10 進 250 桁)の RSA の法(RSA-250)が数体ふるい法で分解されている(第3章)。

2.3 RSA 暗号

n=pqn = pq(p,qp, q は相異なる素数)に対し、λ(n)=lcm⁡(p−1,q−1)\lambda(n) = \operatorname{lcm}(p - 1, q - 1) とおく(カーマイケル関数)。

定義 2.3(RSA 暗号)

  • 鍵生成:相異なる大きな素数 p,qp, q をランダムに選び(第1章 1.8 節)、n=pqn = pq とする。gcd⁡(e,λ(n))=1\gcd(e, \lambda(n)) = 1 となる ee(6553765537 がよく使われる)を選び、d=e−1 mod λ(n)d = e^{-1} \bmod \lambda(n) を拡張ユークリッドの互除法で求める。公開鍵は (n,e)(n, e)、秘密鍵は dd(と p,qp, q)である。
  • 暗号化:平文 m∈{0,1,…,n−1}m \in \lbrace 0, 1, \dots, n - 1 \rbrace に対し c=me mod nc = m^e \bmod n。
  • 復号:m=cd mod nm = c^d \bmod n。

定理 2.4(RSA 暗号の正しさ)p,qp, q を相異なる素数、n=pqn = pq とし、正の整数 e,de, d が ed≡1(modλ(n))ed \equiv 1 \pmod{\lambda(n)} をみたすとする。このとき任意の整数 mm について med≡m(modn)m^{ed} \equiv m \pmod{n} である。特に x↦xe mod nx \mapsto x^e \bmod n は Z/nZ\mathbb{Z}/n\mathbb{Z} 上の全単射で、その逆写像は x↦xd mod nx \mapsto x^d \bmod n である。

証明. ed≥1ed \geq 1 と ed≡1ed \equiv 1 より ed=1+kλ(n)ed = 1 + k\lambda(n)(k≥0k \geq 0)と書ける。法 pp で考える。p∤mp \nmid m なら、フェルマーの小定理と p−1∣λ(n)p - 1 \mid \lambda(n) より

med=m⋅(mp−1)kλ(n)/(p−1)≡m(modp)m^{ed} = m \cdot \left(m^{p-1}\right)^{k\lambda(n)/(p-1)} \equiv m \pmod{p}

p∣mp \mid m なら ed≥1ed \geq 1 より両辺とも 00 と合同である。同様に med≡m(modq)m^{ed} \equiv m \pmod{q}。p≠qp \neq q なので中国剰余定理(04-algebra 第1章 定理 1.28)より med≡m(modn)m^{ed} \equiv m \pmod{n}。最後の主張は、x↦xex \mapsto x^e と x↦xdx \mapsto x^d の合成がどちらの順でも恒等写像になることから従う。□\square

λ(n)\lambda(n) は φ(n)=(p−1)(q−1)\varphi(n) = (p - 1)(q - 1) を割るので、ed≡1(modφ(n))ed \equiv 1 \pmod{\varphi(n)} でもよい(04-algebra 第1章 定理 1.53)。λ(n)\lambda(n) を使うと dd が小さくなり、規格(FIPS 186-5)も λ(n)\lambda(n) で dd を定めている。gcd⁡(m,n)≠1\gcd(m, n) \neq 1 の平文でも正しく復号できるが、そのような mm の割合は 1/p+1/q−1/n1/p + 1/q - 1/n で無視できるほど小さく、しかも gcd⁡(m,n)\gcd(m, n) が nn の素因数を与えてしまう。なお nn が平方因子をもつと定理は成り立たない(問題 2.2)。

例 2.5 p=61p = 61, q=53q = 53, n=3233n = 3233 とすると λ(n)=lcm⁡(60,52)=780\lambda(n) = \operatorname{lcm}(60, 52) = 780。e=17e = 17 とすると d=17−1 mod 780=413d = 17^{-1} \bmod 780 = 413(17⋅413=7021=9⋅780+117 \cdot 413 = 7021 = 9 \cdot 780 + 1)。φ(n)=3120\varphi(n) = 3120 を使えば第1章の例 1.8 の d=2753d = 2753 になり、これでも復号できる。平文 m=65m = 65 は c=6517 mod 3233=2790c = 65^{17} \bmod 3233 = 2790 に暗号化され、2790413≡27902753≡652790^{413} \equiv 2790^{2753} \equiv 65 と復号される(第1章の例 1.10 は中国剰余定理によるこの計算である)。nn と互いに素でない m=122=2⋅61m = 122 = 2 \cdot 61 も、c=1830c = 1830 から 1830413≡1221830^{413} \equiv 122 と正しく戻る(すべて計算機で確認した)。

公開鍵だけから cc を復号する問題(RSA 問題)は、nn を素因数分解できれば λ(n)\lambda(n) と dd が計算できるので解ける。逆に RSA 問題が素因数分解と同じくらい難しいかどうかは未解決である。一方、秘密鍵 dd を求めることは素因数分解と同じくらい難しいことが証明できる。

定理 2.6(秘密鍵から素因数分解へ)n=pqn = pq(p,qp, q は相異なる奇素数)とし、λ(n)\lambda(n) の正の倍数 kk(たとえば k=ed−1k = ed - 1)が与えられたとする。k=2stk = 2^s t(tt は奇数)と書く。a∈{1,…,n−1}a \in \lbrace 1, \dots, n - 1 \rbrace を一様に選ぶと、確率 1/21/2 以上で「gcd⁡(a,n)>1\gcd(a, n) > 1 である」か「列 at,a2t,…,a2st(modn)a^t, a^{2t}, \dots, a^{2^s t} \pmod{n} に、x≢±1x \not\equiv \pm 1, x2≡1x^2 \equiv 1 となる項 xx が現れる」のどちらかが起こり、どちらの場合も nn の素因数が得られる。

証明. gcd⁡(a,n)>1\gcd(a, n) > 1 なら gcd⁡(a,n)\gcd(a, n) が素因数である。後者の場合は第1章の補題 1.19 より gcd⁡(x−1,n)\gcd(x - 1, n) が素因数である。以下 aa が単元のとき、後者が確率 1/21/2 以上で起こることを示せばよい。中国剰余定理より、aa が単元全体を一様に動くとき、ap=a mod pa_p = a \bmod p と aq=a mod qa_q = a \bmod q は独立にそれぞれの単元群を一様に動く。p−1∣kp - 1 \mid k より (apt)2s=1(a_p^t)^{2^s} = 1 なので、apta_p^t の位数は 2α2^\alpha(0≤α≤s0 \leq \alpha \leq s)の形で、同様に aqta_q^t の位数を 2β2^\beta とする。

α>β\alpha > \beta なら、x=a2α−1tx = a^{2^{\alpha - 1}t} は法 pp で位数 2 の元、すなわち −1-1 である(巡回群 (Z/pZ)×(\mathbb{Z}/p\mathbb{Z})^\times で位数 2 の元は −1-1 だけ)。また 2β∣2α−12^\beta \mid 2^{\alpha - 1} より x≡1(modq)x \equiv 1 \pmod{q}。よって x≢±1x \not\equiv \pm 1, x2≡1(modn)x^2 \equiv 1 \pmod{n} となる。α<β\alpha < \beta でも同様である。したがって P(α≠β)≥1/2P(\alpha \neq \beta) \geq 1/2 を示せばよい。

法 pp の原始根 gg をとり ap=gja_p = g^j と書くと、jj は {0,…,p−2}\lbrace 0, \dots, p - 2 \rbrace を一様に動く。p−1=2vwp - 1 = 2^v w(ww は奇数)とすると、p−1∣kp - 1 \mid k より w∣tw \mid t で、t/wt/w は奇数である。04-algebra 第2章の命題 2.19(3) より gjtg^{jt} の位数は (p−1)/gcd⁡(p−1,jt)=2v/gcd⁡(2v,j)(p - 1)/\gcd(p - 1, jt) = 2^v/\gcd(2^v, j)。よって α=v\alpha = v となるのは jj が奇数のときに限り、その確率はちょうど 1/21/2 である。ゆえにどの値 cc についても P(α=c)≤1/2P(\alpha = c) \leq 1/2 で、独立性より

P(α=β)=∑cP(α=c)P(β=c)≤12∑cP(β=c)=12P(\alpha = \beta) = \sum_c P(\alpha = c)P(\beta = c) \leq \frac{1}{2}\sum_c P(\beta = c) = \frac{1}{2}

□\square

この手順を繰り返せば、rr 回で失敗する確率は 2−r2^{-r} 以下である。逆に素因数分解ができれば dd は計算できるので、dd を知ることと素因数分解を知ることは(確率的多項式時間で)同値である。

例 2.7 n=3233n = 3233, e=17e = 17, d=2753d = 2753 では k=46800=24⋅2925k = 46800 = 2^4 \cdot 2925。a=2a = 2 では列が 1514,3232,1,1,11514, 3232, 1, 1, 1 となり、−1≡3232-1 \equiv 3232 を経て 11 になるので失敗する。a=3a = 3 では 2256,794,1,1,12256, 794, 1, 1, 1 で、x=794x = 794 は 11 の非自明な平方根であり、gcd⁡(793,3233)=61\gcd(793, 3233) = 61 を得る。

import math
import random

def factor_from_d(n, e, d, rng):
    """RSA の公開鍵 (n, e) と秘密鍵 d から n の素因数を 1 つ求める。"""
    k = e * d - 1                    # λ(n) の倍数
    s, t = 0, k
    while t % 2 == 0:
        s, t = s + 1, t // 2
    while True:
        a = rng.randrange(2, n - 1)
        g = math.gcd(a, n)
        if g > 1:
            return g                 # a がたまたま n と共通因数をもった
        x = pow(a, t, n)
        for _ in range(s):
            y = x * x % n
            if y == 1 and x != 1 and x != n - 1:
                return math.gcd(x - 1, n)   # 1 の非自明な平方根 x から因数を得る
            x = y

rng = random.Random(0)
p = factor_from_d(3233, 17, 2753, rng)
print(p, 3233 // p)

実行結果は 53 61 である。2048 ビットの nn でも一瞬で終わる。

鍵の長さについて、米国の NIST SP 800-57 Part 1 Rev. 5(2020 年)は、既知の最良の攻撃(第3章の数体ふるい法)の計算量をもとに次の対応を示している(表 2 の一部。全体は第3章 3.11 節)。

安全性の強さ 共通鍵暗号 RSA の法(有限体の DH の法 pp)
112 ビット 3TDEA(2024 年以降は暗号化に使えない) 2048 ビット
128 ビット AES-128 3072 ビット
192 ビット AES-192 7680 ビット
256 ビット AES-256 15360 ビット

注意

推奨鍵長は、計算機の性能やアルゴリズムの進歩、規格の改訂によって変わる。本書の数値は執筆時点のものであり、実際に使うときは最新の規格(NIST の SP 800-57 など。日本では CRYPTREC の暗号リスト)を確認すること。また、大規模な量子計算機が実現すると、ショアのアルゴリズムにより RSA も以下のディフィー–ヘルマンも多項式時間で破られ、鍵長を大きくしても防げない(第7章)。

2.4 RSA 署名

公開鍵暗号の役割を入れ替えると、デジタル署名ができる。秘密鍵の持ち主だけが作れて、誰でも公開鍵で検証できるデータである。

定義 2.8(RSA 署名)鍵は RSA 暗号と同じとする。メッセージ(のハッシュ値を符号化した整数)mm に対し、署名を s=md mod ns = m^d \bmod n とする。検証者は se≡m(modn)s^e \equiv m \pmod{n} が成り立てば受理する。

正しい署名が受理されることは定理 2.4 から従う。しかし、ハッシュ関数を通さない教科書的 RSA 署名は偽造できる。

例 2.9 (1) 好きな ss を選んで m=se mod nm = s^e \bmod n とおけば、(m,s)(m, s) は正しい署名つきメッセージになる(n=3233n = 3233, e=17e = 17 で s=1000s = 1000 なら m=175m = 175)。攻撃者が mm を自由に選べない「存在的偽造」だが、2.10 節の安全性の定義は満たさない。(2) s1,s2s_1, s_2 が m1,m2m_1, m_2 の署名なら、s1s2 mod ns_1 s_2 \bmod n は m1m2 mod nm_1 m_2 \bmod n の署名である。

実際の RSA 署名では、メッセージをハッシュ関数で固定長の値にし、乱数を混ぜて nn とほぼ同じ長さに符号化してから dd 乗する(RSA-PSS。2.5 節)。

2.5 教科書的 RSA の危険とパディング

定義 2.3 のままの RSA(教科書的 RSA, textbook RSA)には、次の弱点がある。

(1) 決定的である. 同じ平文はいつも同じ暗号文になる。平文の候補が少なければ(「賛成」か「反対」など)、攻撃者は候補をすべて公開鍵で暗号化して比べればよい(問題 2.8)。

(2) 準同型性. (m1m2)e=m1em2e(m_1 m_2)^e = m_1^e m_2^e より、暗号文の積は平文の積の暗号文である。これを使うと、「cc そのもの以外なら何でも復号して返す」サーバーから cc の平文を引き出せる(選択暗号文攻撃)。

例 2.10 n=3233n = 3233, e=17e = 17 で c=2790c = 2790 を解読したい。乱数 r=1000r = 1000 を選び、c′=c⋅r17 mod n=2790⋅175 mod 3233=67c' = c \cdot r^{17} \bmod n = 2790 \cdot 175 \bmod 3233 = 67 を復号させると、m′=340m' = 340 が返る。m′≡mrm' \equiv mr なので、r−1 mod 3233=333r^{-1} \bmod 3233 = 333 を掛けて m=340⋅333 mod 3233=65m = 340 \cdot 333 \bmod 3233 = 65 を得る。サーバーには cc と無関係に見える 6767 しか見えていない。

(3) 小さい指数. e=3e = 3 で m<n1/3m < n^{1/3} なら m3<nm^3 < n なので、c=m3c = m^3 は整数として成り立ち、cc の整数の 3 乗根で mm が求まる(n=7387n = 7387 で m=19m = 19 なら c=6859=193c = 6859 = 19^3)。e=3e = 3 で 2048 ビットの nn を使い、128 ビットの共通鍵をそのまま暗号化すると、まさにこの状況になる(署名の規格 FIPS 186-5 は ee を 216<e<22562^{16} < e < 2^{256} の奇数に限っているが、本質的な対策は後で述べるパディングである)。

命題 2.11(ハスタッドの同報攻撃, Håstad's broadcast attack)同じ平文 mm を、公開指数 ee が共通でどの 2 つも互いに素な ee 個の法 n1,…,nen_1, \dots, n_e で暗号化した暗号文 ci=me mod nic_i = m^e \bmod n_i が得られたとする(0≤m<min⁡ini0 \leq m < \min_i n_i)。中国剰余定理で x≡ci(modni)x \equiv c_i \pmod{n_i}(0≤x<N=n1⋯ne0 \leq x < N = n_1 \cdots n_e)を求めると x=mex = m^e であり、mm は xx の整数の ee 乗根として求まる。

証明. me≡ci(modni)m^e \equiv c_i \pmod{n_i} がすべての ii で成り立ち、0≤me<n1⋯ne=N0 \leq m^e < n_1 \cdots n_e = N なので、中国剰余定理の一意性より x=mex = m^e。□\square

例 2.12 e=3e = 3、法を n1=47⋅59=2773n_1 = 47 \cdot 59 = 2773, n2=53⋅71=3763n_2 = 53 \cdot 71 = 3763, n3=83⋅89=7387n_3 = 83 \cdot 89 = 7387(どれも 3∤φ(ni)3 \nmid \varphi(n_i))とし、同じ m=2026m = 2026 を送る。

def crt(residues, moduli):
    """法がどの 2 つも互いに素なときの中国剰余定理。0 以上 N 未満の解と N を返す。"""
    N = 1
    for m in moduli:
        N *= m
    x = 0
    for r, m in zip(residues, moduli):
        Ni = N // m
        x += r * Ni * pow(Ni, -1, m)
    return x % N, N

def iroot(k, x):
    """k 乗が x 以下になる最大の整数を二分探索で求める。"""
    lo, hi = 0, 1 << (x.bit_length() // k + 1)
    while lo < hi:
        mid = (lo + hi + 1) // 2
        if mid ** k <= x:
            lo = mid
        else:
            hi = mid - 1
    return lo

ns = [47 * 59, 53 * 71, 83 * 89]   # 3 人の受信者の法(公開指数はどれも e = 3)
cs = [pow(2026, 3, n) for n in ns] # 盗聴者が集めた 3 つの暗号文
x, N = crt(cs, ns)
print(cs, x, iroot(3, x))

実行結果は [1864, 1622, 3199] 8316073576 2026 で、x=20263x = 2026^3 から平文が復元される。素因数分解は一切していない。

(4) 共通法. 同じ nn を複数の利用者で共有し、公開指数 e1,e2e_1, e_2 だけを変えるのは危険である。定理 2.6 により、自分の (e1,d1)(e_1, d_1) を知る利用者は nn を素因数分解でき、他人の d2d_2 も計算できる。外部の攻撃者でも、同じ mm が gcd⁡(e1,e2)=1\gcd(e_1, e_2) = 1 の 2 つの指数で暗号化されていれば、ue1+ve2=1ue_1 + ve_2 = 1 となる整数 u,vu, v をとって c1uc2v≡mue1+ve2=mc_1^u c_2^v \equiv m^{ue_1 + ve_2} = m と平文を得る(負の指数は法 nn の逆元で計算する。問題 2.3)。

これらの弱点を防ぐのがパディング(平文の符号化)である。OAEP(ベラーレ–ロガウェイ、1994 年)の考え方を示す。ハッシュ関数 G,HG, H と乱数 rr を使い、

X=(m∥0k1)⊕G(r),Y=r⊕H(X)X = (m \mathbin{\Vert} 0^{k_1}) \oplus G(r), \qquad Y = r \oplus H(X)

として、ビット列 X∥YX \mathbin{\Vert} Y(∥\mathbin{\Vert} は連結)を整数とみて ee 乗する。復号では X,YX, Y から r=Y⊕H(X)r = Y \oplus H(X)、m∥z=X⊕G(r)m \mathbin{\Vert} z = X \oplus G(r) を計算し、z=0k1z = 0^{k_1} でなければ拒否する。乱数 rr により暗号化は確率的になり((1) の対策)、符号化は nn とほぼ同じ長さになり((3) の対策)、でたらめに作った暗号文はほぼ確実に拒否されるので積の関係も使えない((2) の対策)。RSA-OAEP は、ハッシュ関数を理想化したモデル(ランダムオラクルモデル)のもとで、RSA 問題が難しいと仮定すれば選択暗号文攻撃に対して安全であることが証明されている。署名用には、乱数(ソルト)とハッシュ値から符号化を作る PSS が同様の役割を果たす。細部は PKCS #1(RFC 8017)で規定されている。

ヒント

実務では RSA を自分で実装したり、教科書的 RSA を使ったりしてはいけない。暗号化には RSA-OAEP、署名には RSA-PSS を、実績のあるライブラリで使う。古い PKCS #1 v1.5 形式の暗号化パディングは、復号時の形式チェックの成否が外部から観測できると、それを手がかりに暗号文を解読される(1998 年のブライヒェンバッハーの攻撃)。この種の攻撃は実装の細部から何度も再発しており、TLS 1.3 では RSA で鍵を暗号化して送る方式自体が廃止され、RSA は署名にだけ使われる。

2.6 ディフィー–ヘルマン鍵共有

公開の通信路だけで共通鍵を作る方法である。以下、pp を素数、qq を p−1p - 1 を割る素数、g∈(Z/pZ)×g \in (\mathbb{Z}/p\mathbb{Z})^\times を位数 qq の元とし、G=⟨g⟩G = \langle g \rangle とおく(群 GG の位数は qq)。

定義 2.13(ディフィー–ヘルマン鍵共有, Diffie–Hellman key exchange)(p,q,g)(p, q, g) は公開されているとする。アリスは a∈{1,…,q−1}a \in \lbrace 1, \dots, q - 1 \rbrace をランダムに選んで A=ga mod pA = g^a \bmod p を、ボブは bb を選んで B=gb mod pB = g^b \bmod p を送る。アリスは K=Ba mod pK = B^a \bmod p、ボブは K=Ab mod pK = A^b \bmod p を計算する。

Ba=gab=AbB^a = g^{ab} = A^b なので、2 人は同じ KK を得る。盗聴者が見るのは p,q,g,A,Bp, q, g, A, B だけである。

例 2.14 p=467=2⋅233+1p = 467 = 2 \cdot 233 + 1, q=233q = 233(素数), g=4=22g = 4 = 2^2(位数 233233)とする。a=153a = 153, b=197b = 197 なら A=207A = 207, B=97B = 97 で、K=97153≡207197≡193(mod467)K = 97^{153} \equiv 207^{197} \equiv 193 \pmod{467}。

定義 2.15(離散対数に関する問題)G=⟨g⟩G = \langle g \rangle を位数 qq の巡回群とする。

  • 離散対数問題 (DLP):gxg^x から x mod qx \bmod q を求める。
  • 計算ディフィー–ヘルマン問題 (CDH):gx,gyg^x, g^y から gxyg^{xy} を求める。
  • 判定ディフィー–ヘルマン問題 (DDH):(gx,gy,gxy)(g^x, g^y, g^{xy}) と (gx,gy,gz)(g^x, g^y, g^z)(x,y,zx, y, z は一様ランダム)を見分ける。

DLP が解ければ CDH が解け(xx を求めて (gy)x(g^y)^x)、CDH が解ければ DDH が解ける。逆向きは一般には知られていない。DH 鍵共有を盗聴から守るには少なくとも CDH が難しくなければならず、共有した KK を「ランダムな値と見分けがつかない」鍵として使うには DDH の困難さが要る。群の選び方は重要である。

命題 2.16 pp を奇素数、gg を法 pp の原始根とする(G=(Z/pZ)×G = (\mathbb{Z}/p\mathbb{Z})^\times 全体)。このとき ga,gbg^a, g^b から gabg^{ab} のルジャンドル記号が計算でき、DDH は易しい。

証明. オイラーの規準(04-algebra 第1章 定理 1.49)と g(p−1)/2≡−1g^{(p-1)/2} \equiv -1(gg の位数が p−1p - 1 だから)より、(gxp)≡gx(p−1)/2≡(−1)x\left(\frac{g^x}{p}\right) \equiv g^{x(p-1)/2} \equiv (-1)^x。よって (gabp)=(−1)ab\left(\frac{g^{ab}}{p}\right) = (-1)^{ab} は、(gap)=(gbp)=−1\left(\frac{g^a}{p}\right) = \left(\frac{g^b}{p}\right) = -1 のときだけ −1-1 である。ルジャンドル記号は反復二乗法で計算できる。3 つ目の成分のルジャンドル記号がこの予測と一致するかを調べれば、本物の組は必ず一致し、ランダムな gzg^z は確率 1/21/2 でしか一致しないので、見分けられる。□\square

そこで実用では、qq が十分大きい素数となる部分群(例 2.14 のように安全素数 p=2q+1p = 2q + 1 の平方剰余の群など)を使う。群の位数が小さい素因数だけの積だと、離散対数はポーリッヒ–ヘルマン法で易しくなる(第3章)。SP 800-57 は、112 ビットの安全性に pp を 2048 ビット、qq を 224 ビットとする組を対応させている。

2.7 エルガマル暗号

DH 鍵共有の片方を固定の公開鍵にすると、公開鍵暗号ができる(エルガマル、1985 年)。

定義 2.17(エルガマル暗号, ElGamal encryption)群 G=⟨g⟩G = \langle g \rangle(位数 qq)は 2.6 節のとおりとする。秘密鍵は x∈{1,…,q−1}x \in \lbrace 1, \dots, q - 1 \rbrace、公開鍵は h=gxh = g^x。平文 m∈Gm \in G に対し、k∈{1,…,q−1}k \in \lbrace 1, \dots, q - 1 \rbrace を暗号化のたびにランダムに選び、暗号文を (c1,c2)=(gk,mhk)(c_1, c_2) = (g^k, mh^k) とする。復号は m=c2(c1x)−1m = c_2 (c_1^x)^{-1}。

命題 2.18 (1) エルガマル暗号は正しく復号できる。(2) 公開鍵と暗号文から平文をつねに求めるアルゴリズムと、CDH をつねに解くアルゴリズムは、一方から他方を多項式時間で構成できる。

証明. (1) c1x=gkx=hkc_1^x = g^{kx} = h^k なので c2(c1x)−1=mc_2(c_1^x)^{-1} = m。(2) CDH が解ければ、h=gxh = g^x と c1=gkc_1 = g^k から hk=gxkh^k = g^{xk} を求めて m=c2(hk)−1m = c_2(h^k)^{-1}。逆に復号アルゴリズムがあれば、gx,gyg^x, g^y に対し公開鍵 h=gxh = g^x、暗号文 (gy,1)(g^y, 1) を与えると m=(gxy)−1m = (g^{xy})^{-1} が返るので、gxy=m−1g^{xy} = m^{-1}。□\square

例 2.19 例 2.14 の群で x=127x = 127 とすると h=4127 mod 467=145h = 4^{127} \bmod 467 = 145。m=100=102m = 100 = 10^2(平方剰余なので GG の元)を k=213k = 213 で暗号化すると (c1,c2)=(374,122)(c_1, c_2) = (374, 122)。復号では c1x=374127≡160c_1^x = 374^{127} \equiv 160 で、122⋅160−1≡100(mod467)122 \cdot 160^{-1} \equiv 100 \pmod{467}。

エルガマル暗号は乱数 kk を使うので確率的である。一方、(c1,tc2)(c_1, tc_2) は tmtm の暗号文になる(準同型性)ので、選択暗号文攻撃には弱い。また kk を使い回すと平文の比が漏れる(問題 2.5)。実用では DH 鍵共有で共通鍵を作り、データは共通鍵暗号で暗号化する方式が主流である。

2.8 デジタル署名アルゴリズム(DSA)

DSA は、エルガマルの署名方式を素数位数の部分群に移して短くした方式で、米国の規格 FIPS 186 として 1994 年に制定された。

定義 2.20(DSA)公開パラメータを素数 p,qp, q(q∣p−1q \mid p - 1)と位数 qq の元 g∈(Z/pZ)×g \in (\mathbb{Z}/p\mathbb{Z})^\times とする。秘密鍵は x∈{1,…,q−1}x \in \lbrace 1, \dots, q - 1 \rbrace、公開鍵は y=gx mod py = g^x \bmod p。hh をメッセージのハッシュ値(qq のビット長に切り詰めた整数)とする。

  • 署名:秘密の乱数 k∈{1,…,q−1}k \in \lbrace 1, \dots, q - 1 \rbrace を署名のたびに選び、r=(gk mod p) mod qr = (g^k \bmod p) \bmod q, s=k−1(h+xr) mod qs = k^{-1}(h + xr) \bmod q とする。r=0r = 0 または s=0s = 0 なら kk を選び直す。署名は (r,s)(r, s)。
  • 検証:0<r<q0 < r < q, 0<s<q0 < s < q を確かめ、w=s−1 mod qw = s^{-1} \bmod q, u1=hw mod qu_1 = hw \bmod q, u2=rw mod qu_2 = rw \bmod q, v=(gu1yu2 mod p) mod qv = (g^{u_1}y^{u_2} \bmod p) \bmod q とし、v=rv = r なら受理する。

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

証明. s≢0s \not\equiv 0 なので ww が定まり、s≡k−1(h+xr)s \equiv k^{-1}(h + xr) より h+xr≡sk(modq)h + xr \equiv sk \pmod q。よって u1+xu2≡w(h+xr)≡wsk≡k(modq)u_1 + xu_2 \equiv w(h + xr) \equiv wsk \equiv k \pmod{q}。gg の位数は qq なので gu1yu2=gu1+xu2=gkg^{u_1}y^{u_2} = g^{u_1 + xu_2} = g^k が法 pp で成り立ち、v=(gk mod p) mod q=rv = (g^k \bmod p) \bmod q = r。□\square

例 2.22 (p,q,g)=(467,233,4)(p, q, g) = (467, 233, 4), x=127x = 127, y=145y = 145, h=100h = 100, k=51k = 51 とする。gk mod p=289g^k \bmod p = 289 より r=289 mod 233=56r = 289 \bmod 233 = 56。k−1 mod 233=32k^{-1} \bmod 233 = 32 で、s=32⋅(100+127⋅56) mod 233=32⋅222 mod 233=114s = 32 \cdot (100 + 127 \cdot 56) \bmod 233 = 32 \cdot 222 \bmod 233 = 114。検証では w=114−1 mod 233=186w = 114^{-1} \bmod 233 = 186, u1=193u_1 = 193, u2=164u_2 = 164 で、4193⋅145164≡243⋅55≡289(mod467)4^{193} \cdot 145^{164} \equiv 243 \cdot 55 \equiv 289 \pmod{467} より v=56=rv = 56 = r。

kk が漏れたり、2 つの署名で同じ kk を使ったりすると、秘密鍵 xx が計算されてしまう(問題 2.6。楕円曲線版の ECDSA での詳しい分析は第4章)。なお FIPS 186-5(2023 年 2 月)では、DSA は署名の生成には承認されなくなり(この規格の実施日より前に作られた署名の検証には使える)、承認される署名方式は RSA・ECDSA・EdDSA の 3 つになった。

2.9 中間者攻撃と公開鍵基盤

DH 鍵共有の A,BA, B には「誰が送ったか」の情報がない。通信路を書き換えられる攻撃者マロリーは、アリスの AA を自分の Z=gzZ = g^z にすり替えてボブに渡し、ボブの BB も ZZ にすり替えてアリスに渡す。アリスは gazg^{az} を、ボブは gbzg^{bz} を「共有した鍵」と思い込むが、マロリーは両方を計算でき、2 人の通信を復号・改ざんして中継できる(中間者攻撃, man-in-the-middle attack。問題 2.4)。数学的にはどの計算問題も解いていない。

防ぐには、受け取った公開鍵が本当に相手のものかを確かめる必要がある。公開鍵基盤 (PKI) では、認証局 (CA) が「この公開鍵はこのドメイン名の持ち主のもの」という文書(証明書)にデジタル署名する。ブラウザや OS は少数のルート認証局の公開鍵をあらかじめ信頼しており、証明書の署名の連鎖をたどって検証する。TLS 1.3 では、サーバーは使い捨ての DH(または楕円曲線 DH)の値を送り、証明書の秘密鍵でそれまでのやりとり全体に署名する。すり替えれば署名の検証に失敗する。使い捨ての DH 鍵を使うので、後でサーバーの秘密鍵が漏れても過去の通信は解読されない(前方秘匿性, forward secrecy)。

ヒント

実務では 暗号の多くの事故は、数学ではなく「鍵が本物か」の確認の不備から起こる。証明書の検証を無効にする設定(テストのために入れて本番に残るなど)は、中間者攻撃をそのまま許す。逆に、認証局が誤って発行した証明書は信頼の連鎖そのものを壊すので、失効の仕組みや、発行されたすべての証明書を公開記録する証明書透明性(Certificate Transparency)などの運用上の対策が重ねられている。

2.10 安全性の定義

「安全」を数学的に定義すると、証明できることとできないことがはっきりする。攻撃者は確率的多項式時間のアルゴリズムとし、鍵の長さを表すセキュリティパラメータ κ\kappa(カーマイケル関数 λ(n)\lambda(n) と区別するため κ\kappa と書く)について、任意の多項式の逆数より速く 00 に近づく関数を無視できる (negligible) という。

  • 一方向性(OW-CPA):公開鍵とランダムな平文の暗号文から、平文全体を求められる確率が無視できる。
  • 識別不可能性(IND-CPA):次のゲームで攻撃者が勝つ確率と 1/21/2 の差(優位)が無視できる。(i) 鍵を生成し、攻撃者に公開鍵を渡す。(ii) 攻撃者が同じ長さの平文 m0,m1m_0, m_1 を選ぶ。(iii) 一様ランダムな b∈{0,1}b \in \lbrace 0, 1 \rbrace について mbm_b の暗号文を渡す。(iv) 攻撃者は bb を当てれば勝ち。
  • IND-CCA2:IND-CPA のゲームで、攻撃者は (iii) の暗号文以外なら何でも復号してもらえる。

IND-CPA は「暗号文から平文の部分的な情報(偶奇や大小関係など)さえ漏れない」ことを表す、一方向性よりずっと強い要求である。

命題 2.23 暗号化が決定的な(乱数を使わない)公開鍵暗号は、IND-CPA 安全ではない。

証明. 攻撃者は相異なる m0,m1m_0, m_1 を選び、受け取った暗号文 cc と、自分で公開鍵を使って計算した m0m_0 の暗号文を比べ、一致すれば b=0b = 0、しなければ b=1b = 1 と答える。復号できる方式では m0≠m1m_0 \neq m_1 の暗号文は異なるので、つねに勝つ。□\square

したがって教科書的 RSA は IND-CPA 安全でない。準同型性をもつ方式(教科書的 RSA、エルガマル暗号)は、例 2.10 のように問題の暗号文を変形して復号してもらえるので IND-CCA2 安全でない。一方、次のことが仮定のもとで証明されている(本書では主張のみ):素数位数の群でのエルガマル暗号は DDH 仮定のもとで IND-CPA 安全である。RSA-OAEP はランダムオラクルモデルと RSA 仮定のもとで IND-CCA2 安全である。署名については「好きなメッセージに署名してもらえても、新しいメッセージの署名を作れない」(EUF-CMA)が標準的な定義で、教科書的 RSA 署名は例 2.9 により満たさないが、RSA-PSS はランダムオラクルモデルと RSA 仮定のもとで満たす。

これらの証明はどれも「攻撃者がいれば、仮定した難しい問題を解くアルゴリズムが作れる」という帰着の形をしている。証明された安全性とは、仮定が正しい限りでの安全性である。

まとめ

  • 共通鍵暗号には鍵配送問題がある。ワンタイムパッドは完全秘匿だが、鍵の使い回しで破れる。
  • 公開鍵暗号の安全性は、一方向性関数の存在という未証明の仮定と、長年の解析という経験的根拠に依存する。
  • RSA の正しさ med≡m(modpq)m^{ed} \equiv m \pmod{pq}(ed≡1 mod λ(n)ed \equiv 1 \bmod \lambda(n))は、gcd⁡(m,n)≠1\gcd(m, n) \neq 1 の場合も含めて成り立つ。秘密鍵 dd を知れば nn は確率的に素因数分解できる。
  • 教科書的 RSA は決定的で準同型性をもち、小さい指数・同報・共通法の攻撃に弱い。OAEP・PSS のパディングで防ぐ。
  • DH 鍵共有・エルガマル暗号・DSA は素数位数の部分群で使う。DH とエルガマルの安全性は CDH・DDH の困難さに、DSA は少なくとも離散対数の困難さに依存する。原始根で生成される群全体ではルジャンドル記号が漏れる。
  • DSA の秘密の乱数 kk の再利用は秘密鍵を漏らす。
  • 認証のない鍵共有は中間者攻撃に弱く、証明書と公開鍵基盤で公開鍵の持ち主を保証する。
  • 安全性の定義(OW-CPA, IND-CPA, IND-CCA2, EUF-CMA)と帰着による証明は、仮定のもとでの安全性を与える。推奨鍵長は規格とともに変わる。

演習問題

問題 2.1 ★ p=67p = 67, q=79q = 79, e=5e = 5 で RSA の鍵を作る。nn, λ(n)\lambda(n), d=e−1 mod λ(n)d = e^{-1} \bmod \lambda(n) を求め、平文 m=2026m = 2026 を暗号化せよ。さらに中国剰余定理(第1章 命題 1.9)を使って復号せよ(冪剰余の計算には計算機を使ってよい)。

解答

n=5293n = 5293, λ(n)=lcm⁡(66,78)=858\lambda(n) = \operatorname{lcm}(66, 78) = 858。互除法 858=171⋅5+3858 = 171 \cdot 5 + 3, 5=3+25 = 3 + 2, 3=2+13 = 2 + 1 を逆にたどると 1=2⋅858−343⋅51 = 2 \cdot 858 - 343 \cdot 5 なので、d=−343 mod 858=515d = -343 \bmod 858 = 515。暗号化:20262≡26012026^2 \equiv 2601, 20264≡26012≡7472026^4 \equiv 2601^2 \equiv 747, c=20265≡747⋅2026≡4917(mod5293)c = 2026^5 \equiv 747 \cdot 2026 \equiv 4917 \pmod{5293}。復号:dp=515 mod 66=53d_p = 515 \bmod 66 = 53, dq=515 mod 78=47d_q = 515 \bmod 78 = 47, c mod 67=26c \bmod 67 = 26, c mod 79=19c \bmod 79 = 19 から mp=2653 mod 67=16m_p = 26^{53} \bmod 67 = 16, mq=1947 mod 79=51m_q = 19^{47} \bmod 79 = 51。79−1 mod 67=2879^{-1} \bmod 67 = 28 より h=(16−51)⋅28 mod 67=25h = (16 - 51) \cdot 28 \bmod 67 = 25、m=51+79⋅25=2026m = 51 + 79 \cdot 25 = 2026。(2026 mod 67=162026 \bmod 67 = 16, 2026 mod 79=512026 \bmod 79 = 51 で、mp,mqm_p, m_q が平文の剰余になっていることも確かめられる。)

問題 2.2 ★★ (1) n=45=32⋅5n = 45 = 3^2 \cdot 5, e=d=5e = d = 5 とすると ed≡1(modφ(n))ed \equiv 1 \pmod{\varphi(n)} だが、m=3m = 3 について med≢m(mod45)m^{ed} \not\equiv m \pmod{45} となることを確かめよ。(2) 一般に、素数 pp について p2∣np^2 \mid n ならば、e≥2e \geq 2 のとき x↦xe mod nx \mapsto x^e \bmod n は単射でないことを示せ。RSA の nn が平方因子をもってはいけない理由を説明せよ。

解答

(1) φ(45)=24\varphi(45) = 24 で 25≡125 \equiv 1。3253^{25} は 99 の倍数で、法 55 ではフェルマーの小定理より 325=3⋅(34)6≡33^{25} = 3 \cdot (3^4)^6 \equiv 3。よって 325 mod 453^{25} \bmod 45 は x≡0(mod9)x \equiv 0 \pmod 9, x≡3(mod5)x \equiv 3 \pmod 5 の解 1818 であり、33 に戻らない。

(2) u=n/pu = n/p とおくと u≢0(modn)u \not\equiv 0 \pmod{n} だが、u2=n⋅(n/p2)u^2 = n \cdot (n/p^2) は nn の倍数なので ue≡0=0e(modn)u^e \equiv 0 = 0^e \pmod{n}。異なる 2 元 u,0u, 0 が同じ値に写るので単射でない。したがってどんな dd を選んでも uu と 00 の両方を正しく復号することはできない。定理 2.4 の証明では、p∣mp \mid m のとき両辺が法 pp で 00 になることを使ったが、法 p2p^2 ではこの議論が成り立たない。

問題 2.3 ★★(共通法攻撃)同じ法 n=3233n = 3233 で、公開指数 e1=17e_1 = 17 と e2=7e_2 = 7 の 2 人に同じ平文 mm が送られ、暗号文 c1=2183c_1 = 2183, c2=1844c_2 = 1844 が盗聴された。mm を求めよ。

解答

gcd⁡(17,7)=1\gcd(17, 7) = 1 で、17=2⋅7+317 = 2 \cdot 7 + 3, 7=2⋅3+17 = 2 \cdot 3 + 1 を逆にたどると 1=7−2⋅3=7−2(17−2⋅7)=5⋅7−2⋅171 = 7 - 2 \cdot 3 = 7 - 2(17 - 2 \cdot 7) = 5 \cdot 7 - 2 \cdot 17。よって m=m−2⋅17+5⋅7≡c1−2c25(modn)m = m^{-2 \cdot 17 + 5 \cdot 7} \equiv c_1^{-2}c_2^5 \pmod{n}。gcd⁡(c1,n)=1\gcd(c_1, n) = 1 で、c1−1 mod 3233=2454c_1^{-1} \bmod 3233 = 2454, c1−2≡24542≡2270c_1^{-2} \equiv 2454^2 \equiv 2270, c25≡3037c_2^5 \equiv 3037 より、m≡2270⋅3037≡1234m \equiv 2270 \cdot 3037 \equiv 1234。実際 123417≡21831234^{17} \equiv 2183, 12347≡1844(mod3233)1234^7 \equiv 1844 \pmod{3233} である。

問題 2.4 ★ p=23p = 23, g=4g = 4(位数 1111)で DH 鍵共有を行う。(1) a=3a = 3, b=7b = 7 のとき A,BA, B と共有鍵 KK を求めよ。(2) マロリーが z=5z = 5 で中間者攻撃をするとき、アリスとボブがそれぞれ計算する鍵と、マロリーがそれらを計算できることを確かめよ。

解答

(1) A=43=64≡18A = 4^3 = 64 \equiv 18, B=47≡8(mod23)B = 4^7 \equiv 8 \pmod{23}(42=164^2 = 16, 44≡34^4 \equiv 3, 47=44⋅42⋅4≡192≡84^7 = 4^4 \cdot 4^2 \cdot 4 \equiv 192 \equiv 8)。K=Ba=83=512≡6K = B^a = 8^3 = 512 \equiv 6。確かに Ab=187≡6A^b = 18^7 \equiv 6 でもある。

(2) Z=45=1024≡12Z = 4^5 = 1024 \equiv 12。アリスは Za=123=1728≡3Z^a = 12^3 = 1728 \equiv 3、ボブは Zb=127≡16Z^b = 12^7 \equiv 16 を鍵とする。マロリーは Az=185≡3A^z = 18^5 \equiv 3, Bz=85≡16B^z = 8^5 \equiv 16 を計算でき、両方の鍵を知る。アリスとボブの鍵は一致しないが、マロリーが一方の鍵で復号して他方の鍵で暗号化し直して中継すれば、2 人は気づかない。

問題 2.5 ★★(ナンスの再利用)例 2.19 の公開鍵 h=145h = 145(p=467p = 467, g=4g = 4)で、ある装置が同じ乱数 kk を使い回した。平文 m1=100m_1 = 100 の暗号文が (374,122)(374, 122) であることを攻撃者は知っている。同じ装置の別の暗号文 (374,3)(374, 3) の平文を求めよ。

解答

c1c_1 が同じなので kk が同じで、c2=m1hkc_2 = m_1 h^k, c2′=m2hkc_2' = m_2 h^k より m2=c2′c2−1m1m_2 = c_2' c_2^{-1} m_1。122−1 mod 467=356122^{-1} \bmod 467 = 356 なので m2=3⋅356⋅100 mod 467=324m_2 = 3 \cdot 356 \cdot 100 \bmod 467 = 324(=182= 18^2)。秘密鍵を知らなくても、既知の平文が 1 つあれば同じ kk の暗号文はすべて解読される。kk は暗号化のたびに CSPRNG で新しく選ばなければならない。

問題 2.6 ★★(DSA の乱数の再利用)例 2.22 のパラメータで、同じ kk を使った 2 つの署名 (r,s1)=(56,114)(r, s_1) = (56, 114)(ハッシュ値 h1=100h_1 = 100)と (r,s2)=(56,195)(r, s_2) = (56, 195)(h2=37h_2 = 37)が見つかった。kk と秘密鍵 xx を求めよ。

解答

si≡k−1(hi+xr)s_i \equiv k^{-1}(h_i + xr) より s1−s2≡k−1(h1−h2)(modq)s_1 - s_2 \equiv k^{-1}(h_1 - h_2) \pmod{q} なので、k≡(h1−h2)(s1−s2)−1k \equiv (h_1 - h_2)(s_1 - s_2)^{-1}。s1−s2≡−81≡152s_1 - s_2 \equiv -81 \equiv 152, 152−1 mod 233=23152^{-1} \bmod 233 = 23 より k≡63⋅23=1449≡51k \equiv 63 \cdot 23 = 1449 \equiv 51。次に x≡(s1k−h1)r−1x \equiv (s_1 k - h_1)r^{-1} で、s1k−h1=5714≡122s_1 k - h_1 = 5714 \equiv 122, 56−1 mod 233=12956^{-1} \bmod 233 = 129 より x≡122⋅129≡127(mod233)x \equiv 122 \cdot 129 \equiv 127 \pmod{233}。検算:4127≡145=y(mod467)4^{127} \equiv 145 = y \pmod{467}。

問題 2.7 ★★ 素数 pp と原始根 gg で、群 (Z/pZ)×(\mathbb{Z}/p\mathbb{Z})^\times 全体をそのまま使ってエルガマル暗号を作る(公開鍵 h=gxh = g^x)。平文 m0m_0 を平方剰余、m1m_1 を平方非剰余に選ぶ攻撃者は、IND-CPA のゲームでつねに勝てることを示せ。

解答

暗号文 (c1,c2)=(gk,mbhk)(c_1, c_2) = (g^k, m_b h^k) について、命題 2.16 の証明と同じく (c1p)=(−1)k\left(\frac{c_1}{p}\right) = (-1)^k, (hp)=(−1)x\left(\frac{h}{p}\right) = (-1)^x が計算でき、(hkp)=(−1)xk\left(\frac{h^k}{p}\right) = (-1)^{xk} は「(hp)=(c1p)=−1\left(\frac{h}{p}\right) = \left(\frac{c_1}{p}\right) = -1 のときだけ −1-1」として求まる。ルジャンドル記号は乗法的なので (mbp)=(c2p)(hkp)\left(\frac{m_b}{p}\right) = \left(\frac{c_2}{p}\right)\left(\frac{h^k}{p}\right) が計算でき、これが 11 なら b=0b = 0、−1-1 なら b=1b = 1 と答えればつねに正しい。これが、素数位数の部分群(平方剰余の群など)を使う理由である。

問題 2.8 ★(この設計のどこが危ないか)ある社内システムは、人事評価 A〜E を教科書的 RSA(e=65537e = 65537, 2048 ビットの nn)で暗号化してデータベースに保存している。「2048 ビットの RSA なので安全」という説明の誤りを指摘し、改善策を述べよ。

解答

教科書的 RSA は決定的なので、公開鍵を知る者は A〜E の 5 通りをすべて暗号化してデータベースの値と比べるだけで、すべての評価を読める(命題 2.23 の攻撃そのもの)。鍵の長さが効くのは素因数分解による攻撃に対してだけで、平文の候補が少ないことによる弱さは防がない。さらに同じ評価の人どうしは暗号文が一致するので、評価の分布も漏れる。改善策は、乱数を含むパディング(RSA-OAEP)を使うか、より一般にハイブリッド暗号(ランダムな共通鍵を公開鍵で暗号化し、データは認証つき共通鍵暗号で暗号化する)を実績のあるライブラリで使うことである。

この章を読み終えたら

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

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