區塊鏈基礎:散列法 (Hashing)

燈泡,比特(bits)與字節(bytes)

你可能知道計算機中所有的數據都是由0或1組成的,最小的數據單位就是一個比特(bit,或位),它也是0或者1。想象一下,一臺計算機擁有著很多的燈泡,而這個燈泡的狀態有兩種,亮(1)或者滅(0)。而不同的數據,由燈泡顯示的圖案也是不同的。大數據如視頻,就使用了相當多的燈泡,而一個簡短的電子郵件,其所需要的燈泡就較少。一個單一的燈泡代表著一個比特。另外,你可能聽說過一個詞叫字節,一個字節就相當於8個燈泡的組合。而1MB的數據約為100萬個字節,也就相當於800萬個燈泡。

如今,家用的電腦就擁有了數十億甚至萬億級數量的燈泡。但我們發現,即使只是由256個燈泡組成的集合,也足以代表宇宙中能夠觀察到的任何顆粒。想象一下256個燈泡組能夠產生的所有圖案,那將是一個天文數字:也就是2^256種可能性。


區塊鏈基礎:散列法 (Hashing)


加密散列函數(或加密哈希函數)

一個散列函數(hash function),即取任何的輸入,就可以產出一個特定大小的輸出。這個運用散列函數,然後產出某些數據的過程,我們稱之為散列法(hashing)或音譯為哈希法。而散列函數的輸出,我們稱之為一個散列(hash)。一個特定散列函數的基本特徵,就是它產出輸出的大小。比方說本文中的示例,我們使用一個產出輸出為256 bits(32字節)的散列函數。當然也有散列函數能夠產出較小的輸出,或者也可以產出較大的輸出,也存在另外一些能夠產出256 bits的散列函數,但這個例子中,我們並不關心具體所使用的散列函數。


區塊鏈基礎:散列法 (Hashing)


使用這個例子的散列函數,當一部N兆(MB)的視頻被散列運算時,那它的輸出結果為:256個燈泡中有一些燈泡是點亮的。當一個簡短的電子郵件被散列運算時,這256個燈泡的輸出顯示,則是另外的一種圖案。在某些方面,散列法看起來就像是壓縮。簡單地解釋下這兩者之間的區別,散列法總是會產生相同數量的燈泡,而壓縮一部N兆(MB)視頻的結果,仍然會產生數以百萬計燈泡的一個輸出。一個壓縮過的視頻,可被解壓縮然後獲得原始的視頻。而當一個視頻被散列到僅僅只有256個燈泡時,從這個散列來重新構建原始視頻的可能性就很小了。這可能聽起來並不是理想的,但實際上這正是散列函數的一個強大功能。


區塊鏈基礎:散列法 (Hashing)


一個安全的加密散列函數,它的一個關鍵特徵就是,它是單向的。這意味著,從數學和計算機學角度上來看講,從輸出來反推輸入,這幾乎是不可能的。也就是說,給定一個散列,想要了解或查到提供給這個散列函數的輸入數據,它應該是不可行的。技術術語上來講,我們稱它為逆原像阻力(pre-image resistance)。

結果是,無論是散列法運算一個較大或者一個較小的輸入,散列函數應消耗大約相同的時間量。另一個理想中的結果是,這個散列,也就是由散列函數而產生的燈泡圖案,似乎應是隨機的,對數據“password1”進行散列法運算,其產生的燈泡圖案,與對數據“password2”進行散列法運算而產生的燈泡圖案,兩者是有很大不同的。否則,如果圖案是相似的,那對方就可以推斷出輸入也是類似的,而如果相關的詞(如“pass”,“word”)被發現時,那密碼也很容易被找到。安全的散列函數,即使輸入僅相差一個bit,也會產生顯著不同的輸出。

安全的理想行為,是給定一個散列,而唯一找到輸入數據的方法,就是通過對所有輸入的組合進行散列法運算,直到正確的輸入是被散列運算了。如果輸入是隨機的,那找到它的時間既是不確定的。

雖然找到一個散列的輸入應該是非常困難的,它需要花費很長的時間,但計算一個散列卻是很快就能完成的。一個帶有大量輸入的散列函數,可能在不到一秒的時間內,就能得到輸出。考慮到今天智能手機,每秒能夠進行數十億次的計算,1秒對於計算而言,就相當於很長的時間了。

加密散列函數也應該是抗碰撞的(collision resistant)。一個碰撞過程,意指當一個散列函數為超過1個輸入進行運算,而產出相同輸出的結果。如果用散列法運算數據1(可能是一份電子表格),而用散列法運算數據2(可能是一張圖片),這兩者產生了相同的輸出,那麼這個碰撞衝突就發生了。

加密散列函數,其安全性的重要性,在我們描述區塊鏈和散列法部分時,會顯得更為清楚。

區塊鏈和散列法

散列法(Hashing)廣泛地應用於區塊鏈,這裡也有一些例子。

