9.2 區塊鏈中的密碼學#
概念說明#
區塊鏈是一個「用密碼學取代中央管理者」的帳本系統。以比特幣為例,它其實就是本書三個零件的組裝:
- 雜湊函數(SHA-256/RIPEMD-160):內容定址、區塊鏈接、Merkle 樹、工作量證明。
- 數位簽章(ECDSA over secp256k1,部分鏈用 Ed25519):誰有權動用哪筆錢。
- 對稱加密(幾乎不在鏈上):用在錢包檔案加密與節點通訊的 TLS。
區塊鏈的「信任」不來自任何機構,而來自密碼學性質:改動歷史任一交易,其雜湊改變 → Merkle 根改變 → 區塊頭雜湊改變 → 之後所有區塊全部斷鏈。竄改 = 必須重做所有後續區塊的工作量證明,經濟上不可行。
核心機制#
Merkle 樹#
把 n 筆交易的雜湊兩兩配對、逐層向上雜湊,直到只剩一個 Merkle 根存進區塊頭:
Root
/ \
H12 H34
/ \ / \
H1 H2 H3 H4 Hi = H(tx_i)
特性:要證明「交易 tx3 在鏈上」,只需提供 H4、H12 兩個雜湊(O(log n) 個),驗證者自行重算路徑——這讓輕節點(手機錢包、SPV)不必下載全部交易。
地址與簽章#
- 私鑰(256 位元隨機數)→ 公鑰(橢圓曲線點 kG)→ 地址(
RIPEMD160(SHA256(pubkey)),再編碼)。 - 花錢 = 對交易資料做 ECDSA 簽章,全網用公鑰驗證(6.2、7.3 節)。
工作量證明(PoW)#
找到 nonce 使 H(block_header) < 目標值(雜湊前導零夠多)
這是 5.1 節「部分前像攻擊」的工程化:找到 nonce 平均需 2^(難度位元) 次雜湊,驗證卻只要一次——難找易驗。
Python 實作#
import hashlib, random
def H(b: bytes) -> bytes:
return hashlib.sha256(b).digest()
# --- Merkle 樹 ---
txs = [f"tx{i}".encode() for i in range(4)]
level = [H(t) for t in txs]
while len(level) > 1:
if len(level) % 2: level.append(level[-1]) # 奇數補複製
level = [H(level[i] + level[i+1]) for i in range(0, len(level), 2)]
merkle_root = level[0]
print("Merkle 根:", merkle_root.hex()[:32])
# Merkle 證明:驗證 tx2 存在(只需 H3、H12)
def merkle_proof(index, leaves):
proof = []
level = [H(t) for t in leaves]
while len(level) > 1:
if len(level) % 2: level.append(level[-1])
sib = index ^ 1
proof.append(level[sib])
level = [H(level[i] + level[i+1]) for i in range(0, len(level), 2)]
index //= 2
return proof
proof = merkle_proof(2, txs)
node = H(b"tx2")
for p in proof: node = H(node + p)
print("驗證 tx2:", node == merkle_root) # True
# --- 工作量證明(迷你版)---
target = 2 ** (256 - 16) # 16 個前導零位元
nonce = 0
while True:
h = int.from_bytes(H(b"block" + str(nonce).encode()), "big")
if h < target: break
nonce += 1
print(f"PoW:nonce={nonce},平均嘗試約 {2**16} 次")
安全性分析#
- 51% 攻擊:若一方控制過半算力,可重寫近期區塊(雙花)。防禦是「算力去中心化」而非密碼學。
- 簽章與橢圓曲線的實戰紀律:ECDSA 的隨機數 k 重用曾直接洩漏比特幣私鑰(Android 錢包事件,7.3 節);現代鏈逐步採用 Ed25519 或 Schnorr(確定性、可聚合)。
- 雜湊選擇與量子:Grover 對 PoW 是「平方加速」——難度位元減半即可補償(10.2);但 ECDSA/ECDSA 型簽章在 Shor 下全毀,後量子簽章遷移(10.3)是區塊鏈的重大課題(地址可能需重生成)。
- 密碼學之外的攻擊面:智慧合約漏洞(重入、整數溢位)、私鑰管理(助記詞、冷錢包)造成的損失遠大於演算法層面——再次印證 9.3 節的主題。
練習#
- 把 5 筆交易建成 Merkle 樹,並為第 0 筆產生證明、驗證通過;再竄改 tx0 的內容,顯示驗證失敗。
- 把迷你 PoW 的難度改為 20 個零位元,測量所需時間,驗證「每增加 1 位元難度,時間翻倍」。
- 研究題:查詢「Schnorr 簽章聚合」,寫 200 字說明它如何讓 n 個簽章合併成 1 個,以及這對區塊容量與隱私的意義。