ECDSA 签名机制详解(secp256k1 曲线)
ECDSA(Elliptic Curve Digital Signature Algorithm)是一种基于椭圆曲线的数字签名算法,广泛应用于比特币、以太坊等区块链系统。其中,secp256k1 是 ECDSA 的一种标准椭圆曲线参数,被比特币和以太坊采用。
1. ECDSA 的核心概念
ECDSA 用于生成数字签名和验证签名,确保:
-
身份认证(签名者拥有私钥)
-
数据完整性(消息未被篡改)
-
不可否认性(签名者无法抵赖)
关键组成部分
| 组件 | 说明 |
|---|---|
| 私钥(Private Key) | 一个随机数(256-bit,用于生成签名) |
| 公钥(Public Key) | 由私钥通过椭圆曲线乘法计算得出 |
| 消息(Message) | 待签名的数据(如交易哈希) |
| 签名(Signature) | 由 (r, s) 两个整数组成 |
2. secp256k1 椭圆曲线参数
secp256k1 是 ECDSA 使用的一种标准化椭圆曲线,定义如下:
-
曲线方程:
y2=x3+7 (在有限域 Fp 上) -
素数模数 p:
p=2256−232−29−28−27−26−24−1
(即0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F) -
基点 G(生成点):
坐标(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8) -
阶数 n(基点的子群阶数):
n=2256−432420386565659656852420866394968145599
(即0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141)
3. ECDSA 签名生成过程
假设:
-
私钥 d(一个随机数,1≤d≤n−1)
-
消息哈希 H(m)(如 SHA-256 哈希)
-
临时随机数 k(必须保密且每次不同)
签名计算步骤
-
计算临时公钥点 R=k×G
-
取 R 的 x 坐标 r=Rxmod n
-
如果 r=0,重新选择 k。
-
-
计算签名 s
s=k−1⋅(H(m)+r⋅d)mod n-
k−1 是 k 的模逆元(即 k⋅k−1≡1mod n)
-
如果 s=0,重新选择 k。
-
-
最终签名
-
签名为
(r, s)两个整数(通常编码为 DER 或紧凑格式)。
-
4. ECDSA 签名验证过程
给定:
-
公钥 Q=d×G
-
消息哈希 H(m)
-
签名 (r,s)
验证步骤
-
检查 r 和 s 是否在 [1,n−1] 范围内(否则无效)。
-
计算 w=s−1mod n(即 s 的模逆元)。
-
计算 u1=H(m)⋅wmod n 和 u2=r⋅wmod n。
-
计算点 R′=u1×G+u2×Q。
-
检查 Rx′mod n=r:
-
如果相等,则签名有效。
-
否则,签名无效。
-
5. secp256k1 在区块链中的应用
(1)比特币 & 以太坊
-
私钥 → 生成 公钥 → 生成 地址。
-
交易签名使用 ECDSA(secp256k1),确保只有私钥持有者能花费资金。
(2)签名格式
-
DER 编码(比特币传统格式):
0x30 [长度] 0x02 [r长度] [r] 0x02 [s长度] [s] -
紧凑格式(64字节)(以太坊常用):
[r (32字节)] [s (32字节)] -
恢复标识(Recovery ID, v)(以太坊额外加 1 字节,用于恢复公钥)。
6. ECDSA 的安全性问题
(1)随机数 k 必须保密
-
如果 k 重复或可预测(如错误 PRNG),私钥可能被破解(如索尼 PS3 漏洞)。
-
解决方案:RFC 6979(确定性 ECDSA,用私钥和消息哈希生成 k)。
(2)签名延展性(Malleability)
-
由于 (r,s) 和 (r,−smod n) 都是有效签名,比特币采用 BIP 62 防止交易篡改。
(3)量子计算威胁
-
Shor 算法可破解 ECDSA,未来可能需要抗量子签名(如 Lamport、Schnorr)。
7. 代码示例(Python + ecdsa 库)
from ecdsa import SigningKey, SECP256k1
import hashlib
# 生成私钥
private_key = SigningKey.generate(curve=SECP256k1)
public_key = private_key.get_verifying_key()
# 签名
message = b"Hello, ECDSA!"
hash_msg = hashlib.sha256(message).digest()
signature = private_key.sign(hash_msg)
# 验证
try:
public_key.verify(signature, hash_msg)
print("Signature is valid!")
except:
print("Signature is invalid!")
8. 总结
-
ECDSA(secp256k1) 是比特币、以太坊等区块链的核心签名算法。
-
签名 = (r, s),验证依赖椭圆曲线数学。
-
安全性依赖:
-
随机数 k 必须保密且唯一。
-
私钥绝不能泄露。
-
-
未来趋势:Schnorr 签名(比特币 Taproot)可能替代 ECDSA,提高效率和隐私。

浙公网安备 33010602011771号