2017-09-23 538 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計算所需的全部資源,非常易於集成到項目中,並且一個許可證,允許它被集成到任何項目中。