Comunion 是一個去中心化的(DAO) 組織協作網絡,提供面向數字時代的全新商業基礎設施和價值轉化機制,致力於讓勞動價值 像 資本一樣自由流通、交易和積累。
本系列內容包含:基本概念及原理、密碼學、共識算法、錢包及節點原理、挖礦原理及實現。
本篇專門講解哈希碰撞原理,這對於哈希算法的理解是非常重要的。如果把這個理解透了,那麼哈希算法裏面的很多特點,包括區塊鏈當中爲什麼使用哈希算法,那麼基本上就完全通透了。
定義
摘要函數(哈希函數),其實是一個安全性定義。
抗原像碰撞
什麼是原像?函數有定義域,有詞語,有對應關係。那麼類比到這裏,原像是指定義域裏面的一些未知數。
引用哈希算法應用中挖礦的例子來說,X是定義域,裏面的部分就是原像,Y就是一個值域。
我們來看其定義,幾乎所有消息摘要,都難以用ppn算法計算出一個原像。
這句話的意思是,假如確定了一個對應關係,或者確定了一個哈希函數,這時對定義域裏面某一個元素,比如X1,進行哈希之後,產生了一個哈希值,比如Y1。
假設這個時候產生了Y1,但是並沒有告訴任何人。那麼這裏就有一個問題:這個Y1的原像是誰呢?
這是很難找出來的,也就是提供一個像:Y1,很難找出其對應的原像:X1,這也就是抗原像碰撞的意思。
抗第二原像碰撞
通過字面意思來解釋是,存在兩個原像,這兩個原像是很難找到碰撞的。
給定一個摘要函數h,消息m1,任何ppn算法都難以計算出一個m2使得m1≠m2並且h(m1)=h(m2)。
意思是,給定一個哈希函數,通過任何ppn算法,很難找出一個m2,但這個m2和m1不相同,然後使得原像m2和m1,裏面的像也相同,這是很難做到的。
抗碰撞
給定一個摘要函數,任意ppn算法,難以找到m1,m2,使得h(m1)=h(m2)。
意思是,給定一個哈希函數,使用任意ppn算法,難以找到兩個消息(原像),使得它們的像相同。
強抗碰撞的意思是,給定一個哈希函數,從定義域(原像)裏面隨便找兩個數,並且這兩個數的像是相同的,這樣的數是很難找到的。
抗第二原像碰撞和抗碰撞之間的區別是:
抗第二原像碰撞是抗碰撞裏面的一個特殊問題。抗碰撞的條件更加強一些,因爲是任意取的兩個原像,想得到的像是相同的。而抗第二原像碰撞是給定了一個固定的原像,讓再找一個原像,使得這兩個原像裏面的像相同。所以說抗第二原像碰撞是弱抗碰撞。
在區塊鏈中,如果一個哈希函數滿足上述三個安全性定義,即:抗原相碰撞、抗第二原像碰撞、抗碰撞,那麼這個函數就可以使用,比如SHA-256就滿足這三點。
應用
通過安全性定義,其實我們能發現一個特點:這種函數能進行一個數據的完整性認證。
爲什麼這麼說呢?
舉個例子,特工A發了一段消息,內容是:使用任意函數H。並用SHA-256對這段話進行哈希,假設其哈希值全部是0,那麼就產生了256個0。
特工A把這段消息發給特工B,特工B收到之後,也對其內容“使用任意函數H”進行哈希,假如產生的值是256個0的話,那麼就說明這個消息在傳播的過程當中沒有被篡改。
發送方將完整的傳輸傳輸給了接收方,完成了發送方的目的,同時接受方也可以對數據的完整性進行驗證。
這裏有的朋友就有疑問了,那麼對於消息:使用任意函數X,經過哈希之後,會不會也產生256個0呢?
我可以負責的告訴你,如果對消息進行哈希使用的函數,滿足上述三個安全性定義的話,那麼是不會產生這種情況的。所以,在進行區塊鏈開發選用函數的時候,可以不必須用SHA-256,但是一定要滿足這三個安全條件。
其實講到這裏,有很多朋友會產生一個問題:假如我採用的是SHA-256算法,其原像是任意的字符串,像是固定的,那麼這個像的空間有多大呢?
答案是:2的256次方的像,也就是總共可以容納這麼多像。
安全級別
還有一個問題是:一個任意多的原像和一個固定空間大的像,那麼肯定會通過一定的概率找到兩個原像一樣的像,也就是產生了碰撞,那麼這個碰撞的概率是多大呢?
這個問題很好理解,像是固定的,但是原線有很多,在一個固定的空間內肯定會有碰撞的概率,就比如之前講過的粒子對撞機一樣的原理。
很多朋友都會對這個問題困擾很久。
其實在密碼學裏面專門有個悖論來解釋這個問題,我們一起來用“生日悖論”來解釋一下這個問題。
生日悖論
上述的成功概率與下述的問題相關。
問題:要使得教室裏的學生中有兩個人的生日相同的概率大於0.5(也就是50%),那麼教室裏至少需要有多少學生?
從直觀上來看,可能至少需要2/365≈183個人纔行。但是大家仔細分析一下,回顧一下之前學過的概率論的一些知識,會發現這個問題其實並不容易回答。
我們另外一個角度,從反面來解決這個問題,可能會更好一點。
這個問題的反面事件可以理解爲:教室裏的學生,任意兩個人的生日,不相同的概率大於50%。
如果我們能把反面事件的概率求出來,那麼用1減去求得概率就是原題目的答案。
所以這個問題我們轉換成:求這個教室裏面任意兩個人的生日,不相同的概率大於50%的人數。
那麼到底有多少個人不相同,概率才大於50%呢?
我們做兩個假設:
假設1,每個學生的生日在某個特定一天的概率是1/365;
假設2,n個學生的生日都互不相同的概率大於50%。
這裏就轉換成了求n是什麼。
我們首先來來分析一下,n 個人裏面,2個人生日不相同的概率是多大?也就是從教室裏面任意選出2個人,那他們生日不相同的概率是多少?
答案是:364/365。
也就是把兩個人標記爲A和B,A的生日是365天中的某一天,那麼B的生日和A不同,就有364種可能。
我們繼續,如果3個人不相同的概率是多大呢?那麼就是:364/365 * 363/365 。
……
那麼n個人不相同的概率應該是:363/365 * 364/365 * ……*(365-n+1)/365
這個時候呢,n個人生日不相同的概率,我們已經求出來了。如果要求這個概率大於50%,則可以寫成:pro[363/365 * 364/365 * ……*(365-n+1)/365] >
0.5,這就是反面事件的解。
那正面事件就可以寫成:1-{ pro[363/365
* 364/365 * ……*(365-n+1)/365] > 0.5} > 0.5
算式列出來之後,對n求解,得出n≥23,也就是說,只要不少於23個人,就至少有兩人生日相同的概率大於50%。
這看起來很不可思議,但通過計算卻是:一個 30 人的班級中,存在兩人生日相同的概率爲 70%;對於 60 人的班級中,這種概率要大於 99%。
從引起邏輯矛盾的角度來說,生日悖論並不是一種“悖論”。但這個數學事實十分反直覺,故稱之爲一個悖論。
通過這個問題,我們回來看哈希函數的碰撞問題:假如使用的哈希函數是SHA-256,那麼它的安全級別是多少呢?
或者說,假如使用的哈希函數是SHA-256,任意找兩個原像,要使這兩個原像產生碰撞的概率大於50%,需要做多少次計算呢?
通過生日悖論,我們可以理解到,SHA-256的安全級別不是2^256(2的256次方),而是:2^(256/2),也就是2的256/2次方。
引申一下,其實在密碼學裏面,對哈希函數有一個專門的安全性界定,它是跟哈希函數的尾綴有關係的,所以假如使用的是SHA-n,那麼其安全級別就是:2^(n/2)。