2017-09-23 13 views
2

Diffie-Hellman鍵交換用の秘密鍵(privateKey)を計算する必要があります。私は大きなプライムプライムを与えました、そして、今私はpより小さい数を選ぶ必要があります。これは私のコードです:Diffie-Hellman鍵交換のC++ GMP乱数生成

 mpz_class privateKey; 
     unsigned long seed; 
     mpz_init(privateKey.get_mpz_t()); 

     gmp_randstate_t rstate; 
     gmp_randinit_mt(rstate); 
     gmp_randseed_ui(rstate, seed); 

     mpz_urandomm(privateKey.get_mpz_t(), rstate, prime.get_mpz_t()); 

なぜ私はいつも同じ "ランダム"番号を取得しているのか分かりません。

答えて

2

seed変数を初期化することはないので、プログラムが間違っていて、コンパイラが警告していたはずです。そうでない場合は、コンパイラを正しく設定する方法を調べてください(たとえば、GCCの場合は少なくとも-O -Wallを渡してください)。

同じシードのRNGを初期化すると、常に同じ乱数が得られます。これはおそらくあなたのプログラムで起こっていることでしょう:seedは初期化されていないので、その値は以前このアドレスのスタックにあったものであり、同じ方法でこの関数を呼び出すと、常に同じ値になります。

これは暗号化アプリケーションなので、乱数ジェネレータに高エントロピーソースを設定する必要があります。オペレーティングシステムに問い合わせてください(プログラム内でエントロピーを生成する方法はありません):Linuxの場合は/dev/urandomから、Windowsの場合はCryptGenRandomに電話してください。

また、これは暗号化アプリケーションなので、gmp_randinit_mtを呼び出しないでください。これは、物理シミュレーションのためには速くても十分ですが、その出力から状態を再構築できるため、暗号化には適していないMersenneツイスターを作成します。私はGMPに慣れていませんが、documentationを見ると、乱数生成アルゴリズムがいくつか用意されていますが、セキュリティアプリケーションには適していません。 /dev/urandomCryptGenRandomなどのOSソースをランダムビットのソースとして直接使用できますが、それを使用してgmp_randstate_tインターフェイスを実装してmpz_urandommに接続する必要があります。私はそれがいかに難しいか分からない。

これは学校の練習問題であれば、先生が教えてくれることは何でもしてください。これが実際のアプリケーションの場合は、libtomなどの既存の暗号ライブラリを使用します。これには、暗号品質の乱数を生成し、Diffie-Hellman計算を実行するために必要なものがすべて含まれており、プロジェクトに統合するのは非常に簡単です。どのプロジェクトにも統合できるライセンス。