ECDSA 橢圓曲線數位簽章密碼學完整指南

深入分析 ECDSA 簽章的數學基礎、演算法實現與安全特性,包括 secp256k1 曲線參數、簽章生成與驗證過程、nonce 安全問題,以及在比特幣交易中的實際應用。

ECDSA 橢圓曲線數位簽章密碼學完整指南

橢圓曲線數位簽章演算法(ECDSA)是比特幣網路中最重要的密碼學基礎設施。用於驗證交易的所有權、確保消息的真實性,並實現比特幣的去中心化安全模型。本文深入分析 ECDSA 的數學基礎、演算法實現、安全特性以及在比特幣中的具體應用場景。

橢圓曲線密碼學數學基礎

橢圓曲線的代數定義

橢圓曲線在密碼學中的標準形式是 Weierstrass 方程:

y² = x³ + ax + b (mod p)

其中 a 和 b 是常數係數,p 是大質數。曲線上的點 (x, y) 必須滿足上述方程,且曲線不能有奇點(即導數不會同時為零),這要求 4a³ + 27b² ≠ 0 (mod p)。

secp256k1 曲線參數

比特幣採用的 secp256k1 曲線定義如下:

曲線方程:y² = x³ + 7 (mod p)

其中:
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
  = 2^256 - 2^32 - 977

基點 G:
Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

階 n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
輔助因子 h = 1

選擇 secp256k1 的原因是多方面的:首先,這條曲線在實現效率上具有優勢,因為 a = 0 簡化了曲線方程;其次,這條曲線經過了充分的密碼學分析,安全性得到了廣泛驗證;最後,NIST 曲線(比特幣未採用)存在爭議,secp256k1 提供了更透明的選擇。

有限域上的點運算

在有限域 Fp 上,橢圓曲線點的加法定義如下:

點加法公式(當 P ≠ Q)

λ = (y₂ - y₁) × (x₂ - x₁)⁻¹ (mod p)
x₃ = λ² - x₁ - x₂ (mod p)
y₃ = λ(x₁ - x₃) - y₁ (mod p)

倍點運算(當 P = Q)

λ = (3x₁² + a) × (2y₁)⁻¹ (mod p)
x₃ = λ² - 2x₁ (mod p)
y₃ = λ(x₁ - x₃) - y₁ (mod p)

標量乘法與循環群

橢圓曲線密碼學的安全性基於「橢圓曲線離散對數問題」(ECDLP):已知點 P 和 kP,求解 k 在計算上是不可行的。

比特幣使用 256 位元的私鑰 k,通過計算 Q = k × G 得到公鑰 Q。這就是比特幣地址生成的數學基礎。

ECDSA 簽章演算法詳解

簽章生成過程

ECDSA 簽章生成過程需要輸入待簽名消息的哈希值 h 和私鑰 d。輸出是簽名對 (r, s)。

演算法步驟:

輸入:消息哈希 h (256位元),私鑰 d
輸出:簽名 (r, s)

1. 計算 e = h mod n(將哈希值標準化為曲線階的範圍)

2. 選擇隨機nonce k ∈ [1, n-1]

3. 計算 (x₁, y₁) = k × G
   如果 x₁ = 0,返回步驟2重新選擇k

4. 計算 r = x₁ mod n
   如果 r = 0,返回步驟2重新選擇k

5. 計算 s = k⁻¹ × (e + r × d) mod n
   如果 s = 0,返回步驟2重新選擇k

6. 返回簽名 (r, s)

簽章驗證過程

任何人都可以使用簽名、公鑰和消息哈希來驗證簽名的有效性。

演算法步驟:

輸入:簽名 (r, s),消息哈希 h,公鑰 Q
輸出:有效/無效

1. 驗證 r, s ∈ [1, n-1],否則返回無效

2. 計算 e = h mod n

3. 計算 u₁ = s⁻¹ × e mod n
   計算 u₂ = s⁻¹ × r mod n

4. 計算 (x₁, y₁) = u₁ × G + u₂ × Q

5. 如果 (x₁, y₁) 是無窮遠點,返回無效

6. 計算 v = x₁ mod n

7. 如果 v = r,返回有效;否則返回無效

簽章格式與編碼

比特幣中的 ECDSA 簽名使用 DER(Distinguished Encoding Rules)編碼:

DER 簽名結構:

┌─────────────────────────────────────────────────────────┐
│  0x30 [總長度]                                          │
│  ├── 0x02 [r長度] [r值]                                │
│  └── 0x02 [s長度] [s值]                                │
└─────────────────────────────────────────────────────────┘

示例簽名(71-73 bytes):
30440220[32 bytes r]0220[32 bytes s]

比特幣還使用 sighash 類型位元組來指定簽名覆蓋的交易部分:

簽章安全性分析

隨機數nonce的重要性

ECDSA 簽章中最關鍵的安全要素是隨機數 k(nonce)的選擇。如果同一私鑰的兩個簽名使用了相同的 k,攻擊者可以通過這兩個簽名直接計算出私鑰:

私鑰恢復攻擊:

已知:(r, s₁), (r, s₂), h₁, h₂

計算:
k = (h₁ - h₂) × (s₁ - s₂)⁻¹ mod n
d = s₁⁻¹ × (h₁ + r × k) mod n

比特幣史上因此類漏洞導致的私鑰洩露:
- 2010年:Sony PlayStation 3 私鑰洩露
- 2020年:多个 Bitcoin Core 开发者的签名泄露

