BTC-密碼學原理

鮑憲立發表於2023-07-04

區塊鏈技術與應用(一)

一、課程簡介

區塊鏈不等於比特幣。比特幣是基於區塊鏈技術的一種加密貨幣。

學習參考資料:
1、比特幣白皮書中文版
2、以太坊白皮書中文版+註釋
3、以太坊黃皮書
4、Solidity官方文件(v8.0)

二、密碼學原理

比特幣是一種加密貨幣(crypto-currency)。區塊鏈上所有的交易內容都是公開的,包括賬戶地轉賬金額等。

在比特幣系統中,主要運用了密碼學中的兩個功能,一個是雜湊,一個是簽名。

1.雜湊

密碼學中使用的雜湊函式有兩個重要性質。

①雜湊碰撞(cryptographic hash function)

雜湊碰撞是指兩個輸入透過雜湊函式計算出來的雜湊值相等。雜湊碰撞比較常見,比如在雜湊表中,不同的輸入可能會被對映到同一個雜湊位置。

  • 雜湊碰撞的作用:

低效的解決雜湊碰撞的方法:暴力剖解(brute-force),遍歷所有輸入的可能性,找到雜湊碰撞的輸入。這種方法工作量太大、低效。 效率太低!!!

注意:雜湊碰撞是不可避免的,因為輸入空間大於輸出空間。雜湊碰撞是客觀存在的,沒有什麼高效的方法人為地去製造雜湊碰撞。(MD5加密演算法已經可以被人為地計算出雜湊。)

②不可逆性(hiding)

不可逆性是指雜湊函式的過程是單向的,不可逆的。這個性質成立的前提是輸入的空間要足夠大,使得暴力破解的方法不可行,而且輸入的分佈要比較均勻,各種取值的可能性都差不多。

  • 不可逆性的作用

可以和雜湊碰撞結合在一起,用來實現雜湊函式將預測結果加密,實際結果釋出後將預測結果和實際結果對比,能夠使人信服預測結果是在實際釋出前預測的(digital commitment or digital equivalent of sealed envelope)。sealed envelope現實意義是指如果一個人預測結果,但是不能提前公開,因為只要公開,不論預測結果對錯,都會影響現實世界的變化。但是可以將預測結果交給第三方公證,待事實結果釋出後,公開並比較預測結果與事實結果。【簡單理解解釋:把預測結果放到一個信箱,待開箱後,判斷真實結果和之前預測的結果是否一致。】

③Puzzle Friendly

雜湊值的計算事先不可預測,只根據輸入很難預測出輸出。如果需要找出一個雜湊值存在某個範圍內,只能透過一個一個運算才能找出。

Puzzle friendly這個性質保證了比特幣系統中,只能透過挖礦獲得比特幣。

挖礦就是找一個隨機數nonce,nonce和區塊頭裡其他資訊合在一起作為輸入,取出一個雜湊來,那個雜湊值要小於某個指定的目標預值,只能透過一個一個試,才能找出在範圍中的值。挖礦的過程沒有捷徑,只能透過大量的一個一個試nonce,才能找到符合要求的值,這個過程叫做工作量證明(POW,proof of work)。

當有人找到了符合要求的nonce釋出出去後,其他人要驗算是否符合要求只需要算一次雜湊值是否小於目標預值。挖礦很難,驗證很容易。這個性質叫做difficult to solve,but easy to verify。

比特幣中用的雜湊函式叫做SHA-256。SHA是指secure hash algorithm,滿足雜湊函式的三個性質。

雜湊碰撞和puzzle friendly性質有一定聯絡,但不完全一樣。

2.比特幣系統中的賬戶管理

比特幣是去中心化的,每個使用者可以自己開設賬戶,不需要任何人批准。開戶的過程就是創立一對公鑰和私鑰。

公私鑰概念來源於非對稱加密體系(asymmetric encryption algorithm)。

最早的加密體系是對稱加密(symmetric encryption algorithm) ,傳送方和接收方事先商量好一個金鑰(encryption key),傳送方將資訊加密後傳送給接收方,接收方收到後用金鑰解密,對稱加密的前提是能有個安全的通道,將金鑰安全地分發給通訊方。(弱點:金鑰分發不方便)

比特幣中的公鑰私鑰作用:使用者簽名。

