d0tfi1e’s blog

趣味と日記

ROCAと離散対数問題

ROCA

原論文はhttps://acmccs.github.io/papers/p1631-nemecA.pdfです。

RSALibで生成された素数を利用したRSA暗号に関する脆弱性です。

RSALibで生成される素数の特徴

本記事では512bitの例を扱います。RSALibで生成される素数は次のような形をしています。

 p = kM + \mathrm{pow}(65537,  a, M)

 \mathrm{pow}(e,  a, M) Mを法とした e a乗を表します。ここで、 M = P_{39}\#素数を小さい順に39個かけ合わせた数です。

 pを決定するパラメータは37bitの kおよび62bitの aだけで、99bitの空間しかなく、512bitの素数全体の空間にくらべ非常に小さいです。

さて、この特徴をもつ素数から生成される公開鍵 n = p \cdot qは次の特徴をもちます。

(特徴)合同式 n \equiv 65537 ^ x (\mathrm{mod} M)が解 xをもつ

 n \equiv 65537 ^ x (\mathrm{mod} M)を解く

本来離散対数問題を解くのはとてもむずかしいのですが、この場合は手元のPythonでも数秒もかからず解けてしまいます。

方針はシンプルで、まず M = P_{39}\# = \prod p_iとなる各 p_iに対しもとの方程式を分解して

 n \equiv 65537^{x_i} (\mathrm{mod} p_i)

の形の連立合同式にします。

それぞれの合同式は全探索することに簡単に解けます。 p_iは非常に小さいですから、 x_iを0から p_i - 1まで動かしてみて、 nと合同になるものを調べていきます。 なお、そのような x_iが見つからなかった場合、もとの方程式にも解がないことになりますので、その場合 nRSALibによって生成された素数からなる公開鍵ではありません

 x_iが見つかったとします( a_iと置きましょう)。次に、65537の位数を調べます。つまり、 65537^{q_i} \equiv 1 (\mathrm{mod} p_i)となるような最小の q_iを探します。 q_i巡回群の性質より必ず存在し、合同式の解は x_i = a_i + m \cdot q_iの形で一般化されます。

 q_iを探す作業もたかだか p_i回の探索で見つかるので十分高速です。

これらの合同式をそれぞれ解き、最後に中国剰余定理により連立合同式の解が一般に求められます。  q_i合成数のとき、中国剰余定理が使えないと思うかもしれませんが、 q_iの各素因数について、 x_i = a_i + m \cdot q_i q_iをそれぞれの素因数に置き換えた合同式が成り立つので、これらで代用すれば中国剰余定理が使えます。

 x = a + m \cdot q

という形になったとします。しかしこの xはすべてが

 n \equiv 65537 ^ x (\mathrm{mod} M)

を満たすとは限りません。なぜなら q Mに比べて小さいからです。しかし、 m \sim 1000ぐらいまでにはもとの合同式を満たす xにヒットするので順番に mを変えていくことでもとの方程式の解を簡単に調べることができます。

混乱しやすいポイント

連立合同式

 n \equiv 65537^{x_i} (\mathrm{mod} p_i)

を解くとき、法 p_iについて中国剰余定理を使うと思いがちですが、 x_iは法 q_iに関して決まるので、ここに注意してください。 また、 q_iどうしは一般に互いに素とは限りませんから、中国剰余定理の結果得られる解 x M = P_{39}\#よりずっと小さい法に関して決まります

より大きな入力での離散対数問題

ROCAでは、それぞれの合同式を解く際に全探索でも十分高速ですが、全探索が難しくなってくると、Baby-step Giant-stepアルゴリズムや、Pohlig-Hellmanアルゴリズムが活躍するようになってきます。

参考文献

RSA鍵生成脆弱性ROCAの紹介