確定性簽章(RFC 6979)

為了解決 nonce 選擇的安全問題,BIP-62 採用了 RFC 6979 確定的簽章生成方案:

確定性 k 的計算:

k = HMAC_SHA256(privkey || hash || counter)

重複直到 k ∈ [1, n-1]:
  k = HMAC_SHA256(d || h || ctr)
  ctr += 1

這種方法確保同一私鑰對同一消息總是產生相同的簽名,消除了隨機數產生器的依賴。

比特幣交易中的 ECDSA 應用

P2PKH 交易簽章

傳統的 Pay-to-Public-Key-Hash (P2PKH) 交易使用 ECDSA 簽名:

解鎖腳本 (scriptSig):
<signature> <pubKey>

鎖定腳本 (scriptPubKey):
OP_DUP OP_HASH160 <pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG

驗證過程:
1. OP_DUP 複製公鑰
2. OP_HASH160 計算公鑰哈希
3. 與輸出中的 pubKeyHash 比較
4. OP_EQUALVERIFY 驗證匹配
5. OP_CHECKSIG 使用 ECDSA 驗證簽名

隔離見證(SegWit)與 ECDSA

SegWit 升級改變了簽名的存儲位置,但仍然使用 ECDSA:

P2WPKH (Pay-to-Witness-Public-Key-Hash):

見證數據 (witness):
<signature> <pubKey>

鎖定腳本:
OP_0 <pubKeyHash>

驗證差異:
- 簽名不再包含在交易輸入中
- 見證數據單獨傳輸
- 解決了交易延展性問題

Schnorr 簽名與 Taproot

比特幣 2021 年 Taproot 升級引入了 Schnorr 簽名作為 ECDSA 的替代方案:

Schnorr 簽名生成:

輸入:私鑰 d,消息 h,隨機數 k

1. R = k × G
2. e = Hash(R || pubKey || h) mod n
3. s = k + e × d mod n

簽名:(R, s)

Schnorr 簽名的優勢包括:

ECDSA 與比特幣地址

地址生成流程

比特幣地址是公鑰的哈希表示,生成過程如下:

步驟 1:生成私鑰
私鑰 d ∈ [1, n-1](256位元隨機數)

步驟 2:計算公鑰
Q = d × G
公鑰未壓縮:04 || x || y (65 bytes)
公鑰壓縮:02/03 || x (33 bytes)

步驟 3:SHA256 哈希
hash1 = SHA256(公鑰)

步驟 4:RIPEMD-160 哈希
hash2 = RIPEMD160(hash1)

步驟 5:加入版本位元組
versioned_hash = 0x00 || hash2 (P2PKH)
versioned_hash = 0x05 || hash2 (P2SH)

步驟 6:校驗和
checksum = SHA256(SHA256(versioned_hash))[:4]

步驟 7:Base58Check 編碼
address = Base58Check(versioned_hash || checksum)

P2PKH 與 P2SH 地址

比特幣有兩種主要的地址格式:

P2PKH(Pay to Public Key Hash)

P2SH(Pay to Script Hash)

隔離見證地址(Bech32)

SegWit 引入了新的地址格式 Bech32:

P2WPKH(Native SegWit)

P2WSH(Pay to Witness Script Hash)

密鑰管理與 ECDSA 安全

私鑰安全存儲

比特幣私鑰的安全性完全依賴於用戶的保管。以下是最佳實踐:

硬體錢包:使用專用硬體設備存儲私鑰,永遠不暴露給連網設備。

紙錢包:將私鑰或助記詞以物理形式存儲,存放在安全位置。

多重簽名:使用 m-of-n 多重簽名方案,分散風險。

階層式確定性錢包(BIP-32)

現代比特幣錢包使用 BIP-32 確定性密鑰派生:

從 seed 生成主密鑰:

seed = HMAC-SHA512("Bitcoin seed", 密碼短語)
master_private_key = seed[:32]
master_chain_code = seed[32:]

從 master 生成子密鑰:

child_private_key = HMAC-SHA512(chain_code, parent_public_key || index)
child_public_key = child_private_key × G

這種設計允許從單一 seed 派生出大量地址,便於備份和管理。

量子計算威脅與 ECDSA 的未來

量子計算對 ECDSA 的威脅

量子計算機可以通過 Shor 演算法在多項式時間內解決橢圓曲線離散對數問題,這將使 ECDSA 完全失效。估計而言,破解比特幣的 256 位元曲線需要約 2000 邏輯量子位元的量子計算機。

後量子密碼學遷移

比特幣社群正在討論後量子遷移策略:

Lamport 簽名:基於哈希的簽名方案,安全性依賴哈希函數的抗碰撞性。

SPHINCS+:NIST 標準化的哈希簽名方案。

橢圓曲線同源加密(ECSIH):基於橢圓曲線同源問題的後量子方案。

混合簽名方案:結合傳統 ECDSA 和後量子簽名,實現逐步遷移。

結論

ECDSA 是比特幣安全的基石,通過橢圓曲線密碼學實現了去中心化的數位簽章。雖然面臨量子計算的潛在威脅,但比特幣社群已經開始規劃後量子遷移。理解 ECDSA 的數學基礎和實現細節對於比特幣開發者、安全研究人員和進階用戶至關重要。隨著 Schnorr 簽名和 Taproot 的引入,比特幣的簽名方案將繼續演進,為用戶提供更強大的安全性和隱私保護。

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!