Hi 游客

更多精彩,请登录!

比特池塘 区块链前沿 正文

一文读懂比特币Schnorr签名

落日余晖97
127 0 0
公私密钥对是加密货币安全性的基石,从安全的网页浏览到加密货币金融业务。公私密钥对是不对称的,这意味着给定一串数字(私钥),可以导出另一串(公钥)。但是,反之就不可行。正是这种不对称性允许人们公开分享公钥,公开也能确信没有人可以推导出私钥(私钥需要秘密且安全地保管)。
$ E" K5 z, g; F/ z( S非对称密钥对主要用于两种应用:- e; W) q* I9 I  x
· 在身份验证中,你需要证明自己掌握私钥;+ K, }8 V* P9 o: O
· 在加密过程中,信息可以编码,只有拥有私钥的人才能解密和阅读消息。( j, Q1 T8 i, D5 U, c2 W. z
在本篇数字签名的介绍中,我们将讨论一类特定的钥匙:从椭圆曲线派生的钥匙,还有其他非对称方案,其中最重要的是基于素数乘积的方案,包括RSA密钥[1]。4 e2 {0 |4 I0 n' f: Y  N/ y3 B0 H
我们假设你了解椭圆曲线加密(Elliptic Curve Cryptography)的基础知识,如果不了解的话没关系可以到原文的前一章节了解。
- E9 \6 J6 \2 r: H/ s" ~·进入正题8 n2 Q4 a( o6 r9 i  y9 U! A1 O
这是对数字签名的交互式介绍,使用Rust代码来演示本文提及的一些想法,因此你可以看到它们是如何运作的,本文介绍的代码使用的是libsecp256k-rs子库。) y/ T. e3 k! H. ^
这个名字有点拗口,但secp256k1是椭圆曲线的名称,它用于保护很多加密货币交易,包括比特币。, ?6 y. w3 m# G- D5 I0 M& ^# a
这个特殊的库提供了一些很不错的功能,我们重写了加法和乘法运算符,以便Rust代码看起来更像数学公式,这使我们更容易试验想要实施的想法。$ N; N7 n5 B$ C; {
友情提示!不要在编写代码过程中使用此库,它没有经过验证,如果需要的话可以用这个子库替代。: }5 k, o$ z. b  p# @  i6 u
·Schnorr签名的基础知识
% Z4 L8 ^5 h( n: S7 }·公钥和私钥! W" T  _' d, {" p6 g$ ^
我们要做的第一件事是从椭圆曲线创建公钥和私钥。
* o# t7 r0 t5 @) d7 |: {在secp256k1中,私钥只是0到2256之间的标量整数值,数量之多相当于整个宇宙的原子数,所以有无穷无尽的可能性。6 \/ {& H( E3 H* q. I2 ^# I
secp256k1曲线上有一个特殊点,名为G,它充当“原点”。公钥是通过将曲线上的G加到自身,乘以“Ka”,这是标量乘法的定义,写成:1 E5 d* _1 ]: ~5 a. S" ]
Pa=KaG; M) A) U$ ~5 J9 C3 u, z3 X2 |: P
举个例子,当以未压缩格式编写时,1的公钥是0479BE667 ... C47D08FFB10D4B8,以下代码演示了这一点:4 S) o/ ]- C# ]( \% [# s$ q+ V8 i2 T
$ y% i( d4 H8 P
·创建签名9 W  k/ |6 l& t/ b3 V/ i8 \6 b) ?
采用方式
: n) e2 T3 i$ k4 X, D2 C3 A当为标量使用正确选择的随机值时,反转ECC数学乘法(即除法)几乎是不可行的([5],[6])。这个属性称为离散日志问题(Discrete Log Problem),作为许多加密货币和数字签名背后的原理使用。有效的数字签名是证明签名提供人知悉与消息相关联的公钥/私钥的证据,或者已解决离散日志问题的证据。6 ?! _3 A7 a: r: |% ~. j  M3 e# X- S
创建签名的方法始终遵循以下方法: 1. 生成秘密一次性数字r(称为随机数)。 2. 从r创建公钥R,其中(R=rG)。 3. 将以下内容发送给你的收件人Bob——你的消息(m),R和你的公钥(P=kG)。
& X$ H% M- j3 N( {! F) N通过哈希上述所有公共信息的组合来创建实际签名以创建问题,e:
; d6 ^1 ]) @! ?, o: Ee=H(R||P||m)* `$ P! }$ I9 k- G3 m8 q
选择哈希函数,使e与私钥具有相同的范围,在我们的例子中,我们想要返回的信息是256位数字,所以SHA256是个不错的选择。' n% U7 J- U2 q4 A9 _7 r; L) a
现在使用你的私人信息构建签名:s=r+ke( G: J4 P0 M3 l2 R; }: j7 m
Bob现在也可以计算e,因为他已经知道m、R、P,但是他不知道你的私钥或随机数。2 [( D* V& d' p. D
注意:创建这样的签名被称为Schnorr签名,我们稍后会继续讨论,还有其他创建s的方法,比如在比特币中使用的ECDSA [2]。
0 o8 N  O* w" ?看这个例子:sG=(r+ke)G5 y7 E, ^* A, Z% ?: O1 N6 X+ k9 `
将右侧相乘:sG=rG+(kG)e
$ E) U' u+ H- h8 b! J/ S0 ?替代R=rG和P=kG,可以得到:sG=R+Pe+ i' |9 p1 C0 u2 c- i3 [3 j
所以Bob必须计算对应于签名(s.G)的公钥,并检查它是否与等式(R+Pe)右侧相等,这些消息对于Bob来说都已知。
1 r" G; W8 R& t6 z9 d
% g" w* e( Y  L  p·随机数Nonce的必要性,为什么标准签名中需要随机数?: n2 l+ q4 I1 v; W4 |
假设我们仅仅只是签署了一条消息m:
/ p! I) n2 ?& i; a; w: E- L% @e=H(P||m)
% w; r& q+ A% _* A1 s8 N/ _: u签名为s=ek* r8 D! v* d0 L% J9 A
我们可以照常检验签名是否有效?( c* L% X' V3 R7 d9 K6 |
目前为止都正常,但是现在任何人都可以阅读你的私钥,因为s是标量,所以k=s/e并不难,至于随机数,必须求解k=(s-r)/e,但r是未知的,所以只要r是随机选择的,这就不是一个可行的计算。2 O, o9 D& \3 _7 T4 Y8 r
我们可以证明,没有随机数确实是非常不安全的:
7 d$ ^1 F2 a/ j" y, S/ |
; u# w7 P: S& i1 D·ECDH是什么?4 G* P" Y. Z  v
想要实现安全通信的各方要如何生成用于加密消息的共享密钥?一种方法称为椭圆曲线Diffie-Hellmam交换(Elliptic Curve Diffie-Hellmam exchange),这是一种简单的方法。8 \0 x& d: j, i- F1 A6 W5 U! j
ECDH用于许多地方,包括通道协商期间的闪电网络[3]。! |2 K- k: d4 \" e2 d- B( Y% C- S2 E5 I
这是它的工作原理,Alice和Bob想要安全地沟通,一种简单的方法是使用彼此的公钥并进行计算:
8 z# Y7 y' l$ y' m9 s& g0 W' q, F' j- n3 Z7 c
出于安全原因,通常会为每个会话随机选择私钥(这涉及到“临时密钥”这一术语的使用),但是我们遇到的问题是不确定对方是否与他们声称的身份相符(可能是中间人攻击[4])。2 Z5 u( [3 m! Q) G% j/ ^
可以采用其他身份验证步骤来解决此问题,这里不再详述。
! {2 e9 c# J% y) F- {- r8 O& I6 v- P% Z4 `6 {5 y( \# ^: C! T% D
·Schnorr签名( E+ I2 \1 A- Q. Q
如果你经常关注加密货币新闻,就会知道比特币Schnorr签名是多热门的话题。0 _& ?" o: w" j7 N
但实际上,这已经算是旧闻了,Schnorr签名被当作是随机预言模型中最简单的安全数字签名方案,它很有效并且生成短签名,获得美国专利4995082,该专利于2008年2月到期[7]。
$ B; i5 @5 d7 {" q- q7 k# i5 @5 P6 p1 g  R, ~' c; u0 q& O/ n1 z. O" a
·为什么Schnorr签名能引起关注?) G! ?! p$ i/ F
Schnorr签名如此迷人而危险的原因在于简洁性。 Schnorr签名是线性的,因此具有一些优良属性。
' {" G1 c1 ~* B; V. G* Z8 V椭圆曲线具有乘法性质,因此,如果有两个对应点X,Y和相应的标量x,y,则:3 K5 p9 u0 z' w( }1 }6 o
(x+y)G=xG+yG=X+Y
2 z, I1 z6 F% P, ?Schnorr签名的形式为s=r+ek,这种结构也是线性的,因此它非常适合椭圆曲线数学的线性。; C( M9 e" ~: n
在上一节中已经介绍了线性,当我们验证签名时,Schnorr签名的线性使其非常具有吸引力,其中包括: 1. 签名聚合; 2. 原子交换; 3.“无脚本”脚本& g! e& J( Y. z8 H$ y

# \6 P) m0 D+ V( t·Na?ve签名聚合
  `5 f6 [+ e( ]  A3 S1 G让我们看看,Schnorr签名的线性属性如何用于构造多重签名。* ]1 g5 j5 X$ b" @8 o
Alice和Bob想要签署一些东西(比如Tari交易)而不必相互信任,也就是说,他们需要证明其各自密钥的所有权,并且只有在Alice和Bob都提供其签名部分时,聚合签名才有效。
8 E) n3 F) L6 P9 H* g4 K" Q假设私钥表示为ki,公钥表示为Pi。 如果我们要求Alice和Bob各自提供一个随机数,可以尝试:6 u1 _# i+ `7 p) S* f+ \
所以Alice和Bob可以自己提供R,任何人都可以从R的总和公钥中构建两个两个签名,这的确可行:
& `/ y+ G; @6 T0 W$ |4 q
$ X2 j' y- g3 E. E0 s但是这个框架并不安全!( \6 T1 V( H8 e5 J2 Z7 y

- ^1 L- k( p! E. w8 w1 \$ ~0 R·密钥消除攻击9 F' ~3 n1 ~  E( N% C) W
依旧是上述场景,但这一次,在Alice公布以后,Bob提前知道了Alice的公钥和随机数。
' X. n( ?' q9 t8 O/ _现在Bob说谎并说他的公钥是P'b=Pb-Pa,公共随机数是R'b=Rb-Ra。1 _; d% i8 C* s  K
Bob并不知道伪造值的私钥,但是也没多大影响。: |- t+ k3 ]8 Q' v
根据聚合方案,每个人都假设Sagg=Ra+R'b+e(Pa+P'b)。9 M1 K* d' C) k5 q+ w1 l" e
但Bob可以自己创建这个签名:
* G' ^  `; T+ d9 s/ t' V
4 q2 x9 C# n; z, @5 B* N' T% j/ H
( @" A" }0 ]# Z5 F  D2 l' L% E·更好的聚合方法- C5 f7 o: t6 K
在密钥取消攻击中,Bob不知道发布的R和P值的私钥,我们可以要求他签署一则消息证明他确实知道私钥,让Bob攻击失败。
! _% |3 ~0 x' a) A6 v/ H: w这是有效的,但它需要在各方之间进行另一轮消息传递,这不利于良好的用户体验。
* E7 q1 P  Z  L2 c( y3 b更好的方法是包含以下一个或多个功能的方法: · 它只需证明在普通的公钥模型中是安全的,而不必证实和密钥有关消息,因为我们可以要求Bob在na?ve模式中证明。 · 它应该满足常规的Schnorr方程,即可以用R+eX形式的表达式验证得到的签名。 · 它允许交互式聚合签名(IAS),签名者需要配合。 · 它允许非交互式聚合签名(NAS),其中聚合可以由任何人完成。 · 它允许每个签名者签署相同的消息,m。 · 它允许每个签名者签署自己的消息,mi。
0 ?# C, h, J2 A) B+ V
! k; l9 ~1 a8 k2 x# Y- [·多重签名4 d; g2 v* O4 K2 {. j
多重签名是最近提出的([8],[9])简单签名聚合方案,它满足前一节中的所有属性。" B4 @$ b2 X' o* B* B
·多重签名演示
9 J* y7 e" R5 \$ a$ n) w. a4 m我们将在这里演示交互式多重签名方案,每个签名者签署相同的消息,该计划的工作原理如下: 1. 如前所述,每个签名者都有一个公私密钥对。 2. 每个签名者都对他们的公共随机数共享一个承诺(在本演示中跳过此步骤),此步骤对防止某些类型的恶意密钥攻击是必要的[10]。 3. 每个签名者都发布他们的随机数,Ri的公钥。 4. 每个人都计算相同的“共享公钥”,X如下:
, J, z4 l: i7 e$ T8 V请注意,在上述公钥排序中,应遵循某些既定规则,例如按字典顺序序列化密钥。 1. 每个人也计算共享的随机数,R=∑Ri。 2. 问题,e是H(R||X||m)。 3. 每位签名者都需要对签名提供贡献:4 n  l* h* d# F2 V8 Q9 ]$ E/ a7 d
注意,标准Schnorr签名的唯一出发点是包含因子ai。+ e0 U8 q6 k6 v0 n9 W$ ~
聚合总签名一般是总和,s=∑si。  W& {/ V$ d# F; U( e
通过以下方式确认验证:sG=R+eX' \) f+ S  o- n/ P) |& U% q+ u
证明:
& B- r# d$ _+ F& W让我们用三重签名来演示:# O  }  K3 v  n% r# E" ^4 N" q) W, g
. Z* O' z: O9 X4 e2 G

8 U" z( n4 Q, ?  n  ]  T2 d·安全演示
% E+ B- E8 Y' S8 o# P作为最后的演示,让我们展示一下多重签名如何从na?ve签名方案中抵御消除攻击。与密钥消除攻击部分想法相同,Bob在他的随机数和公钥中提供了假值:* _: i+ F6 ]  f! S2 }
这导致Alice和Bob共同进行了以下计算:
6 F; P$ t- R2 W, FBob随后在多重签名后构建单边签名:
1 b. \  l% u7 G1 W; E/ A1 B+ F2 m我们现在假设ks不需要成为Bob的私钥,但是他可以使用他已知的信息来推导,要使其成为有效签名,必须验证R+eX,因此:
# s* n6 A" k$ M在之前的攻击中,Bob从类似计算中获得了所需的所有算式右侧信息,在多重签名中,Bob必须以某种方式知道Alice的私钥和伪造的私钥(这些条款不再取消)才能创建单边签名,因此他的消除攻击失败。: |% w, g2 H: |# f

& _5 R4 Q) h2 U+ L6 S0 |+ a% p  a·重放攻击
8 y' X$ r8 g8 J+ a) ]& n1 m1 ]每个签名仪式都要选择一个新的随机数,这一点至关重要,最好的方法是使用加密安全(伪)随机数生成器(CSPRNG)。8 k; G3 Q0 C$ A/ ^5 Q
但即使是这种情况,攻击者可以通过将签名仪式“倒带”到产生部分签名的时间点来诱骗我们签署新消息,此时,攻击者提供了一个不同的消息,e'=H(...||m')来进行签名,而不会引起任何怀疑,每一方会再次计算他们的部分签名:
, @! z6 @- m' B$ y4 b6 n攻击者仍然可以访问第一组签名,只需要简单地做减法:
" k( d- V+ T- H% @) X最终等式右侧的所有消息都被攻击者获取,因此他可以轻易地提取每个人的私钥,这种攻击很难防御。一种方法是增加终止和重启签名仪式的难度,如果多重签名仪式被中断,那么需要再次从第一步开始,这相当符合人体工程学,在出现更强大的解决方案之前,它可能是目前最好的解决方案!
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

落日余晖97 初中生
  • 粉丝

    0

  • 关注

    0

  • 主题

    22