Hmac

給定 32 字節的 sha256,確定性選擇 N of M 的最佳方法是什麼?

  • July 14, 2020

我有一個 M=10,000..100,000 個項目和 32 個字節的 sha256 H 的列表。

我想選擇 N=10..100 個項目(無訂單)。

有沒有一種有效的方法來做到這一點?

或者我應該使用類似的東西(sha256hmac(n, H) & 0xFFFFFFFFFFFFFFFF) % N並跳過重複項。(其中 n 為 0..N-1。)

有沒有一種有效的方法來做到這一點?

通過散列一些秘密值提供的 32 字節“良好隨機性”提供的熵比直接計算 100000 列表中的 100 項樣本所需的熵要少得多。如果任何加密目的都需要這樣做,則必須使用良好的 CSPRNG 來轉換你的起始熵變成你需要的盡可能多的隨機性。

如果通過高效您的意思是“單線”,那麼可能不是

或者我應該使用 (sha256hmac(n, H) & 0xFFFFFFFFFFFFFFFF) % N 之類的東西並跳過重複項。(其中 n 為 0..N-1。)

不要試圖滾動你自己的 CSPRNG 來生成你需要的東西

您所描述的(將 HMAC 重複應用到變化的值)大約是 NIST 描述的HMAC_DRBG。如果您想使用這些方法來生成比特流,請改用它,因為它比您描述的要安全得多。

此外,一旦您擁有強大的隨機字節來源(例如 NIST DRBG),僅僅生成一些位是不夠的,比如說 $ k $ 這樣 $ 2^k $ 大於 $ N = 100000 $ ,拿這個模組 $ N $ 並完成它。這樣做時,如 $ N $ 永遠不會完美分裂 $ 2^k $ ,您正在向生成的隨機數引入偏差;越小 $ 2^k $ 與 $ N $ ,偏差越大。在哪裡 $ k $ 是 64,就像你提出的例子一樣,偏差大約是 $ 2^{-48} $ . 這可能看起來不多,但如果我們將可忽略的函式視為 $ 2^{-b} $ , 在哪裡 $ b $ 是某些加密功能的“安全位”,就像我們經常做的那樣,那麼您的 RNG 只有 48 個“安全位”。考慮到我們的目標是接近 256,我建議使用來自 CSPRNG 的完整 32 字節數據字來生成每個索引。

然而,這是一個計算量很大的過程,最好不要以這種方式取模,而是只生成獲得 0 到 0 之間的單個索引所需的最小字節數 $ N $ 如果它們等於或高於的最高倍數,則丟棄這些字節 $ N $ 小於您的字節表示的可能數字。例如,在 3 個字節中,最大。16777216 的可能值:如果該值低於 16700000,則取該 mod $ N $ 並使用結果,否則丟棄它並從 CSPRNG 流中生成 3 個新字節。理論上,這可能需要無限時間才能完成,但平均而言比以前的方法要少。

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