比特幣中的雙重雜湊在哪裡執行?
SHA256(SHA256(x))在比特幣協議中的哪個位置執行,為什麼?
比特幣幾乎在任何地方都使用雙重雜湊,它以兩種變體之一進行雜湊:
RIPEMD160(SHA256(x)) 稱為 Hash160,產生 160 位輸出
- 散列公鑰以生成部分比特幣地址
SHA256(SHA256(x)) 稱為 Hash256,產生 256 位輸出
- 在比特幣地址中生成校驗和
- 在默克爾樹中散列塊
- 連接交易輸出和輸入
- 塊頭的雜湊(以及工作證明和前一個塊的連結)
似乎中本聰在碰撞成為問題時選擇了 Hash256,而在只有(多目標)第二個原像很重要時選擇了 Hash160。這與實現 128 位安全性的目標是一致的。
您需要 2n 位散列來實現 n 位抗碰撞性,並且您需要 atn 位散列來實現 n 位秒前像抗性。如果我們假設保守的 40 億個目標和 128 位安全級別,這將導致 256 位散列用於抗碰撞性和 160 位散列用於多目標第二原像。
那麼他為什麼要雜湊兩次呢?我懷疑這是為了防止長度擴展攻擊。
SHA-2 與所有 Merkle-Damgard 雜湊一樣,都具有稱為“長度擴展”的屬性。這允許知道 H(x) 的攻擊者在不知道 x 的情況下計算 H(x||y)。這通常不是問題,但在某些用途中它完全破壞了安全性。最相關的例子是使用 H(k||m) 作為 MAC,攻擊者可以很容易地計算出 m||m’ 的 MAC。我認為比特幣從來沒有以一種會受到長度擴展影響的方式使用雜湊,但我猜中本聰選擇了在任何地方都防止它的安全選擇。
為了避免這個屬性,Ferguson 和 Schneier 建議使用 SHA256d = SHA256(SHA256(x)) 來避免長度擴展攻擊。這種結構有一些小弱點(與比特幣無關),所以我不建議將它用於新協議,而是使用帶有常量密鑰的 HMAC,或者截斷 SHA512。
一些相關閱讀:
- 散列或加密兩次以提高安全性?在crypto.SE上
- 雙重雜湊的密碼推理?關於比特幣談話
這是主要的雜湊函式:
template<typename T1> inline uint256 Hash(const T1 pbegin, const T1 pend) { static unsigned char pblank[1]; uint256 hash1; SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1); uint256 hash2; SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2); return hash2; }
我會說任何呼叫兩次使用 SHA256 的地方。
至於為什麼,看這個。