本文使用最简单的方式介绍以太坊签名涉及的密码学的核心知识点
签名基本原理
签名的本质就是告诉别人这个事情的确是你做的,但是不用告诉别人所有信息(私钥)
以以太坊转账举例,比如我转给B一个ETH,这时候就会有一条消息m,可以理解为m="我转给B一个ETH",这时候我需要用私钥对m进行签名,得到一个signature,别人拿到m和signature,就能知道这条m的确是你签名的,然后执行m所对应的动作,在这里是给B转一个ETH,这里不需要暴露你的私钥,同时别人又能验证这的确是你要做的事情
要实现这个功能,需要用到密码学的一些知识,主要包括ECC、ECDSA、secp256k1、rsv,本文的目的是用最简单清晰的方式理解这些概念,而不需要去研究清楚其背后复杂的数学公式。
关系梳理
先梳理一下这些概念之间的关系,有个大致的框架,这些概念都是密不可分的
- ECC是椭圆曲线密码学,就是说这些特殊的椭圆曲线满足一些数学定律
- ECDSA是椭圆曲线数字签名算法,这个算法是基于ECC的,是对ECC的实际应用
- secp256k1是一条ECDSA用到的的实际的椭圆曲线
- rsv是使用ESDSA(椭圆曲线数字签名算法)得到的签名
ECC(Elliptic Curve Cryptography)
ECC中文名椭圆曲线密码学,其原理是满足这个公式
𝑦2=𝑥3+𝑎𝑥+𝑏的椭圆曲线,这些曲线都是相对于X轴对称的,它上面的点满足一种特定的加法。
比如说这个曲线上有两个点,P、Q,那么连接P、Q再得到X轴的对称点R,这个R就是P和Q的和,即P+Q=R.不需要理解为啥这样,反正这个椭圆曲线上的点就是满足这个定律,是由背后的数学原理保证的。
ECDSA(Elliptic Curve Digital Signature Algorithm)
ECDSA是椭圆曲线数字签名算法,是基于上面ECC的特性,开发出的一种可以用来对消息签名的算法。
基本原理就是基于上面的ECC加法,那么如果是x个P点自己相加呢,比如xP=X,如果我们知道x,是很容易计算出X的,但是告诉你X,你基本不可能反推出x,因为x是一个很大的数,2的256次方级别的一个数字
然后在椭圆曲线数字签名算法中,就是取x作为私钥,然后X作为公钥,x是256位的二进制的一个数字,X是椭圆曲线上的一个点,用512位二进制表示,XY坐标分别用256位二进制表示
这里还会有一个问题,为什么椭圆曲线上的点都能用整数表示呢,这个也不用管,反正我们只需要知道它用了其它的一些限制,能保证所有点都是能用整数表示的,背后的数学原理不用深究。
公钥私钥
所以我们要生成一个地址,就是用一个随机方法取一个256位长的数字,即上面的x,然后用xP算出X,即为我们的公钥,再对公钥做一下处理,比如取hash,就得到了我们所知道的地址
以太签名的原理就是你要向别人证明你知道x,但是不需要告诉别人x,基于ECC开发出了这样的一套公式可以实现这个功能,即ECDSA
这边直接贴一个图,这个图里的公式不需要全部看懂,感兴趣的可以自己深究一下,看这篇文章
这里我们只需要知道基于ECC我们知道
n•P + r•P = (n + r)•P
然后对这个公式变换一下可以得到
hash(m, R)•X + R = s•P
其中n·P = X,我们可以把X当成公钥,n当成私钥,即x。
我们只要知道n,就能提供一组m、R、s让hash(m, R)•X + R = s•P这个公式成立,如果不知道n,则无法提供这样一组数据让这个公式成立。
所以这个公式可以用来证明你知道X所对应的x,即私钥。
所以我们取m为要签名的消息,然后R和s就是签名。
secp256k1
这个我们只需要知道这是一条特定的椭圆曲线就行y2=x3+7,ECDSA就是用的这条曲线来进行那些数学计算的
rsv
在以太里的签名就是用rsv表示的,r(32字节、256位),s(32字节、256位),v(1字节,8位),总共65字节。
这里的rsv就是对应于上面公式里的Rs,因为R是一个点,有XY坐标,但是XY分别是256位,完整表示出来太浪费空间了,所以在实际的签名里,只取X轴的坐标,但是同一个X坐标,对应的点有两个点,因为椭圆曲线是相对于X对称的,所以用v来参数来表示取的是哪个点,即这里rv用来表示上面公式里的R
总结
以太坊里的各种交易,底层都是用了上面的ECDSA算法,比如转账交易,这里举个最简单的例子,传给链上的就是类似这样的一个数据结构
{
to: 0x123,
value: 1,
signature: rsv(65字节)
}
其它手续费之类的字段省略了,不影响理解,这个提交说明我要转给0x123这个地址1ETH,然后链上验证signature,验证成功就执行这个操作
在这里to和value都是要签名的消息的原文,我们实际要签名的消息其实是一个hash值,即256位的一个数字,因为签名算法的背后是数学公式,只认数字,这里一般是约定好,你传给我的这些字段用什么方式序列化,然后取hash值,得到要签名的m,签名的地方和验签的地方,用同样的方式序列化就能得到相同的m。
得到m和rsv之后,能反解出X,通过rv能得到R,然后代到公式里看是否满足
hash(m, R)•X + R = s•P,满足则验签通过,执行对应的操作,这里的from地址是X对应的地址,可以根据X计算处理。
这里的P是一个固定的点,是ECDSA提前选好的