密码学
Schnorr

Schnorr

Schnorr 签名基于有限域椭圆曲线, 与 ECDSA 类似, 但是 Schnorr 相对于 ECDSA 来说, 更快速, 并且可以实现多签聚合。

假设有通信双方 A 和 B, 已知椭圆曲线 Ep(a,b)E_p(a, b) 、基点 GGGG 的阶 nn,要签名的消息 mm

A 生成自己的公钥和私钥,即从 {1,,n1}\{1,\cdots,n-1\} 随机选择一个数 kAk_A 作为私钥,公钥 HA=kAGH_A=k_AG

A 签名过程如下:

  • {1,,n1}\{1,\cdots,n-1\} 中选择一个数 kk
  • 计算点 RR 的坐标: R=kGR = kG
  • 将要签名的消息 mm、公钥 HAH_ARRxx 坐标组合进行哈希运算, 得到 e=Hash(Rx  HA m)modne=\mathrm{Hash}(R_x \ || \ H_A|| \ m) \mod n
  • 计算 s=k+ekAmodns = k + e \cdot k_A \mod n

最终签名结果是 (Rx,s)(R_x, s)

计算 ee 时, 使用的哈希函数通常是 Sha256

已知要签名的消息 mm 、签名数据 (Rx,s)(R_x, s)、A 的公钥 HAH_A, B 验证过程如下:

  • 计算哈希值 e=Hash(Rx  HA m)e = \mathrm{Hash}(R_x \ || \ H_A|| \ m)
  • 验证等式: sG=Rx+eHAsG = R_x + eH_A 是否成立。

证明:

Rx+eHA=Rx+ekAG=kG+ekAG=(k+ekA)G\begin{aligned} R_x + eH_A &= R_x + e \cdot k_AG \\ &= kG + e \cdot k_A \cdot G \\ &= (k + e \cdot k_A)G \\ \end{aligned}

k+ekAk + e \cdot k_A 结果等于 ss 时, 则说明签名有效。

与 ECDSA 的区别

  • ECDSA 签名过程需要计算 k1k^{-1} 求模逆元, 而 Schnorr 签名直接计算 s=k+ekAmodns = k + e \cdot k_A \mod n, 没有求逆运算, 运算速度更快
  • ECDSA 签名验证需要两次标量乘法 u1Gu_1Gu2HAu_2H_A, 而 Schnorr 签名验证只需要验证 sG=R+ePsG = R + eP, 运算过程更简单
  • Schnorr 支持多个签名聚合

Schnorr 另一个重要的特征是聚合签名。聚合签名用于将多个签名数据聚合成一个签名数据, 从而减少总签名数据的大小, 降低交易费用。

聚合签名的过程如下:

  • 对于每一个签名的参与者使用同一种椭圆曲线和基点 GG, 生成各自的私钥 kmk_m 和公钥 PiP_i

  • 每个参与者选择不同的随机数 kik_i, 并计算对应的 Ri=kiGR_i = k_iG

  • 与单签不同的, 聚合签名计算 ee 时需要每一个签名参与者的公钥聚合, 以及 RiR_i 聚合。公钥和 RiR_i 都是有限域椭圆曲线上的点。聚合最简单的方式是点加: 将 PiP_i 依次相加得到聚合公钥点 Pagg=PiP_{agg} = \sum P_i, 将 RiR_i 依次相加得到聚合点 Ragg=RiR_{agg} = \sum R_i

  • 计算哈希值 e=Hash(Ragg  Pagg m)e = \mathrm{Hash}(R_{agg} \ || \ P_{agg}|| \ m)

  • 每个签名的参与者使用各自的私钥 kmk_m 以及 选择的随机 kik_i 计算各自的 si=ki+ekmmodns_i = k_i + e \cdot k_m \mod n

  • 计算聚合签名 sagg=simodns_{agg} = \sum s_i \mod n, 这里的加法是算术加法。

  • 最终的聚合签名是 (Ragg,sagg)(R_{agg}, s_{agg})

验证聚合签名时, 只需验证等式 saggG=Ragg+ePaggs_{agg}G = R_{agg} + eP_{agg} 是否成立。

ECDSA 无法多签聚合的原因

假设现有两个 ECDSA 签名数据:

  • r1=k1Gr_1=k_1G, s1=k11(m+r1ku1)modns_1 = k_1^{-1}(m + r_1k_{u1}) \mod n

  • r2=k2Gr_2=k_2G, s2=k21(m+r2ku2)modns_2 = k_2^{-1}(m + r_2k_{u2}) \mod n

聚合 rrss:

  • ragg=r1+r2r_{agg} = r_1 + r_2
  • sagg=s1+s2=k11(m+r1ku1)+k21(m+r2ku2)modns_{agg} = s_1 + s_ 2 = k_1^{-1}(m + r_1k_{u1}) + k_2^{-1}(m + r_2k_{u2}) \mod n

签名数据 (ragg,sagg)(r_{agg}, s_{agg})

问题在于 ss 无法聚合。因为 s1s_1s2s_2 中包含了 k11k_1^{-1}k21k_2^{-1} 这样的求模逆元运算, 使签名具有非线性特征。

而在 Schnorr 签名中, 由于没有求模逆元运算, 则可以直接聚合 ss

Copyright © 2025 HeapUp