為什麼用特定的緩衝區初始化 SHA1?
SHA-1 使用特定的緩衝區進行初始化:
h0 = 0x67452301 h1 = 0xEFCDAB89 h2 = 0x98BADCFE h3 = 0x10325476 h4 = 0xC3D2E1F0?
為什麼?
Merkle-Damgård 類型散列函式的初始值本質上是分組密碼的明文,散列函式的輸入成為密鑰。散列的最大長度由初始值的位數決定。五個 32 位字為 SHA1 提供了一個狀態大小和 160 位的最大輸出。為了使 MD 類型的散列函式輸出一致的值,初始值必須是恆定的。
前 4 個值是 MD4 和 MD5 中使用的值。它們以大端格式表示。如果用 little-endian 表示,可以看出它是一個簡單的 4 位計數器,從 0000 開始,最大到 1111,然後以 32 位為一組反向退步:
0111 0110 0101 0100 0011 0010 0001 0000 = LE 0x76543210 = BE 0x67452301
1111 1110 1101 1100 1011 1010 1001 1000 = LE 0xFEDCBA98 = BE 0xEFCDAB89
1000 1001 1010 1011 1100 1101 1110 1111 = LE 0x89ABCDEF = BE 0x98BADCFE
0000 0001 0010 0011 0100 0101 0110 0111 = LE 0x01234567 = BE 0x10325476
對於奇數 4 位組,最終的大端值是從 1100 開始遞增的計數器,對於偶數組,是從 0011 開始遞減的計數器。
這些被稱為Nothing Up My Sleeve numbers,並被選擇作為證明常數不是特別選擇的一種方式,例如為算法提供後門。根據figlesquidge關於為什麼這些不僅僅是 0 位的評論,整個初始值集的平均漢明權重為 0.5,一半為 1,一半為 0。
SHA-1 的輪常數也被選擇為不是“特殊的”,但生成方式完全不同。它們取二進制數的平方根,然後前 32 位(包括小數位之前的位)成為捨入常數。這與用於生成 MD4 的兩個輪常數的方法相同。
0x5A827999
= $ \sqrt2 $
0x6ED9EBA1
= $ \sqrt3 $
0x8F1BBCDC
= $ \sqrt5 $
0xCA62C1D6
= $ \sqrt{10} $最初的 MD4 論文和 RFC 中指定了前 2 輪常量的設計標準。初始值選擇從未定義或解釋,很可能是因為模式的明顯性。FIPS-180-1 和更高版本中沒有解釋初始值和輪常數的選擇。有趣的是,他們選擇 10 而不是 7 來生成最後一輪常數,因為它不是素數。
選擇的一種可能解釋 $ \sqrt{10} $ 代替 $ \sqrt7 $ 可能是這樣 $ \sqrt{10} $ 與其他三個常數一起,是Donald Knuth的電腦*程式藝術**,*卷。2:半數值算法,第二版(1981 年),p。660,在原始RFC 1320 中引用到 MD4(第 4 頁)作為常量的來源。在本書的第三版(1997 年)中,這些內容位於第 727 頁。
相比之下,SHA-2(256 位和 512 位摘要)使用連續素數 2 到 19 的平方根的小數部分(僅在小數位後)作為初始值,使用連續素數 2 到 19 的立方根的小數部分311 表示舍入常數。