声明: 本文纯做技术分享, 不代表任何加密货币投资购买建议
背景: 在之前的加密货币安全基石: MTA协议在Ecdsa门限签名的应用(计算签名中的r) 中,我向大家展示了MTA协议如何拆分Ecdsa门限签名中的r.在这篇文章中,我将在上篇文章基础更进一步, 讲解MTA协议如何计算Ecdsa门限签名中的s. 看完本文章, 你将彻底理解Ecdsa门限签名的秘密。
需要你有一些密码学, 加密货币, 区块链的前置知识:
- 使用 golang 实现一个极简的 区块链
- 加密货币安全基石:直观理解ECC椭圆曲线加密算法
- 加密货币安全基石:从ECC到ECDSA椭圆曲线签名
- 加密货币安全基石: 从拉格朗日插值到shamir共享密钥算法
- 加密货币安全基石: 从Shamir到Feldman VSS算法, 以币安tss-lib库为例
- 加密货币安全基石: 详解 Paillier 同态加密并使用币安tss-lib库
- 加密货币安全基石: 分布式密钥生成协议(GG18, 币安tss-lib keygen部分)
- 加密货币安全基石: MTA协议在Ecdsa门限签名的应用(计算签名中的r)
回顾 ECDSA 签名
ECDSA 的详细原理中我之前的 加密货币安全基石:从ECC到ECDSA椭圆曲线签名 中有详细介绍, 这里我们简单回顾一下即可。
定义 G为椭圆曲线 起点, g 为循环群, 私钥 为 d, 公钥Q=dG, n 为 一个大质数, 被签名的原文为 M ,
其中 G,Q,M,n 公开, d 为签名方严格保密
签名过程如下:
- 对原文进行取哈希操作, 令 z=hash(M)
- 从 [1,n−1] 范围内选一个随机数 k, 计算终点 R=(k−1)G=g(k−1), R 的 横坐标记为 r
- 计算 s=k−1(z+rd)modn, 其中 k−1 为 kmodn 的逆元
- 最终签名由两部分组成 sign=(r,s)
明白了如何拆分r和s 也就明白了如何进行ecdsa门店签名, 在上一篇文章中我们着重讲解了如何拆分r, 这篇文章着重讲解如何拆分s。
为了简略,我们将s=k−1(z+rd)modn 简化成 s=k(z+rd), 其中 k为随机数, d为完整私钥。
回顾 MTA 协议
MTA 协议 是一种秘密交换协议. 需要两个参与方, 命名为 Alice 和 Bob。
其中Alice 拥有 Paillier 公私钥对, 拥有 秘密值 a.
Bob 拥有 秘密值 b 和随机数 β′ .
MTA协议可以做到在 Alice 不泄露 a 的情况下, 在 Bob 不泄露 b 的情况下, 让 Alice得到一个数 α , 让 Bob 得到一个数字β 使得下列等式成立:
α+β=ξ=ab(modq)
也就是 Alice 与 Bob 在彼此不泄露各自秘密a和b的情况下得到 α 和 β 使得上式成立
回顾 拉格朗日 插值法
给定k个点, 拉格朗日插值法可以拟合一个多项式把这k个点穿起来。 更进一步, 给定k+1个点, 拉格朗日插值法可以唯一确定一个 k 次多项式穿过这k个点。
我们知道两点(不重合)唯一确定一条直线, 3点(不重合)确定一条抛物线,以此类推,k+1个点唯一确定一个 k次多项式。 拉格朗日插值法就是可以唯一确定这 k-1 个多项式。
拉格朗日插值数学表达式
给定二维坐标上 k+1 个点:
(x0,yo),(x1,y1),...,(xk,yk)
可以唯一确定的 k 次项表达式为:
L(x)=j=0∑kyjlj(x)
lj(x)=i=0,i=j∏kxj−xix−xi
举个例子
令 k =1 , 给定2个点可以唯一确定一次多项式
(x0,yo)=(1,3)(x0,yo)=(2,3)
此时 有
L(x)=j=0∑kyjlj(x)=j=0∑1yjlj(x)
其中:
当j=0,l1(x)=i=0,i=0∏kxj−xix−xi=x0−x1x−x1=1−2x−2当j=1,l1(x)=i=0,i=1∏kxj−xix−xi=x1−x0x−x0=2−1x−1
我们将上述的 2个式子乘上对应的y相加, 就得到了:
L(x)=y0l0(x)+y1l1(x)=2⋅x0−x1x−x1+3⋅x1−x0x−x0=−2(x−2)+3(x−1)=x+1
推导如何计算 s
s=k(z+rd)=kz+krd,
其中z也就是被签名的哈希, 对于每一个party都是已知的,d 为完整私钥。
假设有两个参与方, k=k0+k1,d=d0+d1,
s=k0z+k1z+rkd, 其中 k0z, k1z 可以有 party0 和 party1 各自计算, r在上一篇已经讲解如何计算了。剩下的任务就是计算 kd.
完整私钥d也就是拉格朗日曲线在 x=0时候的y,也就是
d=L(x)=y0lo(x)+y1l1(x)=2⋅x0−x1x−x1+3⋅x1−x0x−x0
对于所有party来说,彼此的x坐标都是已知的。所以d的计算在于不泄露各自的y。
我们令
d=L(x)=y0lo(x)+y1l1(x)=wo+w1
则
kd=(k0+k1)∗(wo+w1)=k0w0+k1w0+k0w1+k1w1
其中 w0w0可以由party0独自计算,w1w1可以由party1独自计算
最终计算s的问题只剩下 party0不泄露自己的k0, w0, party1不泄露自己的k1, w1 计算出 k1w0+k0w1.
眼尖的同学已经看出来了, 可以使用两次MTA协议进行秘密交换, 将乘法秘密转化成加法秘密从而得到 k1w0 和 k0w1
总结
自此我们已经完整推导出来了ecdsa门限签名从分布式密钥生成和门限签名的完整过程。从接触这个算法, 到大致梳理完全部流程, 足足花了我半年时间, 可以说是非常的不容易。欢迎大家点赞, 收藏, 关注, 评论。
有了这些知识, 相信你自己去慢慢看 币安的 tsslib 签名部分的源码也能大概看懂了。
Reference
-
github.com/bnb-chain/t…
-
medium.com/@asteacherl…
-
eprint.iacr.org/2021/1621.p…
-
eprint.iacr.org/2019/114
-
juejin.cn/post/726388…
-
juejin.cn/post/737440…
-
juejin.cn/post/737527…
-
juejin.cn/post/739224…
-
juejin.cn/post/739537…
-
juejin.cn/post/746079…