Task F: Schnorr 协议安全性分析
题目分析
问题背景与核心挑战
Task F 深入分析了 Schnorr 识别协议(Schnorr Identification Protocol),这是一个标准的零知识 Sigma 协议。该协议的目标是证明证明者(Prover)知道离散对数 x,使得公钥 y=gx。
本题从三个角度分析协议的安全性:
- Soundness 的缺失:当验证者的随机数生成器可预测时,恶意证明者可以通过"幸运猜测"攻击通过验证
- Special Soundness(特殊可靠性):通过"回放"(Rewinding)技术,可以形式化证明知识可靠性(Knowledge Soundness)
- 实际实现错误:当证明者重用随机数 k 时,攻击者可以恢复秘密密钥
Schnorr 协议的基本结构
公共参数:
- 群 G:大素数阶 q 的群,生成元为 g
密钥:
- 秘密密钥(证明者):x∈Zq
- 公钥(验证者):y=gx
协议步骤(P ↔ V):
- 承诺(Commit):P 选择随机数 k∈Zq,计算承诺 t=gk,发送 t 给 V
- 挑战(Challenge):V 选择随机挑战 c∈Zq,发送 c 给 P
- 响应(Response):P 计算响应 z=k+c⋅x(modq),发送 z 给 V
- 验证(Verify):V 接受证明当且仅当检查 gz≡t⋅yc 成立
正确性验证:
gz=gk+cx=gk⋅gcx=gk⋅(gx)c=t⋅yc✓
零知识证明的三个基本性质
- 完备性(Completeness):如果证明者知道秘密,诚实验证者总是接受
- 可靠性(Soundness):如果证明者不知道秘密,验证者以高概率拒绝
- 零知识性(Zero-Knowledge):验证者无法从证明过程中获得关于秘密的信息
问题 1.1:"幸运猜测"攻击(Soundness 的缺失)
问题描述
场景:恶意证明者 Mallory 不知道秘密 x,但她知道验证者的随机数生成器很弱,总是发出挑战值 c(可预测)。
问题 (a):展示 Mallory 如何构造一个有效的证明转录 (t,c,z),使其通过验证检查 gz=t⋅yc,而不需要知道 x。清楚地说明 Mallory 生成 z 和 t 的顺序。
问题 (b):解释为什么这种"幸运猜测"攻击在单次交互中有效。
深度分析
Soundness 的定义
Soundness(可靠性):
- 如果证明者不知道秘密,则验证者以高概率拒绝证明
- 形式化:Pr[验证者接受∣证明者不知道秘密]≤ϵ,其中 ϵ 是可忽略函数
Soundness 的重要性:
- 保证不知道秘密的证明者无法通过验证
- 如果 Soundness 不满足,协议就不安全
可预测挑战的问题
正常情况:
- 验证者随机选择挑战 c,证明者无法预测
- 证明者必须提前选择 t,然后根据 c 计算 z
- 如果不知道 x,无法对任意 c 都计算出正确的 z
可预测挑战的情况:
- 如果挑战 c 是可预测的(例如,总是固定值或可以从某些信息推断)
- 证明者可以提前知道 c,从而构造有效的证明
标准答案
问题 (a):Mallory 的攻击方法
Mallory 的知识:
- Mallory 不知道秘密 x
- Mallory 知道验证者的随机数生成器很弱,总是发出挑战值 c(可预测)
Mallory 的攻击步骤:
步骤 1:Mallory 提前知道挑战 c
- 由于验证者的随机数生成器可预测,Mallory 可以提前知道挑战值 c
步骤 2:Mallory 随机选择响应 z
- Mallory 随机选择 z←Zq
步骤 3:Mallory 计算承诺 t
- Mallory 计算:t=gz⋅y−c
- 这等价于:t=gz⋅(gx)−c=gz⋅g−cx=gz−cx
步骤 4:Mallory 发送 (t,c,z) 给验证者
验证检查:
gz=t⋅yc=(gz⋅y−c)⋅yc=gz⋅y−c⋅yc=gz✓
关键观察:
- 生成顺序:Mallory 先选择 z,后计算 t
- 这与正常协议相反:正常协议是先选择 k(从而确定 t),后根据 c 计算 z
- 由于 Mallory 提前知道 c,她可以"倒推":先选择 z,然后计算使得验证等式成立的 t
问题 (b):为什么"幸运猜测"攻击在单次交互中有效
哲学原因:
-
Soundness 依赖于挑战的不可预测性:
- Soundness 的证明依赖于证明者无法预测挑战
- 如果挑战是可预测的,证明者可以"提前准备"响应
-
单次交互的限制:
- 在单次交互中,验证者只发送一次挑战
- 如果挑战可预测,证明者可以针对这个特定挑战构造有效证明
- 验证者无法"重试"来检测证明者是否真的知道秘密
-
"倒推"的可能性:
- 正常协议:t=gk(先确定),z=k+cx(后计算)
- 攻击方法:z(先选择),t=gz⋅y−c(后计算)
- 由于知道 c,可以"倒推"出使得验证等式成立的 t
-
缺乏"知识提取"机制:
- 在单次交互中,验证者无法提取证明者的知识
- 如果挑战可预测,证明者可以"伪造"知识证明,而不需要真正知道秘密
总结:"幸运猜测"攻击在单次交互中有效,是因为 Soundness 依赖于挑战的随机性和不可预测性。当挑战可预测时,证明者可以针对特定挑战构造有效证明,而不需要知道秘密。
问题 1.2:回放陷阱(Special Soundness)
问题描述
场景:为了形式化证明"知识可靠性"(Knowledge Soundness),我们使用一个"思想实验",涉及一个能够"回放"(Rewind)证明者的"提取器"(Extractor)。这个测试的目的是确保证明者不仅仅是"运气好"。
场景描述:
- 恶意证明者被"回放"过程测试
- 证明者输出承诺 t
- 然后被迫正确回答两个不同的挑战
运行 A:挑战 c1 产生有效响应 z1
运行 B:挑战 c2 产生有效响应 z2(其中 c1=c2)
由于 t 在两次运行中相同,这意味着隐藏的随机数 k(使得 t=gk)也是相同的。
问题 (a):根据证明者的知识,写出运行 A 和运行 B 的两个验证方程。
问题 (b):使用代数操作(减法和模运算),证明提取器可以使用仅公开的值 z1,z2,c1,c2 计算秘密 x。推导 x 的公式。
问题 (c):用一句话解释,为什么这个回放过程保证任何能够一致通过这个测试的证明者必须拥有秘密 x。
深度分析
Special Soundness 的概念
Special Soundness(特殊可靠性):
- 如果一个证明者能够对同一个承诺 t 回答两个不同的挑战 c1=c2,那么可以提取出秘密
- 这是比普通 Soundness 更强的性质:不仅保证不知道秘密的证明者无法通过验证,还保证能够通过验证的证明者一定知道秘密(知识提取)
回放(Rewinding)技术
回放技术:
- 提取器可以"回放"证明者,使用相同的承诺 t,但发送不同的挑战
- 如果证明者能够对两个不同挑战都给出有效响应,则可以从两个响应中提取秘密
为什么需要回放:
- 在单次交互中,无法提取秘密
- 通过回放,可以"强制"证明者回答多个挑战,从而提取秘密
标准答案
问题 (a):两个验证方程
运行 A:
- 承诺:t=gk
- 挑战:c1
- 响应:z1=k+c1⋅x(modq)
- 验证方程:gz1=t⋅yc1
运行 B:
- 承诺:t=gk(与运行 A 相同)
- 挑战:c2(c2=c1)
- 响应:z2=k+c2⋅x(modq)
- 验证方程:gz2=t⋅yc2
关键观察:
- 两次运行使用相同的 t 和 k
- 但挑战不同:c1=c2
- 响应也不同:z1=z2
问题 (b):提取秘密 x 的公式推导
已知条件:
- z1=k+c1⋅x(modq)
- z2=k+c2⋅x(modq)
- c1=c2
推导过程:
步骤 1:计算 z1−z2
z1−z2=(k+c1⋅x)−(k+c2⋅x)=c1⋅x−c2⋅x=(c1−c2)⋅x(modq)
步骤 2:求解 x
由于 c1=c2,c1−c2=0,因此 (c1−c2) 在 Zq 中有逆元。
x=(z1−z2)⋅(c1−c2)−1(modq)
验证:
x=c1−c2z1−z2(modq)
提取器的算法:
- 运行协议,获得 (t,c1,z1)
- 回放协议,使用相同的 t,发送不同的挑战 c2,获得 (t,c2,z2)
- 计算:x=(z1−z2)⋅(c1−c2)−1(modq)
关键观察:
- 提取器只需要公开值:z1,z2,c1,c2
- 不需要知道 k(因为 k 在减法中被消去了)
- 只要 c1=c2,就可以计算 x
问题 (c):为什么回放过程保证证明者必须拥有秘密 x
一句话解释:
如果证明者能够对同一个承诺 t 回答两个不同的挑战 c1=c2,那么从两个响应 z1,z2 中可以直接计算出秘密 x=(z1−z2)⋅(c1−c2)−1(modq),这意味着证明者必须知道 x(或者能够计算 x),否则无法构造出满足两个验证等式的响应。
详细解释:
-
知识提取的可能性:
- 如果证明者能够通过回放测试,提取器可以计算 x
- 这意味着证明者"拥有"知识(或者能够计算知识)
-
不可能性论证:
- 如果证明者不知道 x,无法对任意挑战都给出正确响应
- 即使"运气好"通过一次验证,也无法对第二个不同挑战也给出正确响应
- 因此,能够通过回放测试的证明者一定知道 x
-
Special Soundness 的保证:
- Special Soundness 保证:能够通过验证的证明者,其知识可以被提取
- 这比普通 Soundness 更强:不仅保证不知道秘密的证明者无法通过,还保证能够通过的证明者一定知道秘密
问题 1.3:实际实现错误(Nonce 重用)
问题描述
场景:问题 1.2 中证明的数学提取是高度理论化的。然而,有时灾难性的实际实现错误会导致完全相同的提取自然发生。
考虑一个懒惰的证明者 Peggy,她为两个独立的、不同的挑战 c1 和 c2 重用相同的随机值 k(从而重用相同的承诺 t)。攻击者 Eve 观察到两个完整的转录:
- 转录 1:(t,c1,z1)
- 转录 2:(t,c2,z2)
问题 (a):证明 Eve 可以使用与问题 1.2 中相同的代数方法恢复 Peggy 的秘密密钥 x,而不需要"黑客攻击"或"回放时间"。
问题 (b):解释以下两种场景中谁控制 k 的重用,以及为什么一种是特性(Soundness 证明),另一种是致命错误(实际攻击):
- 场景 A:问题 1.2 中提取器强制 k 重用
- 场景 B:本问题中证明者意外重用 k
深度分析
Nonce 重用的危险性
Nonce(随机数)的作用:
- 在 Schnorr 协议中,k 是一个随机数(nonce),用于生成承诺 t=gk
- k 必须每次都是随机选择的,不能重用
Nonce 重用的后果:
- 如果 k 被重用,两个不同的证明使用相同的 t
- 攻击者可以观察到两个转录,从而提取秘密
理论提取 vs 实际攻击
理论提取(问题 1.2):
- 提取器可以"回放"证明者,强制使用相同的 t
- 这是理论上的思想实验,用于证明 Special Soundness
实际攻击(问题 1.3):
- 证明者自己重用 k,导致两个证明使用相同的 t
- 攻击者只需要观察两个转录,就可以提取秘密
- 这是实际实现错误导致的真实攻击
标准答案
问题 (a):Eve 恢复秘密密钥 x
Eve 的观察:
- 转录 1:(t,c1,z1),其中 z1=k+c1⋅x(modq)
- 转录 2:(t,c2,z2),其中 z2=k+c2⋅x(modq)(注意:t 相同,意味着 k 相同)
Eve 的攻击方法:
步骤 1:计算 z1−z2
z1−z2=(k+c1⋅x)−(k+c2⋅x)=(c1−c2)⋅x(modq)
步骤 2:求解 x
由于 c1=c2(两个不同的挑战),c1−c2=0,因此可以计算:
x=(z1−z2)⋅(c1−c2)−1(modq)
验证:
这与问题 1.2 中的公式完全相同!
关键观察:
- Eve 只需要观察两个转录,不需要"回放"或"黑客攻击"
- 由于 Peggy 重用 k,两个转录中的 t 相同
- Eve 可以使用与问题 1.2 中完全相同的代数方法提取 x
实际计算示例:
假设 q=23,c1=5,c2=7,z1=12,z2=18。
x=(12−18)⋅(5−7)−1mod23=(−6)⋅(−2)−1mod23=6⋅11mod23=66mod23=20
其中 (−2)−1mod23=11(因为 −2≡21(mod23),21−1mod23=11)
问题 (b):两种场景的区别
场景 A:提取器强制 k 重用(Soundness 证明)
谁控制重用:
- 提取器控制:提取器通过"回放"技术,强制证明者使用相同的承诺 t(从而相同的 k)
- 这是理论上的思想实验,用于证明 Special Soundness
为什么是特性:
- 理论证明工具:回放是用于形式化证明的工具,不是实际攻击
- 证明安全性:通过证明"如果证明者能够通过回放测试,则可以提取秘密",证明了协议的安全性
- 不依赖实现错误:这是协议设计的一部分,不依赖于实现错误
场景 B:证明者意外重用 k(实际攻击)
谁控制重用:
- 证明者控制:证明者由于实现错误(懒惰、随机数生成器故障等),意外重用相同的 k
- 这是实际实现中的错误
为什么是致命错误:
- 实际攻击:攻击者可以观察到两个转录,直接提取秘密
- 不需要特殊能力:攻击者不需要"回放"能力,只需要观察通信
- 完全破坏安全性:秘密密钥被完全泄露,协议的安全性被完全破坏
对比总结:
| 特性 | 场景 A(提取器强制重用) | 场景 B(证明者意外重用) |
|---|
| 控制者 | 提取器(理论实体) | 证明者(实际实现) |
| 目的 | 证明协议安全性 | 实际攻击 |
| 性质 | 理论工具(特性) | 实现错误(致命错误) |
| 攻击者能力 | 需要"回放"能力 | 只需要观察通信 |
| 结果 | 证明 Special Soundness | 完全破坏安全性 |
关键教训:
- Nonce 重用是致命的:在实际实现中,必须确保每次证明都使用新的随机数 k
- 随机数生成器的重要性:必须使用密码学安全的随机数生成器
- 实现安全性的重要性:即使协议设计是安全的,实现错误也可能导致完全的安全破坏
总结
关键知识点
- Soundness 的重要性:协议必须保证不知道秘密的证明者无法通过验证
- 挑战随机性的重要性:Soundness 依赖于挑战的随机性和不可预测性
- Special Soundness:通过回放技术,可以证明知识可靠性
- Nonce 重用的危险性:在实际实现中,重用随机数会导致秘密泄露
实际应用中的注意事项
- 使用密码学安全的随机数生成器:确保每次证明都使用新的随机数
- 验证挑战的随机性:验证者必须使用真正的随机挑战
- 实现安全性:即使协议设计是安全的,实现错误也可能导致安全破坏
协议设计原则
- 完备性:诚实的证明者应该能够通过验证
- 可靠性:不知道秘密的证明者应该被拒绝
- 零知识性:验证者不应该获得关于秘密的信息
- 知识提取:能够通过验证的证明者,其知识应该可以被提取(Special Soundness)
问题 2:安全投票协议
问题背景与核心挑战
问题 2 基于 ElGamal 加密方案设计一个安全的电子投票系统。该协议需要满足:
- 投票保密性:没有人能知道单个投票的内容
- 投票有效性:每个投票必须是 0 或 1
- 正确计票:能够正确统计总票数
- 可验证性:使用零知识证明确保投票有效性
ElGamal 投票协议的基本结构
公共参数:
- 群 G:素数阶 q 的循环群,生成元为 g
密钥:
- 私钥(计票中心):x∈Zq
- 公钥:h=gx
有效投票:v∈{0,1}
投票加密:
- 投票者选择随机数 r∈Zq
- 计算密文 C=(c1,c2),其中:
- c1=gr
- c2=hr⋅gv
问题 2.1:同态聚合
问题描述
场景:有 N 个投票者,产生单独的密文 C1,C2,…,CN。每个密文 Ci 定义为 (c1,i,c2,i)。
任务:定义一个聚合密文 Cagg,表示总票数 Vtotal=∑i=1Nvi 的加密。
要求:展示数学推导。
深度分析
ElGamal 的乘法同态性
ElGamal 加密的同态性质:
- 给定两个密文 C1=(c1,1,c2,1) 和 C2=(c1,2,c2,2)
- 如果 C1 加密 v1,C2 加密 v2
- 那么 C1⋅C2=(c1,1⋅c1,2,c2,1⋅c2,2) 加密 v1+v2(在指数中)
关键观察:
- ElGamal 的明文空间是群 G
- 如果 v∈{0,1},则 gv∈{g0,g1}={1,g}
- 密文 C=(gr,hr⋅gv) 实际上加密的是 gv
- 多个密文的乘积会得到 gv1+v2+…+vN=gVtotal
标准答案
数学推导
单个投票的加密:
对于投票者 i,投票 vi∈{0,1},随机数 ri∈Zq:
Ci=(c1,i,c2,i)=(gri,hri⋅gvi)
聚合密文的构造:
对所有 N 个密文进行分量乘法:
Cagg=∏i=1NCi=(∏i=1Nc1,i,∏i=1Nc2,i)
计算第一个分量:
c1,agg=∏i=1Nc1,i=∏i=1Ngri=g∑i=1Nri=gRtotal
其中 Rtotal=∑i=1Nri。
计算第二个分量:
c2,agg=∏i=1Nc2,i=∏i=1N(hri⋅gvi)=∏i=1Nhri⋅∏i=1Ngvi=h∑i=1Nri⋅g∑i=1Nvi=hRtotal⋅gVtotal
聚合密文:
Cagg=(c1,agg,c2,agg)=(gRtotal,hRtotal⋅gVtotal)
验证:
聚合密文 Cagg 的形式与单个投票的加密形式相同:
- 第一个分量:gRtotal(其中 Rtotal=∑i=1Nri 是随机数的和)
- 第二个分量:hRtotal⋅gVtotal(其中 Vtotal=∑i=1Nvi 是总票数)
因此,Cagg 确实加密了 gVtotal,即总票数的加密。
问题 2.2:解密
问题描述
描述计票中心使用私钥 x 从 Cagg 恢复整数值 Vtotal 的过程。解释为什么这种解密方法在选举的上下文中是计算上可行的。
深度分析
ElGamal 解密过程
标准 ElGamal 解密:
- 给定密文 C=(c1,c2)=(gr,hr⋅gv)
- 使用私钥 x(其中 h=gx)解密:
- 计算共享秘密:s=c1x=(gr)x=grx=hr
- 恢复明文:gv=sc2=hrhr⋅gv=gv
从 gv 恢复 v:
- 如果 v∈{0,1},则 gv∈{g0,g1}={1,g}
- 可以通过简单比较恢复 v:
- 如果 gv=1,则 v=0
- 如果 gv=g,则 v=1
对于聚合密文:
- 解密后得到 gVtotal
- 需要从 gVtotal 恢复 Vtotal
- 这需要计算离散对数,但 Vtotal 的范围很小(0≤Vtotal≤N)
标准答案
解密过程
步骤 1:计算共享秘密
s=c1,aggx=(gRtotal)x=gx⋅Rtotal=hRtotal
步骤 2:恢复 gVtotal
gVtotal=sc2,agg=hRtotalhRtotal⋅gVtotal=gVtotal
步骤 3:计算离散对数恢复 Vtotal
Vtotal=logg(gVtotal)
计算可行性分析:
-
Vtotal 的范围很小:
- Vtotal=∑i=1Nvi,其中每个 vi∈{0,1}
- 因此 0≤Vtotal≤N
- 在选举中,N 通常是可管理的数字(例如,几千到几百万)
-
暴力搜索是可行的:
- 由于 Vtotal 的范围很小,可以使用暴力搜索:
- 对于 i=0,1,2,…,N:
- 计算 gi
- 如果 gi=gVtotal,则 Vtotal=i
- 时间复杂度:O(N),对于合理的 N 值(例如 N≤106),这是可行的
-
不需要通用离散对数算法:
- 通用离散对数算法(如数域筛法)对于大素数阶群是计算上困难的
- 但由于 Vtotal 的范围很小,不需要使用这些算法
- 简单的暴力搜索就足够了
总结:这种解密方法在选举上下文中是计算上可行的,因为总票数 Vtotal 的范围受到投票者数量 N 的限制,可以使用简单的暴力搜索在多项式时间内恢复。
问题 2.3:零知识证明(Sigma 协议)
问题描述
恶意投票者可能尝试加密除 0 或 1 以外的值(例如 v=5)来操纵结果。为了防止这种情况,每个投票者必须提供一个零知识证明,证明他们的密文 C=(c1,c2) 加密的是 0 或 1,而不泄露是哪一个。
设计一个 Sigma 协议(交互式 3 轮协议)来实现这个目的。
提示:将其表述为 OR 证明,证明 (g,h,c1,c2) 是 Diffie-Hellman 元组,或者 (g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组。
深度分析
Diffie-Hellman 元组
Diffie-Hellman 元组定义:
- 四元组 (g,h,A,B) 是 Diffie-Hellman 元组,如果存在 r 使得 A=gr 且 B=hr
- 等价地,loggA=loghB
在投票协议中:
- 密文 C=(c1,c2)=(gr,hr⋅gv)
- 如果 v=0,则 c2=hr⋅g0=hr,因此 (g,h,c1,c2)=(g,h,gr,hr) 是 Diffie-Hellman 元组
- 如果 v=1,则 c2=hr⋅g1=hr⋅g,因此 c2⋅g−1=hr,所以 (g,h,c1,c2⋅g−1)=(g,h,gr,hr) 是 Diffie-Hellman 元组
OR 证明
OR 证明的目标:
- 证明者想要证明:知道 r 使得 (g,h,c1,c2) 是 Diffie-Hellman 元组,或者知道 r 使得 (g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组
- 但不泄露是哪一个
标准答案
Sigma 协议设计
协议设置:
- 公共输入:(g,h,c1,c2)
- 证明者的秘密:r(使得 c1=gr)
- 证明者的目标:证明 v∈{0,1},即:
- 情况 1:v=0,则 (g,h,c1,c2) 是 Diffie-Hellman 元组
- 情况 2:v=1,则 (g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组
协议步骤:
步骤 1:承诺(Commit)
证明者需要为两种情况生成承诺:
对于真实情况(假设 v=0,即 (g,h,c1,c2) 是 Diffie-Hellman 元组):
- 证明者知道 r 使得 c1=gr 且 c2=hr
- 证明者选择随机数 k0←Zq
- 计算承诺:a0=gk0,b0=hk0
- 发送 (a0,b0) 给验证者
对于模拟情况(v=1 的情况):
- 证明者不知道 r′ 使得 c1=gr′ 且 c2⋅g−1=hr′
- 证明者选择随机数 k1←Zq 和随机挑战 c1←Zq
- 计算模拟响应:z1←Zq
- 计算模拟承诺:a1=gz1⋅c1−c1,b1=hz1⋅(c2⋅g−1)−c1
- 发送 (a1,b1) 给验证者
步骤 2:挑战(Challenge)
验证者选择随机挑战 c←Zq,发送给证明者。
步骤 3:响应(Response)
证明者需要分配挑战:
对于真实情况(v=0):
- 证明者设置 c0=c−c1(modq)
- 计算响应:z0=k0+c0⋅r(modq)
- 发送 (c0,z0,c1,z1) 给验证者
对于模拟情况(v=1):
- 如果 v=1,则证明者知道 r 使得 c1=gr 且 c2⋅g−1=hr
- 类似地,证明者会为 v=1 的情况生成真实证明,为 v=0 的情况生成模拟证明
步骤 4:验证(Verify)
验证者检查:
-
挑战分配:c0+c1≡c(modq)
-
对于情况 0((g,h,c1,c2) 是 Diffie-Hellman 元组):
- gz0=a0⋅c1c0
- hz0=b0⋅c2c0
-
对于情况 1((g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组):
- gz1=a1⋅c1c1
- hz1=b1⋅(c2⋅g−1)c1
如果所有检查都通过,验证者接受证明。
协议总结:
完整协议流程:
-
P → V:(a0,b0,a1,b1)(两个情况的承诺)
-
V → P:c(随机挑战)
-
P → V:(c0,z0,c1,z1)(挑战分配和响应)
-
V 验证:
- c0+c1≡c(modq)
- gz0=a0⋅c1c0 且 hz0=b0⋅c2c0
- gz1=a1⋅c1c1 且 hz1=b1⋅(c2⋅g−1)c1
安全性:
- 完备性:如果 v∈{0,1},诚实的证明者总是能够通过验证
- 可靠性:如果 v∈/{0,1},证明者无法通过验证(因为两种情况都不成立)
- 零知识性:验证者无法知道 v 是 0 还是 1(因为两种情况都提供了有效的证明)
问题 2.4:非交互式证明
问题描述
将问题 2.3 中设计的协议应用 Fiat-Shamir 启发式,使其变为非交互式。指定如何计算挑战。
深度分析
Fiat-Shamir 启发式
Fiat-Shamir 启发式:
- 将交互式零知识证明转换为非交互式零知识证明
- 核心思想:使用哈希函数代替验证者的随机挑战
- 挑战计算为:c=H(公共输入∣∣承诺),其中 H 是哈希函数(在随机预言机模型中)
优点:
- 不需要交互,证明者可以独立生成证明
- 证明可以公开验证
- 适用于区块链等场景
安全性:
- 在随机预言机模型下,非交互式证明的安全性等同于交互式证明
标准答案
应用 Fiat-Shamir 启发式
修改后的非交互式协议:
步骤 1:承诺(与交互式协议相同)
证明者生成承诺 (a0,b0,a1,b1)。
步骤 2:计算挑战(使用 Fiat-Shamir)
证明者计算挑战:
c=H(g∣∣h∣∣c1∣∣c2∣∣a0∣∣b0∣∣a1∣∣b1)
其中 H 是密码学哈希函数(如 SHA-256),在随机预言机模型中建模。
步骤 3:响应(与交互式协议相同)
证明者计算响应 (c0,z0,c1,z1),其中 c0+c1≡c(modq)。
步骤 4:验证(与交互式协议相同)
验证者:
- 重新计算挑战:c′=H(g∣∣h∣∣c1∣∣c2∣∣a0∣∣b0∣∣a1∣∣b1)
- 检查 c′=c
- 执行与交互式协议相同的验证检查
完整非交互式证明:
证明者输出:π=(a0,b0,a1,b1,c0,z0,c1,z1)
验证者验证:
- 计算 c=H(g∣∣h∣∣c1∣∣c2∣∣a0∣∣b0∣∣a1∣∣b1)
- 检查 c0+c1≡c(modq)
- 检查 gz0=a0⋅c1c0 且 hz0=b0⋅c2c0
- 检查 gz1=a1⋅c1c1 且 hz1=b1⋅(c2⋅g−1)c1
关键点:
-
挑战的计算:
- 挑战 c 是哈希函数的输出,依赖于所有公共输入和承诺
- 这确保了证明者无法"选择"挑战(因为承诺已经固定)
-
随机预言机模型:
- 哈希函数 H 在随机预言机模型中建模
- 这确保了挑战的随机性和不可预测性
-
非交互性:
- 证明者可以独立生成完整证明,不需要与验证者交互
- 证明可以公开验证,任何人都可以验证证明的有效性
实际应用:
- 在电子投票系统中,投票者可以独立生成投票和证明
- 证明可以存储在区块链上,供任何人验证
- 不需要在线验证者,提高了系统的可扩展性
总结
关键知识点
- ElGamal 同态加密:支持密文上的乘法操作,实现投票聚合
- 同态聚合:通过密文分量的乘法,可以计算总票数的加密
- 小范围离散对数:当值范围很小时,可以使用暴力搜索
- OR 证明:用于证明投票值在允许范围内,而不泄露具体值
- Fiat-Shamir 启发式:将交互式证明转换为非交互式证明
实际应用中的注意事项
- 投票有效性验证:必须使用零知识证明确保每个投票是 0 或 1
- 随机数生成:投票者必须使用密码学安全的随机数生成器
- 密钥管理:计票中心的私钥必须安全保管
- 可验证性:非交互式证明使得投票可以公开验证
问题 3:BLS 数字签名
问题背景与核心挑战
问题 3 介绍了 BLS(Boneh-Lynn-Shacham)数字签名方案,这是一种基于双线性配对(Bilinear Pairing)的数字签名方案。BLS 签名具有签名短、可聚合等优点,在区块链和分布式系统中广泛应用。
双线性配对的基本概念
双线性配对(Bilinear Pairing):
- 设 G0、G1 和 GT 是三个素数阶 q 的循环群
- 设 g0 是 G0 的生成元,g1 是 G1 的生成元
- 双线性配对是一个可高效计算的函数 e:G0×G1→GT
双线性配对的性质:
-
双线性性(Bilinearity):
对于所有 u∈G0,v∈G1 和 a,b∈Zq:
e(ua,vb)=e(u,v)ab
-
非退化性(Non-degeneracy):
e(g0,g1)=1 在 GT 中
计算 co-Diffie-Hellman(co-CDH)问题
co-CDH 问题:
- 给定:元组 (g0,g0α,g0β)∈G0 和 (g1,g1α)∈G1,其中 α,β∈Zq 是未知随机数
- 问题:计算 g0αβ∈G0
- 假设:对于适当的群,co-CDH 问题是计算上不可行的
BLS 签名方案
设置(Setup):
- 群 G0、G1、GT 和配对 e 是公共参数
- 设 H:{0,1}∗→G0 是密码学哈希函数(在随机预言机模型中建模)
密钥生成(KeyGen):
- 选择随机秘密 α∈Zq
- 私钥(签名密钥):sk=α
- 公钥(验证密钥):pk=g1α∈G1
签名(Sign(sk, m)):
- 对消息 m 签名,计算 h=H(m)∈G0
- 输出签名:σ=hα∈G0
验证(Verify(pk, m, \sigma)):
- 计算 h=H(m)
- 当且仅当以下等式成立时接受:
e(σ,g1)=e(h,pk)
问题 3.1:正确性
问题描述
证明有效生成的 BLS 签名总是通过验证方程。使用配对 e 的双线性性质。
深度分析
正确性证明的关键
需要证明:
- 如果签名 σ=hα 是使用私钥 α 对消息 m 正确生成的
- 那么验证方程 e(σ,g1)=e(h,pk) 应该成立
使用双线性性质:
- 双线性性质允许我们将指数"移动"到配对内部
- 这是证明的关键
标准答案
正确性证明
给定:
- 私钥:sk=α
- 公钥:pk=g1α
- 消息:m
- 签名:σ=hα,其中 h=H(m)∈G0
验证方程:
e(σ,g1)=e(h,pk)
证明过程:
左边:
e(σ,g1)=e(hα,g1)
使用双线性性质:
根据双线性性质 e(ua,vb)=e(u,v)ab,我们有:
e(hα,g1)=e(h,g1)α
右边:
e(h,pk)=e(h,g1α)
再次使用双线性性质:
e(h,g1α)=e(h,g1)α
因此:
e(σ,g1)=e(hα,g1)=e(h,g1)α=e(h,g1α)=e(h,pk)✓
结论:有效生成的 BLS 签名总是通过验证方程。✓
问题 3.2:安全性归约
问题描述
我们想要证明:如果 co-CDH 假设成立,那么 BLS 在随机预言机模型下对选择消息攻击下的存在性伪造(EUF-CMA)是安全的。
设 A 是一个攻击者,最多对哈希预言机 H 查询 qH 次,对签名预言机查询 qS 次,并以不可忽略的概率产生有效伪造。
构造一个模拟器 B,使用 A 来解决 co-CDH 问题。
提示:B 收到 co-CDH 挑战 (u0,u0α,u0β)∈G0 和 (g1,g1α)∈G1。B 应该设置公钥 pk=g1α。
问题 (a):B 应该如何编程随机预言机 H(m),使其能够回答某些消息的签名查询(它知道 H(m) 的离散对数),但将挑战项 u0β 嵌入到目标消息 m∗ 的哈希中?
问题 (b):B 如何从 A 的伪造中提取解 u0αβ?
深度分析
EUF-CMA 安全性
存在性伪造(Existential Forgery):
- 攻击者可以伪造某个消息的签名(不需要是特定消息)
- 但攻击者不能选择要伪造的消息(在查询阶段)
选择消息攻击(Chosen Message Attack):
- 攻击者可以查询签名预言机,获得任意消息的签名
- 这模拟了实际场景中攻击者可以观察合法签名的情况
安全性归约的思路
归约目标:
- 假设存在攻击者 A 能够以不可忽略的概率伪造 BLS 签名
- 构造算法 B,使用 A 来解决 co-CDH 问题
- 如果 A 成功,则 B 可以解决 co-CDH 问题
- 这与 co-CDH 问题的困难性矛盾
- 因此,BLS 是 EUF-CMA 安全的
关键挑战:
- 模拟签名预言机:B 需要能够回答 A 的签名查询,但 B 不知道私钥 α
- 嵌入挑战:B 需要将 co-CDH 挑战嵌入到某个消息的哈希中
- 提取解:从 A 的伪造中提取 co-CDH 问题的解
标准答案
问题 (a):编程随机预言机
B 的策略:
步骤 1:初始化
- B 收到 co-CDH 挑战:(u0,u0α,u0β)∈G0 和 (g1,g1α)∈G1
- B 设置公钥:pk=g1α(这是挑战的一部分)
- B 维护一个哈希表 T,用于存储 H(m) 的值
步骤 2:编程随机预言机 H(m)
对于每个哈希查询 mi(i=1,2,…,qH):
-
如果 mi 是签名查询的消息(B 需要能够生成签名):
- B 随机选择 ri←Zq
- B 计算:H(mi)=(u0α)ri=u0αri∈G0
- B 存储 (mi,ri,H(mi)) 在表 T 中
- 关键观察:B 知道 H(mi) 的离散对数(相对于 u0α):logu0αH(mi)=ri
-
如果 mi 是目标消息 m∗(B 希望 A 伪造这个消息):
- B 设置:H(m∗)=u0β∈G0
- B 存储 (m∗,⊥,u0β) 在表 T 中(⊥ 表示未知离散对数)
- 关键观察:B 不知道 H(m∗) 的离散对数,但这是挑战的一部分
步骤 3:回答签名查询
当 A 查询消息 mi 的签名时:
- B 查找表 T,找到 (mi,ri,H(mi))
- 由于 H(mi)=(u0α)ri,B 需要计算签名 σi=H(mi)α=((u0α)ri)α=(u0α2)ri
- 但 B 不知道 α,无法直接计算
正确的策略:
对于签名查询的消息 mi:
- B 随机选择 ri←Zq
- B 设置:H(mi)=(u0α)ri=u0αri
- 当 A 查询 mi 的签名时,B 需要计算 σi=H(mi)α=(u0αri)α=u0α2ri
- 但 B 不知道 α,无法计算 u0α2ri
修正:使用不同的编程方式:
对于签名查询的消息 mi:
- B 随机选择 si←Zq
- B 设置:H(mi)=u0si(其中 u0 是 G0 的生成元,来自挑战)
- B 存储 (mi,si,H(mi)) 在表 T 中
- 当 A 查询 mi 的签名时,B 计算:
σi=(u0α)si=u0αsi
- 关键:B 有 u0α(来自挑战),所以可以计算 σi=(u0α)si
验证签名的有效性:
e(σi,g1)=e(u0αsi,g1)=e(u0,g1)αsi
e(H(mi),pk)=e(u0si,g1α)=e(u0,g1)siα=e(u0,g1)αsi
因此,e(σi,g1)=e(H(mi),pk),签名有效!✓
对于目标消息 m∗:
- B 设置:H(m∗)=u0β(这是挑战的一部分)
- B 不知道 H(m∗) 的离散对数,因此无法为 m∗ 生成签名
- 这迫使 A 必须伪造 m∗ 的签名
问题 (b):从伪造中提取解
A 的伪造:
- A 输出伪造 (m∗,σ∗),其中 m∗ 是 A 没有查询过签名的消息
- 伪造满足:e(σ∗,g1)=e(H(m∗),pk)=e(u0β,g1α)
B 提取解:
步骤 1:验证伪造的有效性
e(σ∗,g1)=e(u0β,g1α)
步骤 2:使用双线性性质
e(σ∗,g1)=e(u0β,g1α)=e(u0,g1)βα
步骤 3:提取 u0αβ
由于 e(σ∗,g1)=e(u0β,g1α),且配对是非退化的,我们有:
σ∗=u0αβ
验证:
e(σ∗,g1)=e(u0αβ,g1)=e(u0,g1)αβ
e(u0β,g1α)=e(u0,g1)βα=e(u0,g1)αβ
因此,σ∗=u0αβ 是 co-CDH 问题的解。
B 的输出:
- B 输出 σ∗ 作为 co-CDH 问题的解 u0αβ
成功概率:
- 如果 A 以概率 ϵ 成功伪造,且 m∗ 是 A 选择的目标消息(概率至少 1/qH),则 B 以概率至少 ϵ/qH 解决 co-CDH 问题
- 如果 ϵ 是不可忽略的,则 ϵ/qH 也是不可忽略的(因为 qH 是多项式)
结论:
- 如果存在攻击者 A 能够以不可忽略的概率伪造 BLS 签名,则存在算法 B 能够以不可忽略的概率解决 co-CDH 问题
- 这与 co-CDH 问题的困难性矛盾
- 因此,BLS 在 co-CDH 假设和随机预言机模型下是 EUF-CMA 安全的
问题 3.3:签名聚合
问题描述
BLS 最强大的特性之一是非交互式聚合。假设我们有 n 个用户,公钥为 pk1,…,pkn。每个用户 i 对不同的消息 mi 签名,产生签名 σi。
聚合签名计算为 σagg=∏i=1nσi(在群 G0 中计算)。
写出给定公钥集合 {pk1,…,pkn} 和消息集合 {m1,…,mn} 的聚合签名 σagg 的验证方程。证明如果所有单个签名都有效,则验证方程成立。
深度分析
签名聚合的优势
非交互式聚合:
- 多个签名可以聚合成一个签名,而不需要签名者之间的交互
- 聚合签名的大小与单个签名相同
- 可以高效地批量验证多个签名
应用场景:
- 区块链中的多重签名
- 分布式系统中的批量验证
- 减少存储和传输开销
标准答案
聚合签名的验证方程
给定:
- n 个用户的公钥:pk1,…,pkn,其中 pki=g1αi(用户 i 的私钥是 αi)
- n 个消息:m1,…,mn
- 聚合签名:σagg=∏i=1nσi,其中 σi=H(mi)αi
验证方程:
e(σagg,g1)=∏i=1ne(H(mi),pki)
等价形式(使用配对的双线性性质):
e(σagg,g1)=∏i=1ne(H(mi),g1αi)
正确性证明
假设:所有单个签名 σi 都是有效的,即对于每个 i:
e(σi,g1)=e(H(mi),pki)
证明聚合签名的验证方程:
左边:
e(σagg,g1)=e(∏i=1nσi,g1)
使用双线性性质:
由于配对是双线性的,对于群元素的乘积,我们有:
e(∏i=1nσi,g1)=∏i=1ne(σi,g1)
使用单个签名的有效性:
∏i=1ne(σi,g1)=∏i=1ne(H(mi),pki)
右边:
∏i=1ne(H(mi),pki)
因此:
e(σagg,g1)=∏i=1ne(σi,g1)=∏i=1ne(H(mi),pki)✓
结论:如果所有单个签名都有效,则聚合签名的验证方程成立。✓
详细推导(使用双线性性质):
对于每个 i,由于 σi=H(mi)αi 和 pki=g1αi:
e(σi,g1)=e(H(mi)αi,g1)=e(H(mi),g1)αi=e(H(mi),g1αi)=e(H(mi),pki)
因此:
e(σagg,g1)=e(∏i=1nH(mi)αi,g1)=∏i=1ne(H(mi)αi,g1)=∏i=1ne(H(mi),pki)
问题 3.4:恶意公钥攻击
问题描述
考虑多个用户对相同消息 m 签名的特殊情况。验证方程显著简化。
问题 1:写出对单个消息 m 的聚合签名 σagg 的简化验证方程,该签名针对公钥 pk1,…,pkn 进行验证。
问题 2:假设 Alice 有一个公钥 pkA。攻击者想要伪造一个聚合签名,使其看起来来自 Alice 和攻击者,针对消息 m。攻击者可以任意选择自己的公钥 pkadv。
展示攻击者如何选择特定的 pkadv(作为 pkA 的函数)并生成对密钥集合 {pkA,pkadv} 在消息 m 上的有效聚合签名 σagg,而不需要知道 Alice 的秘密密钥。
问题 3:简要提出一个简单的对策来防止这种攻击。
深度分析
相同消息的情况
当所有消息相同时:
- m1=m2=…=mn=m
- H(m1)=H(m2)=…=H(mn)=H(m)=h
- 验证方程可以简化
恶意公钥攻击
攻击场景:
- 攻击者可以自由选择自己的公钥
- 攻击者想要伪造聚合签名,使其看起来来自 Alice 和攻击者
- 攻击者不知道 Alice 的私钥
攻击方法:
- 攻击者可以选择 pkadv,使得验证方程更容易满足
- 通过精心选择 pkadv,攻击者可以"抵消"需要 Alice 签名的部分
标准答案
问题 1:简化验证方程
当所有消息相同时(m1=m2=…=mn=m):
设 h=H(m)∈G0。
聚合签名:
σagg=∏i=1nσi=∏i=1nhαi=h∑i=1nαi
简化验证方程:
e(σagg,g1)=e(h,∏i=1npki)
证明:
左边:
e(σagg,g1)=e(h∑i=1nαi,g1)=e(h,g1)∑i=1nαi
右边:
e(h,∏i=1npki)=e(h,∏i=1ng1αi)=e(h,g1∑i=1nαi)=e(h,g1)∑i=1nαi
因此,验证方程成立。✓
简化形式:
e(σagg,g1)=e(h,pk1⋅pk2⋅…⋅pkn)
问题 2:恶意公钥攻击
攻击者的目标:
- 伪造聚合签名 σagg,使其看起来来自 Alice(公钥 pkA)和攻击者(公钥 pkadv)
- 针对消息 m
- 攻击者不知道 Alice 的私钥 αA(其中 pkA=g1αA)
攻击者的策略:
步骤 1:选择恶意公钥
攻击者计算:
pkadv=pkA−1=(g1αA)−1=g1−αA
步骤 2:生成聚合签名
攻击者计算:
σagg=h0=1∈G0
(其中 h=H(m))
步骤 3:验证攻击是否成功
验证方程:
e(σagg,g1)=e(1,g1)=1
e(h,pkA⋅pkadv)=e(h,pkA⋅pkA−1)=e(h,1)=1
因此,e(σagg,g1)=e(h,pkA⋅pkadv)=1,验证通过!✓
攻击成功:
- 攻击者成功伪造了聚合签名
- 验证者会认为这个签名来自 Alice 和攻击者
- 但攻击者实际上没有 Alice 的签名,也没有自己的有效签名(因为 pkadv=pkA−1 对应的私钥是 −αA,攻击者不知道 αA)
关键观察:
- 攻击者通过选择 pkadv=pkA−1,使得 pkA⋅pkadv=1
- 因此,验证方程变为 e(σagg,g1)=e(h,1)=1
- 攻击者可以简单地设置 σagg=1 来满足验证方程
问题 3:对策
简单对策:证明知识(Proof of Knowledge)
方法:要求每个用户在注册公钥时,提供零知识证明,证明他们知道对应私钥的离散对数。
具体实现:
-
密钥注册阶段:
- 用户 i 生成密钥对:(αi,pki=g1αi)
- 用户 i 生成零知识证明 πi,证明知道 αi 使得 pki=g1αi
- 用户 i 提交 (pki,πi) 进行注册
-
验证注册:
- 验证者验证 πi 的有效性
- 只有通过验证的公钥才被接受
-
防止攻击:
- 攻击者无法为 pkadv=pkA−1 生成有效的知识证明
- 因为攻击者不知道 −αA(攻击者不知道 αA)
- 因此,pkadv=pkA−1 无法通过注册
其他对策:
-
消息绑定:要求每个签名者签名时包含自己的公钥,即签名 H(m∣∣pki) 而不是 H(m)
-
公钥聚合:使用更复杂的聚合方案,要求所有公钥在聚合前已知
-
签名者列表:维护一个可信的公钥列表,只接受来自列表中的公钥的签名
最简单的对策:
- 要求知识证明:每个公钥必须附带零知识证明,证明注册者知道对应的私钥
- 这防止了攻击者注册恶意构造的公钥(如 pkA−1)
总结
关键知识点
- 双线性配对:BLS 签名的基础,允许高效的签名验证和聚合
- co-CDH 问题:BLS 安全性的基础假设
- 签名聚合:BLS 的强大特性,允许将多个签名聚合成一个
- 恶意公钥攻击:当消息相同时,攻击者可以通过选择恶意公钥来伪造聚合签名
- 对策:使用知识证明防止恶意公钥注册
实际应用中的注意事项
- 公钥注册:必须要求知识证明,防止恶意公钥攻击
- 消息唯一性:如果可能,避免多个用户对相同消息签名
- 密钥管理:私钥必须安全保管
- 批量验证:聚合签名可以高效地批量验证多个签名
密码学期末考试题目解答
题目一:概念解释
1.1 Hash Function(哈希函数)
知识点分析
哈希函数的基本概念:
- 哈希函数 H:{0,1}∗→{0,1}n 将任意长度的输入映射到固定长度的输出
- 是密码学的基础工具,用于数据完整性验证、数字签名、密码存储等
三个基本安全性质:
- 原像抵抗性(Preimage Resistance / One-Wayness):给定哈希值 y,找到 x 使得 H(x)=y 在计算上不可行
- 第二原像抵抗性(Second Preimage Resistance):给定 x,找到 x′=x 使得 H(x)=H(x′) 在计算上不可行
- 碰撞抵抗性(Collision Resistance):找到任意 x=x′ 使得 H(x)=H(x′) 在计算上不可行
性质之间的关系:
- 碰撞抵抗性 ⇒ 第二原像抵抗性 ⇒ 原像抵抗性
- 如果哈希函数是碰撞抵抗的,则它也是第二原像抵抗和原像抵抗的
标准答案格式
形式(Form):
哈希函数是一个确定性函数 H:{0,1}∗→{0,1}n,将任意长度的二进制字符串映射到固定长度 n 的二进制字符串。
背景(Background):
哈希函数是密码学的基础工具,广泛应用于:
- 数据完整性验证(如文件校验和)
- 数字签名(如 RSA-FDH、BLS 签名)
- 密码存储(如 bcrypt、scrypt)
- 区块链(如比特币的 Merkle 树)
场景(Scenario):
在实际应用中,哈希函数用于:
- 文件完整性:计算文件的哈希值,用于检测文件是否被篡改
- 密码存储:存储密码的哈希值而非明文密码
- 数字签名:将消息映射到固定长度,然后进行签名
- 承诺方案:使用哈希函数实现承诺
优势(Benefit):
- 效率高:计算速度快,适合处理大量数据
- 固定输出长度:无论输入多长,输出都是固定长度
- 单向性:从哈希值难以恢复原始输入
- 雪崩效应:输入的微小变化会导致输出的巨大变化
1.2 1-n OT(1-out-of-n 不经意传输)
知识点分析
1-n OT 的基本概念:
- 1-out-of-n OT 是 1-out-of-2 OT 的推广
- 发送方有 n 个消息 m1,m2,…,mn
- 接收方选择索引 i∈{1,2,…,n}
- 协议结束后,接收方获得 mi,但不知道其他消息,发送方不知道 i
安全性要求:
- 接收方的隐私:发送方无法知道接收方选择了哪个消息
- 发送方的隐私:接收方无法获得未选择的消息
标准答案格式
形式(Form):
1-out-of-n 不经意传输(1-n OT)是一个密码学协议,允许接收方从发送方的 n 个消息中选择并获得一个消息,而发送方不知道接收方选择了哪个消息。
背景(Background):
1-n OT 是 1-out-of-2 OT 的推广,在以下场景中应用:
- 隐私保护的数据查询
- 安全多方计算
- 电子投票系统
- 隐私保护的机器学习
场景(Scenario):
典型应用场景:
- 隐私查询:用户想从数据库查询一条记录,但不想让数据库知道查询的是哪条
- 隐私拍卖:投标者想获得某个物品的信息,但不想泄露自己的兴趣
- 隐私数据共享:一方想从另一方获得某个数据,但不想泄露自己的选择
优势(Benefit):
- 隐私保护:保护接收方的选择隐私和发送方的消息隐私
- 灵活性:支持从多个选项中选择
- 安全性:基于密码学假设,提供形式化的安全保证
1.3 IBE(Identity-Based Encryption,基于身份的加密)
知识点分析
IBE 的基本概念:
- IBE 是一种公钥加密方案,其中公钥可以是任意字符串(如电子邮件地址、身份证号)
- 私钥由密钥生成中心(PKG)根据身份和主密钥生成
- 不需要公钥证书,简化了密钥管理
IBE 的组成部分:
- Setup:生成系统参数和主密钥
- Extract:根据身份生成私钥
- Encrypt:使用身份加密消息
- Decrypt:使用私钥解密消息
安全性:
- IBE 的安全性基于双线性配对和困难问题(如 BDH 问题)
- 需要解决密钥托管问题(PKG 知道所有私钥)
标准答案格式
形式(Form):
基于身份的加密(IBE)是一种公钥加密方案,其中公钥可以是任意字符串(身份),私钥由密钥生成中心根据身份和主密钥生成。
背景(Background):
IBE 由 Boneh 和 Franklin 在 2001 年提出,解决了传统公钥加密中公钥证书管理的复杂性:
- 传统方案需要公钥基础设施(PKI)和证书
- IBE 使用身份(如电子邮件地址)作为公钥,无需证书
场景(Scenario):
典型应用场景:
- 电子邮件加密:使用收件人的电子邮件地址作为公钥加密邮件
- 物联网:使用设备 ID 作为公钥,简化密钥管理
- 云存储:使用用户身份加密存储在云端的数据
优势(Benefit):
- 简化密钥管理:不需要公钥证书,身份即公钥
- 灵活性:可以使用任意字符串作为公钥
- 可扩展性:适合大规模部署
- 前向安全性:可以撤销身份,使旧密文无法解密
1.4 MPC(Multi-Party Computation,安全多方计算)
知识点分析
MPC 的基本概念:
- MPC 允许多个参与方在不泄露各自私有输入的情况下,共同计算一个函数
- 计算结果是正确的,但任何参与方都无法获得其他参与方的私有输入
MPC 的安全模型:
- 半诚实模型(Semi-Honest):参与方遵循协议,但会尝试从协议执行中推断其他参与方的输入
- 恶意模型(Malicious):参与方可能不遵循协议,试图破坏安全性
MPC 的实现方法:
- 秘密共享(Secret Sharing)
- 同态加密(Homomorphic Encryption)
- 混淆电路(Garbled Circuits)
- 不经意传输(Oblivious Transfer)
标准答案格式
形式(Form):
安全多方计算(MPC)是一个密码学协议,允许多个参与方在不泄露各自私有输入的情况下,共同计算一个函数,并获得正确的计算结果。
背景(Background):
MPC 由 Yao 在 1982 年提出,解决了以下问题:
- 多个参与方需要共同计算,但不想泄露各自的私有数据
- 应用场景包括隐私保护的数据分析、联合机器学习、隐私拍卖等
场景(Scenario):
典型应用场景:
- 隐私保护的数据分析:多个医院想共同分析医疗数据,但不想泄露各自的病人数据
- 联合机器学习:多个公司想共同训练模型,但不想泄露各自的训练数据
- 隐私拍卖:多个投标者想确定中标者,但不想泄露各自的投标价格
- 电子投票:多个投票者想统计投票结果,但不想泄露各自的投票内容
优势(Benefit):
- 隐私保护:保护各参与方的私有输入
- 正确性:保证计算结果的正确性
- 灵活性:可以计算任意函数
- 实用性:随着密码学技术的发展,MPC 已经可以应用于实际场景
题目二:方案设计
题目描述
设计一个安全的文件传输方案,满足以下要求:
- 10GB 文件【大】:需要处理大文件
- Payment(No one knows):支付信息保密,没有人知道支付金额
- Integrity:文件完整性
- Only Bob can check the content:只有 Bob 可以检查文件内容
要求:选择工具,说明过程,说明如何满足每个要求。
知识点分析
核心挑战
-
大文件处理:
- 10GB 文件太大,不能直接加密传输
- 需要使用流式加密或分块加密
- 考虑效率问题
-
支付保密性:
- 支付金额必须保密
- 可以使用同态加密或承诺方案
- 需要支持支付验证而不泄露金额
-
完整性:
- 需要检测文件是否被篡改
- 可以使用哈希函数或 MAC
- 需要支持大文件的完整性验证
-
访问控制:
- 只有 Bob 可以解密和检查文件内容
- 需要使用加密方案
- 考虑密钥分发问题
工具选择
- 对称加密:用于加密大文件(如 AES-256-CTR)
- 公钥加密:用于加密对称密钥(如 RSA-OAEP 或 ElGamal)
- 哈希函数:用于完整性验证(如 SHA-256)
- MAC:用于认证(如 HMAC-SHA256)
- 承诺方案:用于支付保密(如 Pedersen 承诺)
标准答案
工具选择
1. 文件加密:
- 对称加密:AES-256-CTR(流式加密,适合大文件)
- 密钥加密:RSA-OAEP 或 ElGamal(用于加密对称密钥)
2. 完整性验证:
- 哈希函数:SHA-256(用于计算文件哈希值)
- MAC:HMAC-SHA256(用于认证)
3. 支付保密:
- 承诺方案:Pedersen 承诺(用于隐藏支付金额)
方案设计
阶段 1:初始化
-
Bob 生成密钥对:
- Bob 生成 RSA 密钥对:(pkB,skB)
- Bob 将公钥 pkB 发送给 Alice
-
Alice 生成文件密钥:
- Alice 随机生成文件加密密钥:K←{0,1}256
- Alice 使用 K 加密文件:C=AES-CTR-Enc(K,File)
阶段 2:支付处理
-
Alice 生成支付承诺:
- Alice 选择支付金额 p 和随机数 r
- Alice 计算支付承诺:Cp=gp⋅hr(Pedersen 承诺)
- Alice 发送 Cp 给 Bob(Bob 不知道 p)
-
支付验证(可选):
- 如果需要验证支付,Alice 可以打开承诺,但只在特定条件下
- 或者使用零知识证明证明支付金额在合理范围内
阶段 3:文件传输
-
Alice 加密文件密钥:
- Alice 使用 Bob 的公钥加密文件密钥:EK=RSA-Enc(pkB,K)
-
Alice 计算文件哈希:
- Alice 计算文件哈希值:h=SHA-256(File)
-
Alice 生成 MAC:
- Alice 使用共享密钥 KMAC(或从 K 派生)计算 MAC:
- M=HMAC-SHA256(KMAC,C∣∣h∣∣Cp)
-
Alice 发送给 Bob:
- Alice 发送:(C,EK,h,Cp,M) 给 Bob
阶段 4:Bob 接收和验证
-
Bob 解密文件密钥:
- Bob 使用私钥解密:K=RSA-Dec(skB,EK)
-
Bob 解密文件:
- Bob 使用 K 解密文件:File=AES-CTR-Dec(K,C)
-
Bob 验证完整性:
- Bob 计算文件哈希:h′=SHA-256(File)
- Bob 检查 h′=h,如果相等,文件完整
-
Bob 验证 MAC:
- Bob 计算 MAC:M′=HMAC-SHA256(KMAC,C∣∣h∣∣Cp)
- Bob 检查 M′=M,如果相等,数据未被篡改
如何满足每个要求
1. 10GB 文件【大】:
- ✅ 使用 AES-CTR 流式加密:可以逐块加密,不需要将整个文件加载到内存
- ✅ 分块传输:可以将文件分成多个块,分别加密和传输
- ✅ 效率高:对称加密速度快,适合大文件
2. Payment(No one knows):
- ✅ 使用 Pedersen 承诺:Cp=gp⋅hr 隐藏支付金额 p
- ✅ 随机数 r:确保相同金额的承诺看起来不同
- ✅ 只有 Alice 知道 p 和 r:Bob 和其他人无法从 Cp 推断 p
3. Integrity(完整性):
- ✅ SHA-256 哈希:计算文件的哈希值,检测任何篡改
- ✅ HMAC:提供认证,防止数据被修改
- ✅ 验证机制:Bob 可以验证文件是否完整
4. Only Bob can check the content(只有 Bob 可以检查内容):
- ✅ RSA 加密文件密钥:只有 Bob 的私钥可以解密 EK,从而获得 K
- ✅ AES 加密文件:只有拥有 K 的 Bob 可以解密文件
- ✅ 访问控制:其他人无法获得文件内容
题目三:ElGamal 投票系统
3.1 计算流程:给出 x,计算 y, C1, C2, r
题目构造
题目:在 ElGamal 加密方案中,给定:
- 群参数:p=23,g=5(g 是 Z23∗ 的生成元)
- 私钥:x=7
- 消息:m=12
- 随机数:r=3
请计算:
- 公钥 y
- 密文 (C1,C2)
知识点分析
ElGamal 加密方案:
- 密钥生成:私钥 x∈Zp∗,公钥 y=gxmodp
- 加密:选择随机 r∈Zp∗,计算 C1=grmodp,C2=m⋅yrmodp
- 解密:计算 m=C2⋅(C1x)−1modp=C2⋅C1−xmodp
标准答案
步骤 1:计算公钥 y
y=gxmodp=57mod23
计算 57mod23:
- 51=5mod23=5
- 52=25mod23=2
- 54=(52)2=22=4mod23=4
- 57=54⋅52⋅51=4⋅2⋅5=40mod23=17
因此,y=17。
步骤 2:计算密文 C1
C1=grmodp=53mod23=125mod23=10
步骤 3:计算密文 C2
首先计算 yrmodp:
yr=173mod23
计算 173mod23:
- 171=17mod23=17
- 172=289mod23=289−12×23=289−276=13
- 173=172⋅17=13⋅17=221mod23=221−9×23=221−207=14
因此,yr=14。
然后计算 C2:
C2=m⋅yrmodp=12⋅14mod23=168mod23=168−7×23=168−161=7
结果总结:
- 公钥:y=17
- 密文:(C1,C2)=(10,7)
- 随机数:r=3
验证(解密):
m′=C2⋅(C1x)−1modp=7⋅(107)−1mod23
计算 107mod23:
- 101=10mod23=10
- 102=100mod23=8
- 104=(102)2=82=64mod23=18
- 107=104⋅102⋅101=18⋅8⋅10=1440mod23=1440−62×23=1440−1426=14
计算 14−1mod23:
- 使用扩展欧几里得算法:14−1mod23=5(因为 14×5=70≡1(mod23))
因此:
m′=7⋅5mod23=35mod23=12
验证成功:m′=m=12 ✓
3.2 投票同态加密:[gb],b∈{0,1},画出流程
题目构造
题目:设计一个基于 ElGamal 同态加密的投票系统,其中:
- 投票值 b∈{0,1}(0 = 反对,1 = 支持)
- 使用同态加密加密投票:[gb] 表示 gb 的加密
- 要求画出完整的投票和计票流程
知识点分析
ElGamal 同态加密:
- 如果 C1=(gr1,hr1⋅gv1) 加密 gv1,C2=(gr2,hr2⋅gv2) 加密 gv2
- 那么 C1⋅C2=(gr1+r2,hr1+r2⋅gv1+v2) 加密 gv1+v2
- 这是乘法同态(在指数中是加法)
投票流程:
- 设置阶段:生成密钥对
- 投票阶段:每个投票者加密投票
- 聚合阶段:聚合所有密文
- 计票阶段:解密聚合结果
标准答案
流程图:
┌─────────────────────────────────────────────────────────────┐
│ 投票系统流程 │
└─────────────────────────────────────────────────────────────┘
【阶段 1:系统设置】
┌─────────────┐
│ 计票中心 │
│ (Tally) │
└─────────────┘
│
│ 1. 生成密钥对
│ - 选择私钥 x ∈ Zq
│ - 计算公钥 h = g^x
│
▼
┌─────────────┐
│ 公开参数 │
│ (G, q, g, h)│
└─────────────┘
│
│ 2. 广播公钥
│
▼
【阶段 2:投票阶段】
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 投票者 1 │ │ 投票者 2 │ │ 投票者 N │
│ (Voter 1) │ │ (Voter 2) │ ... │ (Voter N) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
│ 3. 选择投票 │ 3. 选择投票 │ 3. 选择投票
│ b₁ ∈ {0,1} │ b₂ ∈ {0,1} │ bₙ ∈ {0,1}
│ │ │
│ 4. 加密投票 │ 4. 加密投票 │ 4. 加密投票
│ - 选择 r₁ │ - 选择 r₂ │ - 选择 rₙ
│ - C₁ = (g^r₁, │ - C₂ = (g^r₂, │ - Cₙ = (g^rₙ,
│ h^r₁·g^b₁) │ h^r₂·g^b₂) │ h^rₙ·g^bₙ)
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ 投票箱(所有密文) │
│ C₁, C₂, ..., Cₙ │
└─────────────────────────────────────────────────────────┘
【阶段 3:聚合阶段】
┌─────────────┐
│ 计票中心 │
└─────────────┘
│
│ 5. 聚合密文
│ C_agg = (C₁ · C₂ · ... · Cₙ)
│ = (g^R_total, h^R_total · g^V_total)
│ 其中 R_total = Σrᵢ, V_total = Σbᵢ
│
▼
【阶段 4:计票阶段】
┌─────────────┐
│ 计票中心 │
│ (使用私钥 x)│
└─────────────┘
│
│ 6. 解密聚合结果
│ - 计算 s = (g^R_total)^x = h^R_total
│ - 计算 g^V_total = (h^R_total·g^V_total) / h^R_total
│
│ 7. 计算离散对数
│ - V_total = log_g(g^V_total)
│ - 使用暴力搜索(因为 V_total ≤ N)
│
▼
┌─────────────┐
│ 投票结果 │
│ V_total │
│ (总支持票数)│
└─────────────┘
详细步骤说明:
步骤 1:系统设置
- 计票中心选择群 G(素数阶 q),生成元 g
- 计票中心选择私钥 x∈Zq
- 计票中心计算公钥 h=gx
- 公开参数:(G,q,g,h)
步骤 2:投票加密
对于每个投票者 i:
- 投票者选择投票 bi∈{0,1}
- 投票者选择随机数 ri∈Zq
- 投票者计算密文:
- c1,i=gri
- c2,i=hri⋅gbi
- 投票者提交密文 Ci=(c1,i,c2,i)
步骤 3:密文聚合
- 计票中心计算聚合密文:
- c1,agg=∏i=1Nc1,i=g∑i=1Nri=gRtotal
- c2,agg=∏i=1Nc2,i=h∑i=1Nri⋅g∑i=1Nbi=hRtotal⋅gVtotal
- 其中 Rtotal=∑i=1Nri,Vtotal=∑i=1Nbi
步骤 4:解密和计票
- 计票中心使用私钥 x 解密:
- 计算 s=c1,aggx=(gRtotal)x=hRtotal
- 计算 gVtotal=sc2,agg=hRtotalhRtotal⋅gVtotal=gVtotal
- 计算离散对数:Vtotal=logg(gVtotal)
- 由于 0≤Vtotal≤N,可以使用暴力搜索
3.3 投票的计算:给出数
题目构造
题目:在 ElGamal 投票系统中,给定:
- 群参数:p=23,g=5,q=11(g 的阶为 q)
- 计票中心私钥:x=3
- 3 个投票者的投票:
- 投票者 1:b1=1,r1=2
- 投票者 2:b2=0,r2=5
- 投票者 3:b3=1,r3=7
请计算:
- 公钥 h
- 每个投票者的密文 (c1,i,c2,i)
- 聚合密文 (c1,agg,c2,agg)
- 总票数 Vtotal
标准答案
步骤 1:计算公钥 h
h=gxmodp=53mod23=125mod23=10
步骤 2:计算各投票者的密文
投票者 1(b1=1,r1=2):
- c1,1=gr1modp=52mod23=25mod23=2
- c2,1=hr1⋅gb1modp=102⋅51mod23=100⋅5mod23=8⋅5mod23=40mod23=17
投票者 2(b2=0,r2=5):
- c1,2=gr2modp=55mod23
- 52=2mod23
- 54=(52)2=22=4mod23
- 55=54⋅51=4⋅5=20mod23
- c2,2=hr2⋅gb2modp=105⋅50mod23=105⋅1mod23
- 102=8mod23
- 104=(102)2=82=64mod23=18
- 105=104⋅101=18⋅10=180mod23=180−7×23=180−161=19
- 因此 c2,2=19mod23=19
投票者 3(b3=1,r3=7):
- c1,3=gr3modp=57mod23
- 从之前计算:57=17mod23
- c2,3=hr3⋅gb3modp=107⋅51mod23
- 107=105⋅102=19⋅8=152mod23=152−6×23=152−138=14
- 因此 c2,3=14⋅5=70mod23=70−3×23=70−69=1
步骤 3:计算聚合密文
c1,agg=c1,1⋅c1,2⋅c1,3modp=2⋅20⋅17mod23=680mod23=680−29×23=680−667=13
c2,agg=c2,1⋅c2,2⋅c2,3modp=17⋅19⋅1mod23=323mod23=323−14×23=323−322=1
步骤 4:解密并计算总票数
解密:
- s=c1,aggxmodp=133mod23
- 132=169mod23=169−7×23=169−161=8
- 133=132⋅131=8⋅13=104mod23=104−4×23=104−92=12
- gVtotal=sc2,aggmodp=121mod23
计算 12−1mod23:
- 使用扩展欧几里得算法:12−1mod23=2(因为 12×2=24≡1(mod23))
因此:
gVtotal=1⋅2=2mod23
计算离散对数:
- 需要找到 Vtotal 使得 gVtotal=5Vtotal≡2(mod23)
- 尝试:50=1,51=5,52=2 ✓
- 因此 Vtotal=2
验证:
- Vtotal=b1+b2+b3=1+0+1=2 ✓
结果总结:
- 公钥:h=10
- 投票者 1 密文:(2,17)
- 投票者 2 密文:(20,19)
- 投票者 3 密文:(17,1)
- 聚合密文:(13,1)
- 总票数:Vtotal=2(2 票支持,1 票反对)
3.4 如果有人撒谎:用 ZK 证明他的 b 不是 0,1
题目构造
题目:在 ElGamal 投票系统中,恶意投票者可能尝试加密除 0 或 1 以外的值(例如 b=5)来操纵结果。设计一个零知识证明协议,证明投票者的密文 C=(c1,c2) 加密的是 0 或 1,而不泄露是哪一个。如果投票者撒谎(b∈/{0,1}),证明应该失败。
知识点分析
OR 证明:
- 需要证明:(g,h,c1,c2) 是 Diffie-Hellman 元组 或者 (g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组
- 如果 b=0,则 c2=hr,所以 (g,h,c1,c2) 是 DH 元组
- 如果 b=1,则 c2=hr⋅g,所以 c2⋅g−1=hr,因此 (g,h,c1,c2⋅g−1) 是 DH 元组
标准答案
协议设计:
公共输入:(g,h,c1,c2)
证明者的秘密:r(使得 c1=gr)
证明者的目标:证明 b∈{0,1},即:
- 情况 1:b=0,则 (g,h,c1,c2) 是 Diffie-Hellman 元组
- 情况 2:b=1,则 (g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组
协议步骤:
步骤 1:承诺(Commit)
证明者需要为两种情况生成承诺:
对于真实情况(假设 b=0,即 (g,h,c1,c2) 是 Diffie-Hellman 元组):
- 证明者知道 r 使得 c1=gr 且 c2=hr
- 证明者选择随机数 k0←Zq
- 计算承诺:a0=gk0,b0=hk0
- 发送 (a0,b0) 给验证者
对于模拟情况(b=1 的情况):
- 证明者不知道 r′ 使得 c1=gr′ 且 c2⋅g−1=hr′
- 证明者选择随机数 k1←Zq 和随机挑战 c1←Zq
- 计算模拟响应:z1←Zq
- 计算模拟承诺:a1=gz1⋅c1−c1,b1=hz1⋅(c2⋅g−1)−c1
- 发送 (a1,b1) 给验证者
步骤 2:挑战(Challenge)
验证者选择随机挑战 c←Zq,发送给证明者。
步骤 3:响应(Response)
证明者需要分配挑战:
对于真实情况(b=0):
- 证明者设置 c0=c−c1(modq)
- 计算响应:z0=k0+c0⋅r(modq)
- 发送 (c0,z0,c1,z1) 给验证者
对于模拟情况(b=1):
- 如果 b=1,则证明者知道 r 使得 c1=gr 且 c2⋅g−1=hr
- 类似地,证明者会为 v=1 的情况生成真实证明,为 v=0 的情况生成模拟证明
步骤 4:验证(Verify)
验证者检查:
-
挑战分配:c0+c1≡c(modq)
-
对于情况 0((g,h,c1,c2) 是 Diffie-Hellman 元组):
- gz0=a0⋅c1c0
- hz0=b0⋅c2c0
-
对于情况 1((g,h,c1,c2⋅g−1) 是 Diffie-Hellman 元组):
- gz1=a1⋅c1c1
- hz1=b1⋅(c2⋅g−1)c1
如果所有检查都通过,验证者接受证明。
如果有人撒谎(b∈/{0,1}):
- 投票者无法为 b=0 或 b=1 生成真实证明
- 只能生成两个模拟证明
- 但模拟证明无法通过验证(因为挑战分配不正确)
- 验证者检测到证明无效,拒绝投票
题目四:Schnorr 签名不安全性证明
4.1 证明 Schnorr 签名的不安全性:(R, Z) 逆元消掉
题目构造
题目:在 Schnorr 签名的变体中,如果签名是 (R,Z) 而不是 (R,s),其中 Z=s−1modq(s 的模逆元),证明这个变体是不安全的。
给定标准 Schnorr 签名:
- 签名生成:s=r+cxmodq,签名是 (R,s),其中 R=gr
- 验证:检查 gs=R⋅yc
变体签名:
- 签名生成:s=r+cxmodq,Z=s−1modq,签名是 (R,Z)
- 验证:需要推导验证方程
知识点分析
Schnorr 签名的标准形式:
- 签名:(R,s),其中 R=gr,s=r+cxmodq
- 验证:gs=R⋅yc
变体的安全问题:
- 如果签名是 (R,Z) 其中 Z=s−1,攻击者可能通过操作 Z 来伪造签名
- 关键问题:如何从 Z 恢复 s,以及验证方程如何修改
标准答案
变体签名的验证方程推导:
由于 Z=s−1modq,我们有 s=Z−1modq。
标准验证方程:gs=R⋅yc
代入 s=Z−1:
gZ−1=R⋅yc
两边同时取 Z 次幂:
(gZ−1)Z=(R⋅yc)Z
即:
g=(R⋅yc)Z=RZ⋅ycZ
因此,变体的验证方程为:
g=RZ⋅ycZ
攻击方法:逆元消掉攻击
攻击场景:
- 攻击者 A 观察到两个有效签名:(R1,Z1) 和 (R2,Z2)
- 两个签名针对不同的消息 m1 和 m2,但使用相同的随机数 r(即 R1=R2=R=gr)
攻击步骤:
步骤 1:观察两个签名
- 签名 1:(R,Z1),其中 Z1=s1−1,s1=r+c1xmodq
- 签名 2:(R,Z2),其中 Z2=s2−1,s2=r+c2xmodq
- 注意:R 相同,意味着 r 相同
步骤 2:利用逆元关系
由于 Z1=s1−1 和 Z2=s2−1,我们有:
- s1=Z1−1modq
- s2=Z2−1modq
步骤 3:计算私钥 x
从两个签名中:
- s1=r+c1xmodq
- s2=r+c2xmodq
计算 s1−s2:
s1−s2=(r+c1x)−(r+c2x)=(c1−c2)x(modq)
如果 c1=c2,则:
x=(s1−s2)⋅(c1−c2)−1(modq)
由于 s1=Z1−1 和 s2=Z2−1:
x=(Z1−1−Z2−1)⋅(c1−c2)−1(modq)
步骤 4:攻击成功
一旦攻击者获得私钥 x,可以伪造任意消息的签名。
为什么变体不安全:
- 逆元操作破坏了安全性:使用 Z=s−1 而不是 s,使得攻击者可以通过观察多个签名来提取私钥
- Nonce 重用更容易被利用:即使 r 被重用,标准 Schnorr 签名也需要两个不同的挑战才能提取私钥;但变体中,逆元关系使得攻击更容易
- 验证方程的问题:验证方程 g=RZ⋅ycZ 中的 Z 和 c 的乘积关系可能被利用
结论:使用 (R,Z) 其中 Z=s−1 的变体是不安全的,因为攻击者可以通过观察多个签名并利用逆元关系来恢复私钥。
4.2 r 的取值只从 {r1,r2,r3} 中,证明不安全性
题目构造
题目:在 Schnorr 签名中,如果随机数 r 不是从整个 Zq 中均匀随机选择,而是只从一个小集合 {r1,r2,r3} 中选择,证明这个变体是不安全的。
给定:
- 标准 Schnorr 签名:s=r+cxmodq,签名是 (R,s),其中 R=gr
- 变体:r 只从 {r1,r2,r3} 中选择
知识点分析
随机数空间的重要性:
- 在 Schnorr 签名中,r 必须从整个 Zq 中均匀随机选择
- 如果 r 的空间很小,攻击者可以暴力搜索 r,从而恢复私钥
小空间攻击:
- 如果 r 只有 3 个可能值,攻击者只需要尝试 3 次就能找到正确的 r
- 一旦找到 r,可以从签名中提取私钥
标准答案
攻击方法:小空间暴力搜索
攻击场景:
- 攻击者 A 知道签名者只从 {r1,r2,r3} 中选择 r
- 攻击者可以查询签名预言机,获得消息 m 的签名 (R,s)
攻击步骤:
步骤 1:查询签名
- 攻击者查询消息 m 的签名,获得 (R,s)
- 其中 R=gr,s=r+cxmodq,c=H(m∣∣R)
步骤 2:暴力搜索 r
由于 r∈{r1,r2,r3},攻击者尝试所有可能值:
对于每个 ri∈{r1,r2,r3}:
- 计算 Ri=grimodp
- 如果 Ri=R,则找到了使用的 ri
步骤 3:恢复私钥 x
一旦找到 ri,从签名方程中:
s=ri+cxmodq
因此:
x=(s−ri)⋅c−1modq
步骤 4:攻击成功
获得私钥 x 后,攻击者可以伪造任意消息的签名。
成功概率分析:
标准情况(r 从整个 Zq 中选择):
- r 有 q 个可能值(q 很大,例如 2256)
- 攻击者需要尝试 q 次,成功概率为 1/q(可忽略)
变体情况(r 只从 {r1,r2,r3} 中选择):
- r 只有 3 个可能值
- 攻击者只需要尝试 3 次,成功概率为 1(在查询足够多次后)
计算复杂度:
标准情况:
- 时间复杂度:O(q)(不可行,因为 q 很大)
- 成功概率:可忽略
变体情况:
- 时间复杂度:O(3)=O(1)(常数时间)
- 成功概率:1(在查询一次后)
结论:
- 如果 r 只从 {r1,r2,r3} 中选择,攻击者可以在常数时间内恢复私钥
- 因此,这个变体是不安全的
- 关键教训:Schnorr 签名要求 r 必须从整个 Zq 中均匀随机选择,任何对 r 空间的限制都会破坏安全性
题目五:零知识证明
5.1 ZK 的 AND Proof(看图说话,说他是什么证明)
题目构造
题目:给定一个 AND 证明的图示(PPT 原图),请描述这个证明是什么类型的证明,并解释其工作原理。
知识点分析
AND 证明的基本概念:
- AND 证明用于证明证明者同时知道多个秘密
- 例如:证明知道 x1 和 x2,使得 y1=g1x1 且 y2=g2x2
AND 证明的协议结构:
- 这是一个 Sigma 协议(3 轮交互协议)
- 包含:承诺(Commit)、挑战(Challenge)、响应(Response)
标准答案
证明类型:
这是一个零知识 AND 证明(Zero-Knowledge AND Proof),用于证明证明者同时知道两个离散对数。
具体来说:
- 证明者想要证明:知道 x1 和 x2,使得 y1=g1x1 且 y2=g2x2
- 这是一个知识证明(Proof of Knowledge),证明证明者"拥有"这些知识
- 同时是零知识的(Zero-Knowledge),验证者无法获得关于 x1 和 x2 的信息
协议描述(基于标准 AND 证明):
公共输入:(g1,g2,y1,y2)
证明者的秘密:(x1,x2)
协议步骤:
-
承诺(Commit):
- 证明者选择随机数 r1,r2←Zq
- 证明者计算:a1=g1r1,a2=g2r2
- 证明者发送 (a1,a2) 给验证者
-
挑战(Challenge):
- 验证者选择随机挑战 c←Zq
- 验证者发送 c 给证明者
-
响应(Response):
- 证明者计算:z1=r1+cx1modq,z2=r2+cx2modq
- 证明者发送 (z1,z2) 给验证者
-
验证(Verify):
- 验证者检查:
- g1z1=a1⋅y1c
- g2z2=a2⋅y2c
- 如果两个检查都通过,验证者接受证明
关键特性:
- AND 性质:必须同时满足两个关系,缺一不可
- 知识证明:如果证明者不知道 x1 或 x2,无法通过验证
- 零知识性:验证者无法从证明过程中获得关于 x1 和 x2 的信息
5.2 ZK 的 Soundness 证明(说 AND Proof 满足 Soundness 性质)
题目构造
题目:证明零知识证明中的 AND 证明满足 Soundness 性质。
给定:证明者要证明知道 x1 和 x2,使得 y1=g1x1 且 y2=g2x2。
请证明:如果证明者不知道 x1 或 x2,则验证者以高概率拒绝证明。
知识点分析
Soundness 的定义:
- 如果证明者不知道秘密,则验证者以高概率拒绝证明
- 形式化:Pr[验证者接受∣证明者不知道秘密]≤ϵ,其中 ϵ 是可忽略函数
AND 证明的 Soundness:
- 必须同时知道 x1 和 x2 才能通过验证
- 如果不知道 x1 或 x2,无法构造有效的响应
标准答案
AND 证明协议回顾:
协议步骤:
- 承诺:证明者发送 (a1,a2),其中 a1=g1r1,a2=g2r2,r1,r2←Zq
- 挑战:验证者发送 c←Zq
- 响应:证明者发送 (z1,z2),其中 z1=r1+cx1modq,z2=r2+cx2modq
- 验证:验证者检查 g1z1=a1⋅y1c 且 g2z2=a2⋅y2c
Soundness 证明:
证明思路:
使用反证法:假设存在攻击者能够以不可忽略的概率通过验证,即使不知道 x1 或 x2。我们将证明这与离散对数问题的困难性矛盾。
情况分析:
情况 1:证明者不知道 x1
假设证明者不知道 x1,但知道 x2。
攻击者策略:
- 攻击者可以正确计算 z2=r2+cx2(因为知道 x2)
- 但无法正确计算 z1=r1+cx1(因为不知道 x1)
验证失败分析:
- 验证者检查:g1z1=a1⋅y1c
- 如果攻击者不知道 x1,无法计算正确的 z1
- 假设攻击者猜测 z1′,则:
g1z1′=a1⋅y1c=g1r1⋅(g1x1)c=g1r1+cx1
- 验证失败的概率:Pr[验证失败]≥1−ϵ,其中 ϵ 是可忽略的
情况 2:证明者不知道 x2
类似地,如果证明者不知道 x2,无法正确计算 z2,验证失败。
情况 3:证明者不知道 x1 和 x2
如果证明者既不知道 x1 也不知道 x2,则无法正确计算 z1 和 z2,验证必然失败。
形式化证明:
假设:存在攻击者 A 能够以不可忽略的概率 δ 通过验证,即使不知道 x1 或 x2。
构造算法 B 求解离散对数问题:
给定离散对数问题实例:(g1,y1),要计算 x1=logg1y1。
算法 B:
- 设置 g2 和 y2=g2x2(B 知道 x2)
- 运行 AND 证明协议作为验证者
- 如果攻击者 A 通过验证,从响应中提取信息
关键观察:
- 如果 A 能够通过验证,则 g1z1=a1⋅y1c
- 即 g1z1=g1r1⋅y1c
- 因此 z1=r1+c⋅logg1y1modq
- 如果 B 知道 r1 和 c,可以计算:logg1y1=(z1−r1)⋅c−1modq
问题:B 不知道 r1(因为 a1=g1r1 是攻击者发送的)
使用重放技术:
- B 运行协议,获得 (a1,a2),发送挑战 c,获得 (z1,z2)
- B 重放协议,使用相同的 (a1,a2),但发送不同的挑战 c′
- 如果 A 再次通过验证,获得 (z1′,z2′)
- 从两个响应中:
- z1=r1+cx1modq
- z1′=r1+c′x1modq
- 因此:z1−z1′=(c−c′)x1modq
- 如果 c=c′,则:x1=(z1−z1′)⋅(c−c′)−1modq
成功概率:
- 如果 A 能够以概率 δ 通过验证
- 则 B 能够以概率至少 δ2 解决离散对数问题
- 如果 δ 是不可忽略的,则 δ2 也是不可忽略的
- 这与离散对数问题的困难性矛盾
结论:
- 如果证明者不知道 x1 或 x2,无法生成有效的 AND 证明
- 验证者拒绝证明的概率 ≥1−ϵ,其中 ϵ 是可忽略函数
- 因此,AND 证明满足 Soundness 性质
5.3 ZK 的 OR Proof:证明 Alice 拥有 [g1,g2] 中的一个和 [g3,g4] 中的一个
题目构造
题目:设计一个零知识 OR 证明,证明 Alice 拥有以下知识之一:
- 知道 x1 使得 y1=g1x1 或者 知道 x2 使得 y2=g2x2
- 并且知道 x3 使得 y3=g3x3 或者 知道 x4 使得 y4=g4x4
即:Alice 拥有 [g1,g2] 中的一个离散对数 和 [g3,g4] 中的一个离散对数。
知识点分析
OR 证明的基本思想:
- OR 证明用于证明知道多个关系中的一个
- 对于不知道的关系,使用模拟证明
- 使用分叉技术(Forking Technique)来分配挑战
复合 OR 证明:
- 本题需要证明:(g1 OR g2) AND (g3 OR g4)
- 这可以分解为:为每个 OR 关系生成证明,然后组合
标准答案
协议设计:
公共输入:(g1,g2,g3,g4,y1,y2,y3,y4)
证明者的秘密:
- Alice 知道 xi 使得 yi=gixi,其中 i∈{1,2} 中的一个 和 j∈{3,4} 中的一个
- 假设 Alice 知道 x1 和 x3(其他情况类似)
协议步骤:
步骤 1:承诺(Commit)
Alice 需要为四个关系生成承诺:
对于真实关系(g1 和 g3):
- Alice 知道 x1 使得 y1=g1x1
- Alice 知道 x3 使得 y3=g3x3
- Alice 选择随机数 r1,r3←Zq
- Alice 计算:a1=g1r1,a3=g3r3
- Alice 发送 (a1,a3) 给验证者
对于模拟关系(g2 和 g4):
- Alice 不知道 x2 和 x4
- Alice 选择随机数 r2,r4←Zq 和随机挑战 c2,c4←Zq
- Alice 计算模拟响应:z2,z4←Zq
- Alice 计算模拟承诺:
- a2=g2z2⋅y2−c2
- a4=g4z4⋅y4−c4
- Alice 发送 (a2,a4,c2,c4) 给验证者
步骤 2:挑战(Challenge)
验证者选择随机挑战 c←Zq,发送给 Alice。
步骤 3:响应(Response)
Alice 需要分配挑战:
对于真实关系(g1 和 g3):
- Alice 设置:c1=c−c2(modq),c3=c−c4(modq)
- Alice 计算响应:
- z1=r1+c1⋅x1(modq)
- z3=r3+c3⋅x3(modq)
- Alice 发送 (c1,z1,c3,z3) 给验证者
对于模拟关系(g2 和 g4):
- Alice 已经发送了 (c2,z2,c4,z4)
步骤 4:验证(Verify)
验证者检查:
-
挑战分配:
- c1+c2≡c(modq)
- c3+c4≡c(modq)
-
对于 g1 关系(如果 Alice 知道 x1):
- g1z1=a1⋅y1c1
-
对于 g2 关系(模拟):
- g2z2=a2⋅y2c2
-
对于 g3 关系(如果 Alice 知道 x3):
- g3z3=a3⋅y3c3
-
对于 g4 关系(模拟):
- g4z4=a4⋅y4c4
如果所有检查都通过,验证者接受证明。
完整协议流程:
-
Alice → Verifier:(a1,a2,a3,a4,c2,c4)(承诺和部分挑战)
-
Verifier → Alice:c(随机挑战)
-
Alice → Verifier:(c1,z1,z2,c3,z3,z4)(挑战分配和响应)
-
Verifier 验证:
- c1+c2≡c(modq) 且 c3+c4≡c(modq)
- g1z1=a1⋅y1c1 且 g2z2=a2⋅y2c2
- g3z3=a3⋅y3c3 且 g4z4=a4⋅y4c4
安全性:
- 完备性:如果 Alice 知道 x1 和 x3(或相应的组合),诚实的 Alice 总是能够通过验证
- 可靠性:如果 Alice 不知道 [g1,g2] 中的一个 或者 不知道 [g3,g4] 中的一个,无法通过验证
- 零知识性:验证者无法知道 Alice 知道的是 g1 还是 g2,以及是 g3 还是 g4
关键观察:
- AND 组合:必须同时满足两个 OR 关系
- OR 证明:每个 OR 关系使用标准的 OR 证明技术
- 挑战分配:使用分叉技术确保挑战正确分配
总结
关键知识点回顾
- 概念解释:Hash Function、1-n OT、IBE、MPC 的基本概念和应用
- 方案设计:大文件传输、支付保密、完整性、访问控制
- ElGamal 投票:同态加密、密文聚合、零知识证明
- Schnorr 签名安全性:逆元攻击、小空间攻击
- 零知识证明:AND 证明、OR 证明、Soundness 证明
考试答题技巧
- 概念题:按照 Form、Background、Scenario、Benefit 的结构回答
- 方案设计题:明确工具选择、详细过程、逐条说明如何满足要求
- 计算题:步骤清晰、验证结果
- 证明题:逻辑严密、使用反证法或归约技术