交易發起方用自己的私鑰對交易進行簽名,其他人收到交易後用發起方的公鑰去驗證簽名是否正確。產生兩個相同公私鑰的賬戶的可能性微乎其微。生成公私鑰的過程是隨機源。(a good source of randomness)

非對稱加密使用接收方的公鑰和私鑰,公鑰加密,私鑰解密。
注意:加密和解密是用的同一個人的公鑰和私鑰

好處:加密公鑰不需要保密,私鑰儲存在本地,解決了對稱加密中金鑰分發不方便的問題。

比特幣中使用的簽名演算法,不光是生成私鑰的時候要有好的隨機源,之後每一次簽名的時候也要有好的隨機源。只要有一個簽名的過程中的隨機源不好,就有可能洩漏私鑰。

三、比特幣中的資料結構

1.雜湊指標(hash pointers)

普通的指標儲存的是某個結構體在指標中的地址,雜湊指標要儲存地址和雜湊值。

比特幣中最基本的資料結構就是區塊鏈。區塊鏈是一個個區塊組成的連結串列。

區塊鏈與其他普通連結串列的區別:

  • 區塊鏈用雜湊指標代替了普通指標。
  • 區塊鏈的一個雜湊指標改變會影響到其他雜湊指標,普通指標變化不會影響其他的指標。【多米諾效應】
  • 每一個區塊都保留了指向前一個區塊的雜湊指標

雜湊指標的內容是把整個區塊的內容取雜湊。

區塊鏈資料結構的好處:

透過這種資料結構可以實現 tamper-evident log(防篡改log,後一個區塊儲存了前一個區塊的雜湊值,前一個區塊修改了區塊的內容,雜湊值會改變,後一個區塊會找不到前一個區塊的雜湊指標,所以就要修改後一個區塊的雜湊指標,以此類推,系統保留的雜湊指標也需要修改,就只需要記住系統中保留的雜湊,就可以檢測任何一個部位的修改。系統中任意一個區塊的雜湊值發生改動,最終儲存的這個區塊的雜湊值也會發生改動。即“牽一髮而動全身”=>多米諾骨牌效應)

比特幣可以根據這個性質,只儲存最近的幾個區塊雜湊。如果需要找之前的區塊,可以使用雜湊指標找到正確的區塊。

2.默克爾樹(merkle tree)

Merkle tree 和 binary tree 的區別:
用雜湊指標代替了普通的指標

B樹的特點:資料值存放在葉子結點

Merkle tree的好處:只要記住根雜湊就可以檢測出對樹中任何部位的修改。

比特幣當中各個區塊用雜湊指標連線在一起,每個區塊所包含的交易是組織成Merkle tree的形式。每層資料塊是一個交易->葉子節點。每個區塊分為兩部分,塊頭(block header)和塊體(block body),根據雜湊值儲存在塊頭中,即這個區塊所包含的所有交易組成的Merkle tree的根雜湊值是儲存在這個區塊的塊頭中,但是塊頭中沒有交易的具體內容,只有根雜湊值。塊體中有交易的列表。

Merkle tree的用途:提供Merkle proof

比特幣中的節點分為兩類:

全節點:儲存整個區塊的內容,包括塊頭和塊體,有交易的具體資訊

輕節點:只儲存塊頭,如手機上的比特幣錢包。

如何向輕節點證明某個交易是寫入到區塊鏈中?

使用Merkle proof,找到交易所在的位置。(從交易一直往根節點的路徑就是Merkle proof。)

image-20230708100232663

輕節點向某個全節點發出請求,請求一個能夠證明交易被包含在這個Merkle tree的Merkle proof,全節點收到請求後,只要全節點請求的雜湊值(紅色的)發給輕節點即可,輕節點可以透過這些雜湊值在本地計算出SPV本地計算雜湊值(綠色的),首先算出交易的雜湊值,再和旁邊紅色雜湊值拼接可以算出上一層雜湊,依次類推出整棵樹的根雜湊值。輕節點把根雜湊值和塊頭的雜湊值比較就可以知道交易是不是在Merkle tree裡。輕節點收到Merkle proof後只要從下往上驗證,沿途的雜湊值都是正確的,即可證明。

注意:查詢雜湊值只能查詢某個交易的從下往上分支的雜湊,不能查詢其他分支的雜湊。這種證明叫做proof of membership或者proof of inclusion,即可證明Merkle tree包含了某個交易。時間複雜度是O(logn)

相關文章