HMAC-SHA-512 輸出隨機性?
這是關於一個聲稱是公平的線上輪盤遊戲。這是解釋:
- 創建了兩個字元串:
字元串 1 = "
$$ NONCE $$:$$ SERVER SEED $$:$$ NONCE $$" 字元串 2 = “$$ NONCE $$:$$ CLIENT SEED $$:$$ NONCE $$” 2. HMAC-SHA512 用於作為密鑰進行散列,給我們一個 128 個字元的十六進製字元串
STRING1
。STRING2
3. 十六進製字元串的前 8 個字元被取出並轉換為十進制。 4. 然後將該小數除以 429496.7295 並四捨五入到最接近的整數。 5. 這個整數用作您的點數,最大可能值為 10,000。我的問題是,HMAC-SHA-512 的輸出是 100% 隨機的,以便將其用作這樣的隨機數生成器,或者換句話說,是否有平等的機會擊中任何數字?
HMAC-SHA-512 輸出甚至可以以
"FFFFFFFF"
還是以開頭"00000000"
?在我看來,擊中第一個數字(1 或 0)或最後一個數字(10000)的可能性要低 50%。
出的 $ 10001 $ 可能的輸出
- $ 7295 $ 發生的機率正好等於 $ 429497 $ 在 $ 2^{32} $ .
- $ 2705 $ 發生的機率正好等於 $ 429496 $ 在 $ 2^{32} $ .
- 一個值,特別是值一萬,出現的機率正好等於 $ 1 $ 在 $ 2^{32} $ .
分佈的平均值約為 $ 4999.5 $ . 在該範圍內近似均勻分佈 $ [0, 9999] $ . 它比現實世界的公平骰子分佈更加均勻,但它也是密碼學世界中的一個巨大偏差。
這不是一個大到足以阻止賭徒的偏見。即使僅基於賠率和支出,密碼學家也不會傾向於賭博甚至更公平的賠率(很像關於物理學家會議在維加斯不受歡迎的故事/謠言。但這並不是說有數學頭腦的人可能仍然會非理性或尋找其他玩遊戲的理由。)
忽略價值 $ 10000 $ , 每個 $ 7295 $ 過度表示的值偏離其預期機率的因子為 $ 1.0000006298 $ 和彼此 $ 2705 $ 值偏離一個因子 $ 0.9999983015 $ .
在較小範圍內將一個均勻分佈轉換為另一個均勻分佈的乘法方法(使用精確數學,浮點運算不一定精確)與人們認為的樸素除法餘數(沒有拒絕採樣)方法具有相同的偏差量警告程序員不要使用。然而,乘法方法的偏差更加微妙,因為它不會導致過度表示的元素都是低元素。
對於這個特定的分佈 $ 0 $ , $ 1 $ , 和 $ 2 $ 都略微偏多。 $ 3 $ 代表性略低。 $ 4 $ , $ 5 $ , $ 6 $ 代表過多, $ 7 $ 代表性不足, $ 8 $ , $ 9 $ , $ 10 $ 代表過多, $ 11 $ 和 $ 12 $ 代表過多, $ 13 $ 代表性不足。我認為大多數(或所有)過度代表的元素出現在兩個或三個執行中。並且在一個執行中代表性不足。
至於你描述的協議,我不能說太多細節,因為你的描述並不准確。
我可以說像 SHA-512 和擴展 HMAC-SHA-512 等算法的輸出可以安全地視為所有 512 位長位串的均勻分佈。散列函式通常被建模為**隨機預言**。維基百科將其描述為:
在密碼學中,隨機預言機是一個預言機(理論上的黑匣子),它使用從其輸出域中統一選擇的(真正的)隨機響應來響應每個唯一查詢。如果重複查詢,則每次送出查詢時都會以相同的方式響應。
00000000
雜湊輸出可以以或FFFFFFFF
或任何其他 32 位值開頭。事實上,給定長度的每個可能的前綴 $ n $ 預計每個發生的機率 $ 2^{-n} $ .可以使用散列函式在多方之間創建公平共享的隨機值。兩方選擇一個隨機秘密數字,同時在彼此之間交換這些數字(因此沒有人可以通過改變他們的數字來作弊),並通過對兩個秘密進行散列來創建一個新的商定的共享隨機值。(他們顯然需要就他們散列每個數字的順序達成一致。)
承諾方案用於防止各方在觀察到其他玩家的號碼後更改他們的秘密號碼。他們互相發送自己秘密的雜湊值。他們不會通過交換雜湊值向對方透露他們秘密的實際價值。假設輸入足夠不可預測,僅從散列函式的輸出中確定輸入是不可能的。(具有高熵。)玩家不能在沒有發現雜湊函式衝突的情況下交換他們承諾的秘密值。(使用前置隨機數會使查找碰撞更加困難,因為您不能使用預先計算的碰撞。)
兩個秘密、隨機數以及所涉及的任何其他數據的最終散列會導致來自均勻分佈的隨機值(假設散列函式的行為類似於隨機預言)。散列函式輸入的任何變化都會導致輸出發生不可預測的變化。這意味著只要自己的號碼是隨機選擇的,一方就不必相信對方的秘密是隨機的。
然而,即使使用承諾方案,如果中止協議允許第二個人因不合作而洩露他們的秘密而以比他們因合作而遭受的損失更小的損失離開,那麼仍然有可能作弊。(有點像在輸給另一個玩家時按下游戲機上的重置按鈕的人。或者從桌上翻轉棋盤。)第二個人有足夠的資訊來自己計算遊戲的結果,因此他們可能會假裝自己的電腦崩潰,以避免支付更大的獎金。
再說一次,你對協議的描述是模糊的,所以我們不能說實際的協議是否安全。(即使協議是安全的,實現是否正確也是另一回事。)
這是最著名的加密水龍頭網站之一的滾動系統的機制。我認為上面的先前答案有點誤導。但是,當數學令人困惑時,使用一些程式碼和一些偽隨機生成的數據進行簡單測試應該不會留下任何疑問。
您的聲明:
“..在我看來,第一個數字(1 或 0)或最後一個數字(10000)的可能性降低 50%..”
假設在生成*(32 位)數字時具有良好的熵,由第一個數字產生和表示 $ 4 $ 十六進制數( $ 8 $ hex chars 作為(4 字節)*無符號整數)生成的SHA512摘要,那麼你是對的:
- $ 0 $ (不是 $ 1 $ ) 和 $ 10000 $ 發生頻率低於其他所有滾動數字, $ 50% $ 平均來說更少,(~ $ 0.005% $ 機率而不是~ $ 0.01% $ )
為什麼?關鍵是在削減範圍的 ROUNDING 階段。
- 僅*(32 位)*數字,大於或等於 ( $ 429496.7295 \times 9999.5 $ ),四捨五入為 $ 10000 $ , 從 $ 4294752546.64 $ (~ $ 4294752547 $ ) 至 $ 4294967295 $ , 然後 $ 214749 $ 數字,因為我們僅限於 $ 2^{32} $ 數字。
- 也一樣 $ 0 $ , 每個*(32 位)*整數小於或等於 $ 214748 $ , 舍入為 $ 0 $ , 總共 $ 214749 $ 不同的數字。
- 例如,每隔一個滾動數字 $ 9999 $ , 是對*(32 位)*整數進行四捨五入的結果,範圍為:
- $ 429496.7295 \times 9998.5 $ 至 $ 429496.7295 \times 9999.499\ldots = $ ~ 不少於 $ 429496(.7295) $ 平均數不同。
- 區間中的每個(32 位)整數 $ [4294323050, 4294752546] $ 產生一個 $ 9999 $ 滾動,然後 $ 429497 $ 不同的價值觀。
- 相反,只有區間之間的整數 $ [ 5368710, 5798206 ] $ 四捨五入/滾到數字 $ 13 $ , 然後 $ 429496 $ 不同的價值觀。
- 它幾乎是可以分別四捨五入的*(32 位)*數字範圍的兩倍,以 $ 10000 $ 或者 $ 0 $ .
間隔內有多少卷號未被充分代表 $ [1,9999] $ ?
大約 4 個數字中的 1 個,準確地說 $ 1 $ 在……之外 $ 3.696858.. $ .
我們使用小數部分來計算它:
- $ f = (1-0.7295) = 0.2705 $
- $ t = (1/f) = 3.696858.. $
- $ r = round(9999/t) = 2705 $ 數字
- $ u = 2705 \times 429496 = 1161786680 $ *(32 位)*輸入整數
對於區間中的每個k ,生成第k 個數字****非常簡單 $ [1, 2705] $ ,使用這個公式:
- $ R(k) = round(2 + m \times (k-1)) $
- 第一個, $ R(1) = 2 $
- 最後一個, $ R(2705) = 9998 $
- >
一個簡短的清單是: $ { 2, 6, 9, 13, 17, 20, 24, 28, 32, 35, 39, .., 9987, 9991, 9995, 9998} $
間隔中有多少卷號被過度表示 $ [1,9999] $ ?
- $ 9999 - 2705 = 7294 $
- $ o = 7294 \times 429497 = 3132751118 $ *(32 位)*輸入整數
總共 $ 1161786680 + 3132751118 = 4294537798 $ *(32 位)*輸入整數滾動/舍入到區間中的數字 $ [1, 9999] $ . 剩下的, $ 429498 $ , 滾/滾到 $ 0 $ 或者 $ 10000 $ .
總之:
- $ n = 214748 + 214748 = 429498 $ *(32 位)*整數,四捨五入 $ 0 $ 或者 $ 10000 $
- $ m = (2^{32} - n) = 4294537798 $ *(32 位)*整數在區間內四捨五入 $ [1, 9999] $
所以:
的機率 $ (n/2^{32}) = $ ~ $ 0.01000002958% $ 生產 $ 0 $ 或者 $ 10000 $
的機率 $ (n/2^{33}) = $ ~ $ 0.005000014789% $ 生產 $ 10000 $
的機率 $ (m/2^{32}) = $ ~ $ 99.98999997042% $ 生產任何其他 $ 9999 $ 數字
在區間中選擇了一個數字 $ [1,9999] $ ,平均而言,四捨五入的*(32位)*整數的數量等於:
- $ k = (m/9999) = 429496.7295 $
- 那麼平均機率為 $ (k/2^{32}) = 0.0099999999970% $ 滾動一個特定的數字 $ [1,9999] $ 間隔
- 總機率 = $ (9999 \times k + n )/2^{32}) = 1 $
從區間中隨機選擇一個數字 $ [0, 10000] $ , 我們有:
- $ (u/2^{32}) = 1161786680/2^{32} = 0.2705.. $ 選擇/滾動一個代表性不足的數字的機率(在區間內 $ [1,9999] $ )
- $ (o/2^{32}) = 3132751118/2^{32} = 0.7294.. $ 選擇/滾動過度代表數字的機率(在區間內 $ [1,9999] $ )
- $ (n/2^{32}) = 429498/2^{32} = 0.01.. $ 選擇機率 $ 0 $ 或者 $ 10000 $