Hash

我們可以使用密碼散列函式來生成無限隨機數嗎?

  • December 13, 2019

我已經看到有 PRNG 可以生成特定數量的隨機數。以 Mersenne Twister 為例,它可以生成 2**19937 (如果我沒記錯的話)但是……我們可以使用加密雜湊函式來生成無限隨機數,並為其設置任何種子嗎?所以我可以為種子設置文本並這樣做:

seed set to "myseed"
counter set to 0
first random number generated = first 64 bits of "myseed0" hashed with sha512
secound number = first 64 bits of "myseed1" hashed with sha512

或者我們可以保存剩下的其他 448 位,稍後再使用。主要思想是,從散列函式生成 PRN 是否 100% 安全?我們為什麼不這樣做?

這種結構為您提供了加密質量的偽隨機輸出,但它不如隨機生成器那樣安全。

配合常用的散列函式 $ H $ (如任何 SHA2 和 SHA3 系列),據我們所知, $ H(\textrm{seed}, n) $ 如果你只知道是不可預測的 $ n $ 和 $ H(\textrm{seed}, m_i) $ 對於任意數量的值 $ m_i \ne n $ ,但你不知道 $ \textrm{seed} $ . 這使得 $ D(n) = H(\textrm{seed}, n) $ 一個好的密鑰推導函式:它的輸出基本上與隨機無法區分。

一個好的隨機生成器必須具有這樣的特性:即使對手知道輸出的所有其他位,但不知道種子,輸出中的位是不可預測的。那個工程 $ H(\textrm{seed}, \textrm{counter}) $ 有這個屬性。但是一個好的隨機生成器還有一個額外的屬性:回溯阻力。回溯阻力意味著如果對手在某個時候破壞了雜湊狀態,那麼他們就無法恢復過去的輸出。(當然,對手會知道每個未來的輸出,至少在重新播種隨機生成器之前。)您的構造不具有此屬性,因為原始種子仍然是雜湊狀態的一部分。

一個好的隨機生成器有一個“棘輪”步驟,這使得在生成一些輸出時無法從目前狀態恢復之前的狀態。使用散列函式很容易建構棘輪:您基本上只需在散列狀態上執行散列函式。取一個散列函式 $ n $ 位輸出。從一個開始 $ n $ -位秘密種子;那是隨機發生器的原始狀態。最多生成 $ n $ 偽隨機位,計算 $ H(0 || \textrm{state}) $ 並輸出;還要計算 $ H(1 || \textrm{state}) $ 並將其用作下一個內部狀態。在虛擬碼中:

state = seed
while True:
   output(hash('0' + state))
   state = hash('1' + state)

Hash_DRBGNIST SP 800-90A中指定的一種流行的偽隨機生成器構造基於此原理。

引用自:https://crypto.stackexchange.com/questions/76382