第 2 讲:BTC 密码学原理

第 2 讲:BTC 密码学原理
agsd第 2 讲:BTC 密码学原理
1. 本节主线
- 比特币虽然常被称为“加密货币”,但它的交易内容并不是加密隐藏的,链上交易信息整体是公开的。
- 比特币主要使用密码学中的两个功能:哈希(hash) 和 数字签名(digital signature)。
- 哈希函数在比特币中不仅用于生成摘要,还支撑了 digital commitment 和 proof of work。
- 数字签名用于证明“这笔交易确实由账户所有者发起”,从而解决去中心化系统中的账户授权问题。
- 本节的核心是理解:比特币不是靠隐藏交易内容来保证安全,而是靠哈希和签名来保证不可篡改、难伪造、易验证。
2. 核心概念速览
| 概念 | 简要理解 | 在本节中的作用 |
|---|---|---|
| cryptographic hash function | 密码学哈希函数,把任意长度输入映射成固定长度输出 | 比特币中用于摘要、承诺、挖矿 |
| collision resistance | 难以人为找到两个不同输入,使它们哈希值相同 | 支撑防篡改和 message digest |
| hash collision | 两个不同输入得到相同哈希值 | 理论上必然存在,但难以人为制造 |
| message digest | 消息摘要,即对消息取哈希得到的“指纹” | 用来检测消息是否被篡改 |
| hiding | 从哈希值难以反推出原始输入 | 支撑 digital commitment |
| digital commitment | 数字承诺,类似电子版密封信封 | 先公开承诺,后公开内容,防止事后篡改 |
| nonce | 一次性随机数或可调随机值 | 在 commitment 和挖矿中用于增加随机性或试探哈希结果 |
| puzzle friendly | 哈希结果不可预测,只能不断尝试输入 | 支撑比特币挖矿机制 |
| proof of work | 工作量证明 | 通过找到满足条件的 nonce 证明做过大量计算 |
| SHA-256 | Secure Hash Algorithm 256-bit | 比特币使用的哈希函数 |
| public key | 公钥,可以公开 | 类似比特币账户地址,用于验证签名 |
| private key | 私钥,必须保密 | 用于对交易签名,证明账户控制权 |
| digital signature | 数字签名 | 证明交易确实由私钥持有者发起 |
| good source of randomness | 良好的随机源 | 生成密钥和签名时非常关键 |
3. 知识结构图
flowchart TD
A[BTC 密码学原理] --> B[Hash]
A --> C[Digital Signature]
B --> B1[Collision Resistance]
B --> B2[Hiding]
B --> B3[Puzzle Friendly]
B1 --> D1[Message Digest]
B2 --> D2[Digital Commitment]
B3 --> D3[Proof of Work]
C --> C1[Public Key]
C --> C2[Private Key]
C --> C3[Sign and Verify]
C3 --> E[证明交易由账户所有者发起]
这张图展示了本节课的整体结构:比特币使用密码学并不是为了“加密隐藏交易”,而是分别用 hash 解决数据摘要、承诺和挖矿问题,用 digital signature 解决交易授权问题。
4. 课程内容详解
4.1 “加密货币”并不意味着交易内容被加密
比特币常被称为 cryptocurrency,中文通常译为“加密货币”。但这里的“加密”容易造成误解。
在比特币系统中:
- 区块链上的交易内容是公开的;
- 账户地址是公开可见的;
- 转账金额也是公开可见的;
- 所有人都可以查看链上的交易记录。
因此,比特币中的密码学主要不是用于隐藏交易内容,而是用于解决两个问题:
- 如何保证数据不容易被篡改?
- 如何证明某笔交易确实由账户所有者发起?
对应的两个工具就是:
- 哈希(hash)
- 数字签名(digital signature)
4.2 Cryptographic Hash Function 的基本作用
普通哈希函数在数据结构中很常见,例如哈希表会把 key 映射到某个位置。密码学中的哈希函数要求更强,它被称为 cryptographic hash function。
它的基本形式可以写成:
1 | h = H(x) |
其中:
x是输入;H是哈希函数;h是哈希值。
哈希函数的输出长度通常是固定的。例如 SHA-256 的输出长度是 256 bit。
本节重点讲了密码学哈希函数的三个性质:
- collision resistance
- hiding
- puzzle friendly
前两个是密码学哈希函数的常见性质,第三个是比特币挖矿中特别重要的性质。
4.3 Collision Resistance:不是没有碰撞,而是难以人为制造碰撞
4.3.1 什么是 hash collision?
如果存在两个不同输入 x 和 y,满足:
1 | x ≠ y |
那么就发生了 hash collision,即哈希碰撞。
需要注意:哈希碰撞不是异常现象,而是理论上必然存在的。
原因是:
- 输入空间可以非常大,甚至可以认为是无限的;
- 输出空间是有限的,例如 SHA-256 只有
2^256种可能输出; - 根据鸽巢原理,足够多的输入必然会映射到相同输出。
所以,collision resistance 不是说哈希碰撞不存在。
它真正的意思是:
没有高效方法可以人为找到两个不同输入,使它们产生相同哈希值。
如果强行寻找,当然可以使用 brute force,也就是暴力枚举输入。但对于 256 bit 级别的哈希值,实际计算量极大,在现实中不可行。
4.3.2 Collision Resistance 的作用:message digest
Collision resistance 可以用来生成 message digest。
比如有一个消息 m:
1 | digest = H(m) |
这个 digest 可以看成消息的“指纹”。
如果有人修改了消息内容,变成 m',通常会导致:
1 | H(m') ≠ H(m) |
攻击者如果想偷偷修改消息,又不被发现,就必须找到一个 m',使得:
1 | m' ≠ m |
而 collision resistance 保证了这件事在现实中很难做到。
4.3.3 文件校验的例子
假设你把一个大文件上传到云端。上传前,你先在本地保存它的哈希值:
1 | h_original = H(file) |
之后你从云端下载文件,再算一次:
1 | h_downloaded = H(downloaded_file) |
如果两个哈希值相同,就可以高度相信文件没有被篡改。
这里依赖的就是 collision resistance:别人很难构造一个被篡改后的文件,同时让它的哈希值和原文件完全一致。
4.3.4 Collision Resistance 不能被数学证明
课程中特别强调:没有哪个实际使用的哈希函数可以被严格数学证明为 collision resistant。
我们通常依赖的是长期实践经验:
- 很多密码学专家长期研究;
- 目前没有发现高效制造碰撞的方法;
- 因此认为该哈希函数在实践中是安全的。
但这种安全性可能会随时间变化。例如 MD5 曾经很流行,但后来已经发现可以人为制造碰撞,因此不再被认为安全。
4.4 Hiding:哈希值不应泄露输入信息
4.4.1 Hiding 的含义
Hiding 指的是哈希计算是单向的:
1 | x -> H(x) |
从输入 x 计算哈希值 H(x) 很容易,但从 H(x) 反推出 x 很难。
也就是说,哈希值不应该泄露原始输入的有效信息。
不过,这个性质成立需要两个前提:
- 输入空间足够大;
- 输入分布足够均匀。
如果输入空间太小,就可以暴力枚举。
例如,如果输入只是“明天涨停的股票代码”,股票总数有限,攻击者可以把所有可能股票都算一遍哈希,然后和公开哈希值对比,从而猜出原始内容。
4.4.2 Hiding 和 brute force 的关系
Hiding 不是说绝对无法反推,而是说没有高效方法反推。
如果输入空间很小,攻击者可以这样做:
1 | for each possible x: |
所以,hiding 的安全性依赖于“猜不到”。
如果原始输入本身很容易猜,那么单独取哈希并不能保证隐藏性。
4.5 Digital Commitment:电子版密封信封
4.5.1 现实中的 sealed envelope
课程用“预测股票涨停”的例子解释 digital commitment。
假设某人声称自己能预测明天哪只股票会涨停。为了验证他的预测,有两个要求:
- 他不能提前公开预测内容,否则可能影响市场;
- 他也不能等结果出来后再随便编一个预测。
现实中可以用 sealed envelope:
- 今天把预测写在纸上;
- 放进信封并封好;
- 交给第三方保管;
- 第二天再打开验证。
这保证了:
- 预测内容提前确定;
- 预测内容没有提前泄露;
- 预测内容不能事后篡改。
4.5.2 用 hash 实现 digital commitment
电子世界中,可以用哈希函数实现类似功能。
假设预测内容是 x:
1 | commitment = H(x) |
今天先公布 commitment,但不公布 x。
第二天再公布 x,所有人都可以验证:
1 | H(x) == commitment |
这里同时用到了两个性质:
| 哈希性质 | 在 digital commitment 中的作用 |
|---|---|
| hiding | 公布哈希值时,别人看不出原始内容 |
| collision resistance | 之后不能随便换一个内容来匹配原哈希 |
4.5.3 为什么要加 nonce?
如果 x 的输入空间太小,单纯公布 H(x) 并不安全。
例如,预测内容只有几千只股票的可能性,攻击者可以枚举所有股票,算出每个哈希值,然后反推出预测内容。
解决办法是拼接一个随机数 nonce:
1 | commitment = H(x || nonce) |
其中:
x是原始内容;nonce是随机数;||表示拼接。
这样整体输入变得更随机、更难枚举。
之后公布时,需要同时公布:
1 | x, nonce |
其他人验证:
1 | H(x || nonce) == commitment |
这样既保留了承诺功能,又增强了 hiding。
4.6 Puzzle Friendly:挖矿没有捷径
4.6.1 Puzzle Friendly 的含义
Puzzle friendly 指的是:哈希值事先不可预测。
给定一个输入,你很难提前判断它的哈希值会落在哪里。如果想找到一个满足特定条件的输入,没有明显捷径,只能不断尝试。
例如,希望找到一个输入 x,使得:
1 | H(x) 的前 k 位都是 0 |
由于哈希输出看起来近似随机,你无法提前知道哪个 x 更可能成功,只能不断试。
4.6.2 Puzzle Friendly 和比特币挖矿
比特币挖矿本质上就是找一个 nonce。
矿工把 nonce 和 block header 中的其他信息放在一起取哈希:
1 | hash = H(block header) |
要求结果满足:
1 | hash <= target |
其中:
block header是区块头;nonce是区块头中可以不断调整的字段;target是目标阈值;hash <= target表示这个区块满足挖矿难度要求。
矿工的工作就是不断尝试不同 nonce:
1 | nonce = 0, 1, 2, 3, ... |
直到找到某个 nonce,使得区块头哈希值落入目标范围。
4.6.3 为什么这能成为 Proof of Work?
因为 puzzle friendly 保证:
- 找到符合条件的 nonce 很难;
- 没有比暴力尝试更好的捷径;
- 所以找到 nonce 本身就说明矿工做了大量计算。
这就是 proof of work 的核心思想。
但是,验证却很容易。
别人只需要拿到区块头和 nonce,算一次哈希:
1 | H(block header) <= target ? |
如果成立,就说明这个 nonce 合法。
所以 PoW 的重要性质是:
difficult to solve, but easy to verify
求解很难,验证很容易。
4.7 SHA-256:比特币使用的哈希函数
比特币中使用的哈希函数是 SHA-256。
SHA 是:
1 | Secure Hash Algorithm |
SHA-256 的输出长度是 256 bit。
在本节课语境中,SHA-256 被认为满足:
- collision resistance
- hiding
- puzzle friendly
其中:
- collision resistance 支撑防篡改;
- hiding 支撑 digital commitment;
- puzzle friendly 支撑 proof of work。
需要注意:课程没有要求在这里深入 SHA-256 的内部压缩函数或具体算法过程,重点是理解它在比特币系统中的作用。
4.8 从中心化账户到账户密钥对
4.8.1 中心化系统中的账户
在银行这类中心化系统中,开户通常需要:
- 带身份证件;
- 到银行办理手续;
- 由银行系统创建账户;
- 银行负责账户身份管理。
这是中心化账户管理方式。
4.8.2 比特币中的账户创建
比特币是去中心化系统,没有银行这样的中心机构给你开户。
在比特币中,创建账户的方式是:
1 | 本地生成一对 public key 和 private key |
这对密钥就代表一个账户。
可以粗略类比为:
| 比特币概念 | 日常类比 |
|---|---|
| public key | 银行账号,别人可以知道 |
| private key | 账户密码,必须自己保管 |
别人要给你转账,需要知道你的 public key 或由它派生出的地址。
你要花费账户里的钱,需要使用 private key 对交易进行签名。
4.9 对称加密与非对称加密
4.9.1 Symmetric Encryption Algorithm
最早的加密体系是 symmetric encryption algorithm,即对称加密。
特点是:
1 | 加密和解密使用同一个 key |
例如,A 要给 B 发消息:
- A 和 B 事先共享一个密钥;
- A 用这个密钥加密消息;
- B 收到后用同一个密钥解密。
问题是:密钥如何安全分发?
如果网络本身可能被窃听,就不能直接把密钥明文发过去。因此,对称加密的一个难点是密钥分发。
4.9.2 Asymmetric Encryption Algorithm
为了解决密钥分发问题,出现了 asymmetric encryption algorithm,即非对称加密。
它使用一对密钥:
- public key
- private key
在加密通信场景中:
1 | 用接收方 public key 加密 |
public key 可以公开,private key 只保存在接收方本地。
这就避免了双方必须提前秘密共享同一个密钥的问题。
4.10 比特币中 public key/private key 主要用于签名
课程中特别指出:比特币的交易内容是公开的,所以 public key 和 private key 在比特币中主要不是为了加密交易内容,而是为了做 digital signature。
4.10.1 签名要解决什么问题?
假设 A 发布了一笔交易:
1 | A 转 10 BTC 给 B |
其他节点需要判断:
这笔交易真的是 A 发起的吗?
如果没有签名,攻击者可以伪造交易,声称:
1 | A 转 10 BTC 给攻击者 |
数字签名的作用就是防止这种冒名操作。
4.10.2 签名和验证的流程
比特币交易签名的基本逻辑是:
1 | signature = Sign(private key, transaction) |
然后其他人使用对应 public key 验证:
1 | Verify(public key, transaction, signature) |
如果验证通过,说明:
- 这笔交易确实由 private key 持有者签名;
- 交易内容没有被篡改;
- 签名者不能轻易否认自己签过这笔交易。
需要注意:
- 签名用 private key;
- 验证签名用 public key;
- 它们属于同一个用户。
4.11 为什么随机性非常重要?
比特币账户由本地生成的 public key/private key pair 表示。
这引出一个问题:
如果两个人随机生成了相同的密钥对怎么办?
理论上确实存在这种可能,但如果密钥空间足够大,并且随机源足够好,那么概率小到可以忽略。
但这里有一个关键前提:
1 | a good source of randomness |
也就是生成密钥时必须有良好的随机源。
如果随机源不好,可能出现严重后果:
- 不同用户生成相同或相关的密钥;
- 攻击者能够猜测 private key;
- 在某些签名算法中,签名过程随机性不足可能泄露 private key。
因此,本节最后强调:不仅生成密钥时需要好的随机源,签名时也可能需要好的随机源。只要 private key 泄露,账户里的币就可能被转走。
4.12 先 hash,再签名
课程最后提到,比特币系统中通常不是直接对完整 message 签名,而是:
1 | digest = H(message) |
也就是:
- 先对 message 取 hash;
- 得到固定长度的 digest;
- 再对 digest 进行签名。
这样做的直观原因是:
- hash 可以把任意长度 message 压缩成固定长度摘要;
- 签名算法处理固定长度 digest 更方便;
- digest 和原 message 强绑定,message 一变,digest 也会变,签名验证就无法通过。
5. 关键机制图解
5.1 Digital Commitment 机制
sequenceDiagram
participant A as 承诺者
participant Public as 公开环境
participant V as 验证者
A->>A: 准备内容 x
A->>A: 选择随机 nonce
A->>A: 计算 H(x || nonce)
A->>Public: 公开 commitment
Note over Public: 此时看不到 x
A->>Public: 之后公开 x 和 nonce
V->>V: 重新计算 H(x || nonce)
V->>Public: 对比是否等于 commitment
这个机制解决的是“提前确定但暂不公开”的问题。
Hiding 保证公开 commitment 时别人难以知道内容,collision resistance 保证之后不能随意换内容。
5.2 Proof of Work 挖矿机制
flowchart TD
A[准备 block header] --> B[设置 nonce]
B --> C[计算 H(block header)]
C --> D{hash <= target?}
D -- 否 --> E[更换 nonce]
E --> C
D -- 是 --> F[找到合法区块]
F --> G[广播区块]
G --> H[其他节点验证一次 hash]
这张图体现了 PoW 的核心:
矿工需要不断尝试 nonce,直到哈希值小于等于 target。这个过程求解困难,但其他节点验证时只需要算一次哈希,因此验证成本很低。
5.3 数字签名验证交易
sequenceDiagram
participant User as 账户所有者
participant Tx as 交易
participant Network as 比特币网络节点
User->>Tx: 构造交易内容
User->>User: 用 private key 签名
User->>Network: 广播交易和 signature
Network->>Network: 用 public key 验证 signature
alt 验证通过
Network->>Network: 接受交易进入后续处理
else 验证失败
Network->>Network: 拒绝交易
end
这张图说明 digital signature 的功能不是隐藏交易,而是证明交易授权。交易本身可以公开,但只有 private key 持有者才能生成有效签名。
6. 易混点与常见误解
| 易混点 | 正确理解 |
|---|---|
| “加密货币”是不是交易内容都被加密? | 不是。比特币交易内容整体公开,“加密”主要指使用密码学机制保证安全性。 |
| collision resistance 是不是表示不会发生碰撞? | 不是。碰撞理论上必然存在,只是难以人为找到。 |
| hash collision 和哈希表冲突是不是一回事? | 思路相似,都是不同输入映射到同一输出;但密码学关注的是攻击者能否高效制造碰撞。 |
| hiding 是不是绝对无法反推输入? | 不是。若输入空间小或分布不均匀,可以 brute force 猜出来。 |
| 只对预测内容取 hash 就一定能隐藏预测吗? | 不一定。如果预测范围很小,需要拼接 nonce 增加随机性。 |
| puzzle friendly 和 collision resistance 是不是完全一样? | 不是。collision resistance 关注难以找两个相同哈希的输入;puzzle friendly 关注难以提前预测哪个输入能落入目标范围。 |
| 挖矿是不是在“解密”? | 不是。挖矿是在不断尝试 nonce,让 block header 的哈希值满足 target。 |
| public key 是不是用来签名的? | 不是。签名用 private key,验证签名用 public key。 |
| private key 是不是可以发给别人验证? | 绝对不应该。private key 一旦泄露,账户资产就可能被转走。 |
| 比特币使用 public/private key 是为了加密交易金额吗? | 不是。主要是为了 digital signature,证明交易由账户所有者发起。 |
7. 课堂外补充理解
7.1 Hash 的三个常见安全性质可以分层理解
本节重点讲了 collision resistance、hiding、puzzle friendly。为了避免混淆,可以这样理解:
| 性质 | 关注的问题 | 直观问题 |
|---|---|---|
| hiding | 从输出能不能推出输入? | 看到 H(x) 后能不能猜到 x? |
| collision resistance | 能不能找到两个输入哈希值相同? | 能不能找 x ≠ y 但 H(x)=H(y)? |
| puzzle friendly | 能不能预测哪个输入会满足目标? | 能不能不靠试错就找到合格 nonce? |
它们都和“哈希输出看起来随机”有关,但解决的问题不同。
7.2 为什么签名通常签 hash,而不是直接签原文?
直接对完整 message 签名通常不方便,因为 message 可能很长,格式也可能复杂。
先 hash 再签名有几个好处:
- 把任意长度 message 变成固定长度 digest;
- 签名算法只需要处理 digest;
- message 一旦被修改,digest 就会变化;
- 验证签名时可以重新计算 digest,检查签名是否匹配。
所以可以把 digest 理解为“被签名的消息指纹”。
7.3 “账户”在比特币里不是由机构创建的
在银行系统中,账户存在于银行数据库里,由银行确认身份并分配账户。
在比特币中,账户更像是:
1 | 谁拥有某个 private key,谁就控制对应资产 |
所以,比特币账户安全的核心不是“平台帮你找回密码”,而是:
- private key 不能丢;
- private key 不能泄露;
- 随机源必须可靠。
这也解释了为什么去中心化系统中,用户自主管理密钥非常重要。
8. 本节小结
- 比特币不是通过加密隐藏交易内容来保证安全,链上交易信息是公开的。
- 比特币主要使用两个密码学工具:hash 和 digital signature。
- Hash 的 collision resistance 支撑 message digest 和防篡改。
- Hash 的 hiding 与 collision resistance 结合,可以实现 digital commitment。
- Hash 的 puzzle friendly 支撑 proof of work,使挖矿“难求解、易验证”。
- Digital signature 通过 private key 签名、public key 验证,解决去中心化账户系统中的交易授权问题。
- 良好的随机源对密钥生成和签名过程非常关键,随机性不足可能导致 private key 泄露。
9. 自测问题
1. 为什么说比特币虽然叫“加密货币”,但交易内容并不是加密的?
参考答案:
因为比特币链上的交易记录、账户地址和转账金额都是公开可见的。这里的“加密”主要指它使用了密码学工具,如 hash 和 digital signature,而不是把交易内容隐藏起来。
2. Collision resistance 是不是表示哈希碰撞不存在?
参考答案:
不是。由于输入空间大于输出空间,哈希碰撞理论上必然存在。Collision resistance 的意思是:攻击者很难高效地人为找到一组碰撞输入。
3. Message digest 如何用于检测文件是否被篡改?
参考答案:
上传文件前先保存文件的哈希值,下载后重新计算哈希值。如果两个哈希值一致,就可以高度相信文件未被篡改;如果不同,则说明文件内容发生了变化。
4. Hiding 为什么要求输入空间足够大、分布足够均匀?
参考答案:
如果输入空间太小,攻击者可以枚举所有可能输入,逐个计算哈希值并对比目标哈希,从而反推出原始输入。输入分布不均匀时,攻击者也可以优先猜高概率输入。
5. Digital commitment 为什么要同时依赖 hiding 和 collision resistance?
参考答案:
Hiding 保证承诺公布时别人看不出原始内容;collision resistance 保证承诺者之后不能换一个不同内容来匹配原来的哈希值。
6. 比特币挖矿为什么可以被称为 proof of work?
参考答案:
因为矿工必须不断尝试 nonce,使 block header 的哈希值小于等于 target。由于 puzzle friendly,这个过程没有捷径,找到合法 nonce 就说明矿工做过大量计算。
7. 为什么说 PoW 是 difficult to solve but easy to verify?
参考答案:
求解时需要不断尝试大量 nonce,计算成本高;但验证时只需要对给定 block header 算一次哈希并检查是否满足 target,成本很低。
8. 比特币中 private key 和 public key 分别起什么作用?
参考答案:
Private key 用于对交易签名,证明账户所有者授权了这笔交易;public key 用于验证签名。Private key 必须保密,public key 可以公开。









