加密货币安全基石: MTA协议在Ecdsa门限签名的应用(计算签名中的s)

154 阅读4分钟

声明: 本文纯做技术分享, 不代表任何加密货币投资购买建议

背景: 在之前的加密货币安全基石: MTA协议在Ecdsa门限签名的应用(计算签名中的r) 中,我向大家展示了MTA协议如何拆分Ecdsa门限签名中的r.在这篇文章中,我将在上篇文章基础更进一步, 讲解MTA协议如何计算Ecdsa门限签名中的s. 看完本文章, 你将彻底理解Ecdsa门限签名的秘密。

需要你有一些密码学, 加密货币, 区块链的前置知识:

  1. 使用 golang 实现一个极简的 区块链
  2. 加密货币安全基石:直观理解ECC椭圆曲线加密算法
  3. 加密货币安全基石:从ECC到ECDSA椭圆曲线签名
  4. 加密货币安全基石: 从拉格朗日插值到shamir共享密钥算法
  5. 加密货币安全基石: 从Shamir到Feldman VSS算法, 以币安tss-lib库为例
  6. 加密货币安全基石: 详解 Paillier 同态加密并使用币安tss-lib库
  7. 加密货币安全基石: 分布式密钥生成协议(GG18, 币安tss-lib keygen部分)
  8. 加密货币安全基石: MTA协议在Ecdsa门限签名的应用(计算签名中的r)

回顾 ECDSA 签名

ECDSA 的详细原理中我之前的 加密货币安全基石:从ECC到ECDSA椭圆曲线签名 中有详细介绍, 这里我们简单回顾一下即可。

定义 G为椭圆曲线 起点, g 为循环群, 私钥 为 d, 公钥Q=dG, n 为 一个大质数, 被签名的原文为 M , 其中 G,Q,M,n 公开, d 为签名方严格保密 签名过程如下:

  1. 对原文进行取哈希操作, 令 z=hash(M)z = hash(M)
  2. [1,n1][1,n-1] 范围内选一个随机数 k, 计算终点 R=(k1)G=g(k1)R = (k-1)G = g^{(k^{-1})}, R 的 横坐标记为 r
  3. 计算 s=k1(z+rd)modns = k^{-1} (z+rd) mod n , 其中 k1k^{-1}kmodn k mod n 的逆元
  4. 最终签名由两部分组成 sign=r,ssign = (r, s)

明白了如何拆分r和s 也就明白了如何进行ecdsa门店签名, 在上一篇文章中我们着重讲解了如何拆分r, 这篇文章着重讲解如何拆分s。

为了简略,我们将s=k1(z+rd)modns = k^{-1} (z+rd) mod n 简化成 s=k(z+rd)s = k (z+rd) , 其中 k为随机数, d为完整私钥。

回顾 MTA 协议

MTA 协议 是一种秘密交换协议. 需要两个参与方, 命名为 Alice 和 Bob。 其中Alice 拥有 Paillier 公私钥对, 拥有 秘密值 a. Bob 拥有 秘密值 b 和随机数 β\beta ' .

MTA协议可以做到在 Alice 不泄露 a 的情况下, 在 Bob 不泄露 b 的情况下, 让 Alice得到一个数 α\alpha , 让 Bob 得到一个数字β\beta 使得下列等式成立:

α+β=ξ=ab(modq) \alpha + \beta = \xi = ab (mod q)

也就是 Alice 与 Bob 在彼此不泄露各自秘密a和b的情况下得到 α\alphaβ\beta 使得上式成立

回顾 拉格朗日 插值法

给定k个点, 拉格朗日插值法可以拟合一个多项式把这k个点穿起来。 更进一步, 给定k+1个点, 拉格朗日插值法可以唯一确定一个 k 次多项式穿过这k个点。

我们知道两点(不重合)唯一确定一条直线, 3点(不重合)确定一条抛物线,以此类推,k+1个点唯一确定一个 k次多项式。 拉格朗日插值法就是可以唯一确定这 k-1 个多项式。

拉格朗日插值数学表达式

给定二维坐标上 k+1 个点:

(x0,yo),(x1,y1),...,(xk,yk)(x_0,y_o), (x_1,y_1),...,(x_k, y_k)

可以唯一确定的 k 次项表达式为:

L(x)=j=0kyjlj(x) L(x)= \sum_{j=0}^{k} y_j l_j(x) \newline
lj(x)=i=0,ijkxxixjxi l_j(x)= \prod_{i=0, i\ne j}^{k} \frac{x-x_i}{x_j-xi}

举个例子

令 k =1 , 给定2个点可以唯一确定一次多项式

(x0,yo)=(1,3)(x0,yo)=(2,3)(x_0,y_o) = (1,3) \newline (x_0,y_o) = (2, 3) \newline

此时 有

L(x)=j=0kyjlj(x)=j=01yjlj(x) L(x)= \sum_{j=0}^{k} y_j l_j(x) = \sum_{j=0}^{1} y_j l_j(x)

其中:

j=0,l1(x)=i=0,i0kxxixjxi=xx1x0x1=x212j=1,l1(x)=i=0,i1kxxixjxi=xx0x1x0=x121 当 j = 0, l_1(x) = \prod_{i=0, i\ne 0}^{k} \frac{x-x_i}{x_j-xi} = \frac{x-x_1}{x_0-x1} = \frac{x-2}{1-2} \newline 当 j = 1, l_1(x) = \prod_{i=0, i\ne 1}^{k} \frac{x-x_i}{x_j-xi} = \frac{x-x_0}{x_1-x0} = \frac{x-1}{2-1} \newline

我们将上述的 2个式子乘上对应的y相加, 就得到了:

L(x)=y0l0(x)+y1l1(x)=2xx1x0x1+3xx0x1x0=2(x2)+3(x1)=x+1 L(x) = y_0 l_0(x) + y_1 l_1(x) \newline = 2 \cdot \frac{x-x_1}{x_0-x1} + 3 \cdot \frac{x-x_0}{x_1-x_0} \newline = -2(x-2)+ 3(x-1) = x + 1

推导如何计算 s

s=k(z+rd)=kz+krds = k (z+rd) = kz + krd ,

其中z也就是被签名的哈希, 对于每一个party都是已知的,d 为完整私钥。

假设有两个参与方, k=k0+k1,d=d0+d1 k = k0+ k1, d = d0+ d1,

s=k0z+k1z+rkds = k0z +k1z + rkd, 其中 k0z, k1z 可以有 party0 和 party1 各自计算, r在上一篇已经讲解如何计算了。剩下的任务就是计算 kdkd.

完整私钥dd也就是拉格朗日曲线在 x=0时候的y,也就是

d=L(x)=y0lo(x)+y1l1(x)=2xx1x0x1+3xx0x1x0d= L(x)=y_0l_o(x)+y_1l_1(x) \newline = 2 \cdot \frac{x-x_1}{x_0-x1} + 3 \cdot \frac{x-x_0}{x_1-x_0}

对于所有party来说,彼此的x坐标都是已知的。所以d的计算在于不泄露各自的y。

我们令

d=L(x)=y0lo(x)+y1l1(x)=wo+w1d= L(x)=y_0l_o(x)+y_1l_1(x) = w_o+w_1

kd=(k0+k1)(wo+w1)=k0w0+k1w0+k0w1+k1w1kd = (k_0+k_1)*(w_o+w_1) \newline = k_0 w_0+k_1 w_0+k_0 w1+k1 w1

其中 w0w0w_0 w_0可以由party0独自计算,w1w1w_1 w_1可以由party1独自计算

最终计算s的问题只剩下 party0不泄露自己的k0k0, w0w_0, party1不泄露自己的k1k1, w1w_1 计算出 k1w0+k0w1k_1 w_0+k_0 w1.

眼尖的同学已经看出来了, 可以使用两次MTA协议进行秘密交换, 将乘法秘密转化成加法秘密从而得到 k1w0k_1 w_0k0w1k_0 w1

总结

自此我们已经完整推导出来了ecdsa门限签名从分布式密钥生成和门限签名的完整过程。从接触这个算法, 到大致梳理完全部流程, 足足花了我半年时间, 可以说是非常的不容易。欢迎大家点赞, 收藏, 关注, 评论。

有了这些知识, 相信你自己去慢慢看 币安的 tsslib 签名部分的源码也能大概看懂了。

Reference

  1. github.com/bnb-chain/t…

  2. medium.com/@asteacherl…

  3. eprint.iacr.org/2021/1621.p…

  4. eprint.iacr.org/2019/114

  5. juejin.cn/post/726388…

  6. juejin.cn/post/737440…

  7. juejin.cn/post/737527…

  8. juejin.cn/post/739224…

  9. juejin.cn/post/739537…

  10. juejin.cn/post/746079…