區塊鏈上的地址,是由散列法運算公鑰而得到的。一個以太坊的賬戶地址,是以Keccak-256(開發者應該閱讀下它與SHA3-256的關鍵區別)散列法運算一個公鑰而得出的。而一個比特幣地址,則是通過SHA2–256和RIPEMD160來散列法運算一個公鑰而得出的。

散列函數的抗碰撞性是重要的,因為如果2個人產生了相同的地址(發生了衝突),那任何一方都可以花費這個地址上的錢。

簽名也是區塊鏈的基本組成部分。類似於簽署一張支票,加密簽名決定哪些交易是有效的。簽名是由私鑰和需要被簽名的數據散列而生成的。

交易散列在區塊鏈中是非常明顯的。比方說描述一筆交易:“Alice在D日T時,向Bob發送了X單位的貨幣”,那麼交易就會被提交為他們的散列,例如5c504ed432cb51138bcf09aa5e8a410dd4a1e204ef84bfed1be16dfba1b22060 是以太坊區塊鏈中的一筆交易。交易散列也是更為直接可用的,例如“在1337個區塊中的第1024筆交易”這樣的描述,你只需要複製這個散列,並粘貼到一個區塊鏈瀏覽器中,然後就可以查看這筆交易的細節。

形而上學地講,區塊鏈中的區塊是由它們的散列來確定的,其充當了鑑別和完整驗證的雙重角色。一個識別字符串還會提供它自有的完整性,被稱為自認證標識符。

對於使用挖礦機制的區塊鏈來說,工作量證明(Proof-of-Work)就是一個數字,我們稱它為隨機數(nonce),當它和其他散列過的數據進行合併時,會產生一個比規定目標值更小的值。挖礦使得散列法成為一種快速運算、單向不可逆的算法。找到一個有效的隨機數需要時間,因為(礦工)沒有可用的線索來幫助它們找到一個足夠小的散列,而唯一找到一個小於目標值的方法,就是計算很多的散列:在比特幣中,目前存在了超過10^25(10 septillion)數量級的散列。當一個(nonce)隨機數被找到時,驗證它的時間就需要1秒,然後這個新區塊會在網絡中廣播,形成最新的共識和區塊鏈。

在區塊鏈上的存儲數據是永久性的,但把大量的數據存儲在區塊鏈上則是不明智的,而實用的區塊鏈存儲方法,是將固定大小(通常是小的)的數據代表存儲在區塊鏈上,我們稱之為“數據的散列”。區塊鏈的一個應用是作為一個時間戳服務。假設你想要證明一張當前存在的圖片,保證在未來時它不是編造出來的。你可以將圖片的散列存儲在區塊鏈上,一年以後,當法官問起這張圖片是否在一年前真實存在時,你可以提供這個圖片,然後法官就可以散列運算這張圖片,並與你存儲在區塊鏈上的散列進行對比。

散列法還涉及到更多高級的例子,例如區塊鏈、可擴展性、輕錢包創新的根本 —— 梅克爾樹(Merkle tree)。

用於安全識別的散列

安全加密散列函數是單向、快速計算,並且抗碰撞的。結合這些特點後,它們會處理任何類型的輸入,然後產生一個固定大小的輸出,稱之為散列,散列作為任何數據的標識而言,是非常有用的。長度256 bits的散列,代表了一個天文數字的組合,將它們用於全球物聯網的唯一標識符,那也是綽綽有餘的,即使是在納米技術規模下,這些散列也可以被寫為64個字符(十六進制),這使得它們足以作為標識符來使用。在區塊鏈中,散列是作為區塊、交易和地址的標識符。


區塊鏈基礎:散列法 (Hashing)


散列還享有安全與隱私的優勢。如果一首歌是以數字格式被記錄的,並且這首歌的散列是被記錄在區塊鏈之上的,那任何他人都無法聲稱是他們是第一個創造了這首歌,並生成了這個散列,他們也不會知道歌曲本身:某人不能寫歌,也沒法篡改這個散列。同樣地,除非歌曲或其他數字化財產或數據被表明了,展示在區塊鏈上的僅僅是散列本身而已。 所有權記錄也可以存儲在區塊鏈上,舉個簡單的例子,車輛登記處可以將汽車數據散列(照片,VIN, 車牌)存儲在區塊鏈上,只有車輛所有者,保險公司以及政府會知道這個車輛的實際細節。

深入理論,廣泛應用

設計加密散列函數,需要藝術與科學的結合。為了證明它們的安全性,就需要用到先進的數學與計算機科學。區塊鏈是為廣大人群提供的,第一個充滿散列的用戶界面。好的用戶體驗,其背後隱藏著很多的散列,但正如我們今天看到的各種 id和序列號,有時候散列會是替代長篇大論的最佳標識符。隨著加密技術與物聯網技術變得更加普及化,希望在未來能夠看到更多64字符的散列!

原文鏈接: https://medium.com/@ConsenSys/blockchain-underpinnings-hashing-7f4746cbd66b

翻譯: 灑脫喜

稿源:巴比特資訊(https://www.8btc.com/article/77770)


分享到:


相關文章: