ECDSA算法#
前言#
我今天简单查了查ECDSA的流程,发现一大堆人瞎写,私钥写成公钥,随机数k写成d,真是令人尴尬。所以写个这个,额,差不多可以说是维基百科的翻译版。
ECDSA算法的讲解#
场景假设还是经典的Alice,Bob场景,他们一开始只协商好了椭圆曲线ID,基点G,和基点G的阶n(multiplicative order)。
基本参数定义#
场景假设还是经典的ALICE,BOB场景,他们一开始只协商好了椭圆曲线ID,基点G,和基点G的阶n(multiplicative order)。在TLS1.3中,选定了椭圆曲线就标识对应的基点和基点的阶了。我们下面定义具体的参数。
参数名(英文) | 含义 |
---|---|
Curve | 选定的曲线和有限域,一般写作y^2 = x^3 + ax + b,这里面a & b都是系数 |
G | 基点,使用基点在曲线上生成子群 |
n | 基点的阶,n * G = O,O为基础元 |
d(A) | Alice的私钥,对应于一个大素数 |
Q(A) | Alice的公钥,对应于d(A)的公钥,即d(A)*G(椭圆曲线的加乘) |
m | 要签名的消息,对于ECDSA这里应该是握手消息的hash输出 |
k` | k在n的整数域上的逆 |
基点G的阶必须是素数,我们这里假设计算是基于整数域也就是Z/nZ的。此外,上面的d(A)是随机生成的私钥,注意d(A)并不是临时密钥(Ephemeral Key)。
ECDSA计算流程#
现在假设Alice要开始对消息做签名了,除了第四步是加乘,其他都是正常的整数域乘法。流程如下:
- 先对消息做$$hash$$,在TLS1.3中称之为transcrpthash(m)。具体体现为$$e = HASH(m)$$,将输出转换为整数
- 假设$$L(n)$$是基点$$G$$的阶$$n$$的bit长度,取z为上一步计算结果e的最左端$$L(n)$$位,实际上就是个截断操作,毕竟这个要参与运算的
- 从$$[1,n-1]$$中随机的选取一个随机数$$k$$,该随机数应当满足密码学安全性
- 计算新的点$$(x(1),y(1))=k*G$$,这里的*依然是椭圆曲线上的加乘
- 取上一步结果的横坐标$$x(1)$$,计算$$r = x(1) mod n$$,如果$$r==0$$,回退到第三步。
- 计算$s=k`*(z+rd(A)) modn$,如果s==0,再次回退到第三步,这里的k`就是k的逆
ECDSA的验签#
验签的流程并不难,对Bob而言,验签过程首先要验证的就是公钥是合法的。这点不多说了。具体流程如下:
- 验证r和s在[1,n-1]之间,如果不在,则签名无效
- 计算 $$e=hash(m)$$,保存e的最左端$$L(n)$$位为$$z$$
- 计算$$u(1)=zs`mod n$$与$$u(2)=rs`mod n$$,s`指代s在n整数域上的逆
- 计算点$$(x(1),y(1))=u(1)*G+u(2)*Q(A)$$,这里的两个乘都是椭圆曲线的加乘
- 验证$$r==x(1)mod n$$,成立则说明签名有效,反之无效。
ECDSA验签的证明#
证明就不多说了,本身将计算流程带入然后结合律搞一下就完了。ECDSA本身需要依靠椭圆曲线逆推难的结论,这点也没啥好说的。
结语#
国内好多文章不知道为啥要自己改来改去,如何定义一个标准的正确的竟然成为了难题。奇葩
结尾的闲言碎语#
写到这里差不多就可以结束了,就不多说了。TLS这块还有啥不明白的直接告诉我就成了