楕円曲線セキュリティー

10
楕円曲線セキュリティーについて 作:アンダーウッド・ジョナサン

Transcript of 楕円曲線セキュリティー

Page 1: 楕円曲線セキュリティー

楕円曲線セキュリティーについて

作:アンダーウッド・ジョナサン

Page 2: 楕円曲線セキュリティー

概要

・楕円曲線の基本、秘密鍵と公開鍵の関係

・署名時のアルゴリズム

・乱数への依存について

・攻撃ベクトルの事例

・対策

・結論

Page 3: 楕円曲線セキュリティー

楕円曲線1

・y2 = x3 + ax + b mod p という方程式を満たす曲線で、素数に限った平面の点が存在する数が order n に縛られます。

・ビットコインが使う曲線は「 SECp256k1」・定数は a = 0 ; b = 7・p = 2256 - 232 - 29 - 28 - 27 - 26 - 24 -1 (大きな素数)・n = 115,792,089,237,316,195,423,570,985,008,687,907,852,837,564,279,074,904,382,605,163, 141,518,161,494,337・見た目は ⇒ ・でも本当はこうなる⇒

Page 4: 楕円曲線セキュリティー

楕円曲線2

・曲線上に存在する2つの点を通過する直線は必ず 3つ目の点を通過する。

・曲線上に存在する1つの点を通過し、接線となる場合、その接線は必ず 2つ目の点を通過する。

・よって、擬似的な足し算を定義できます。  ー「点Aと点Bを足し合わせて出来る点はその 2つの点をつなぐ直線が通過する 3つ目の点の反転」

・例えば A + B = C の場合: ・A + A = 2A の場合:

*しかし、通過する直線が縦線となった場合、できる点は「インフィニティポイント」と呼ばれ、無効です。

Page 5: 楕円曲線セキュリティー

楕円曲線3

・定数として、ジェネレーターポイント (点)を決めます。

  -SECp256k1の場合: G = (x, y)    x = 55066263022277343669578718895168534326250603453777594175500187360389116729240

    y = 32670510020758816978083085130507043184471273380659243275938904335757337482424

・ G + G + G + G = 4G のようにGを複数回足し合わせると擬似的な掛け算ができます。

・秘密鍵の整数をGに掛けるとできる点が公開鍵である。

・例:秘密鍵=3 G = 緑の点と想定

* 2G + G = 3G

Page 6: 楕円曲線セキュリティー

署名時のアルゴリズム

・楕円曲線の場合、 r と s という2つの値を合わせて「デジタル署名」と言います。

・生成アルゴリズム: (楕円曲線の方程式は基本的に大文字=点、小文字=整数を表します。

  - r = Rx = kG mod p  - s = k-1(z + dr) mod n      -G, p, n は定数、 z は署名したいメッセージのハッシュ、  d は秘密鍵(整数)      -k が秘密鍵のような乱数で全ての取引ごとに新しく生成する必要があります。

・この2つの値と公開鍵 (Q)を使って確認したい場合は下記のように確認します。

  - w = s-1 mod n  - u1 = zw mod n  - u2 = rw mod n  - R = u1G + u2Q  - Rx == r ならば OK、 違えば NG

Page 7: 楕円曲線セキュリティー

乱数の依存について

・秘密鍵生成時

  ー弱い乱数を当てられる=秘密鍵当てられる= アウト

・署名時

  ー署名のr, sを知るだけで、乱数である kが当てられれば、秘密鍵が強くても計算できます。

      - d = r-1(sk - z) mod n  -さらに、k を知らなくても、2つの異なる方程式で同じ k (よって同じ r )使っていれば計算できます。

      - s1 - s2 = k-1(z1 + dr) - k-1(z2 + dr) mod n  *(k と r に1と2は付かない、同じなので )      - s1 - s2 = k-1(z1 - z2) mod n      ー k = (s1 - s2)

-1(z1 - z2) mod n

・乱数の依存を少なくすることが重要

Page 8: 楕円曲線セキュリティー

攻撃ベクトルの事例 (架空)

・社内プログラマーが乱数を出す関数に分かりづらいバグを仕込む。

・社外の人がサーバーの保管されたルームに侵入し、OS自体の乱数を当てられるように改ざん。

・アホなプログラマーのタイプミスで乱数は0~255の間でしか取らないようにしてしまった。(blockchain.info)

Page 9: 楕円曲線セキュリティー

対策

・署名時は決定性署名(RFC6979)を使う。

  -kを生成するために z と d を複数回ハッシュをかけることで、    メッセージか秘密鍵のどっちかがちっとでも変われば異なる kになる。

・秘密鍵生成時はセキュアなカーネルレベルの乱数 を取得すると同時に、ユーザの操作などを読み取って蓄積していき、それらのランダムさを混ぜてハッシュ取ると更に良い。 (マウスの位置が一番手っ取り早い )・秘密鍵はできれば乱数に依存する回数を 少なくしたいので、BIP32の決定性ウォレットを使用すれば、乱数に依存する回数は1ユーザーごとに1回のみ。

Page 10: 楕円曲線セキュリティー

結論

・安全な乱数を出せるようにしないといけません。

・しかし、安全な乱数かどうかはテストができないので、100%乱数に依存しないように仕組みを作るといい。

・ユーザーの動きなどでランダムさを取得して、念のために乱数と合わせてハッシュを取ると良い。

・決定性ウォレットや決定性署名のテストベクトルを実装して、実行してください。(それぞれのコードが悪意ある人に改ざんされていたら終わり。)