程序员易懂的 ECDSA 原理简述
系列索引: 上链与背后的流程 | 联盟链开发(一) 动手编 SDK | 联盟链开发(二) SDK 1.0 版本的打造 | 联盟链开发(三) 将 SDK 发布到 PIP | 联盟链开发(四) 什么样的数据应该上链?| 联盟链开发 (五) BSN 相关问与答 | 联盟链开发(六) 链上简历应用 — 设计 | 联盟链开发(七) FISCO BCOS 介绍 | 联盟链开发(八) WeIdentity 极速体验 | 联盟链开发(九) 给Remix升个级 | 联盟链开发(十) 伪代码简述 ECDSA 签名过程 | 联盟链开发(十一) WeIdentity 的多签及限量凭证的实现 | 联盟链开发(十二)
在《比特币极速入门指南》一书里,我阐述了公私钥究竟是什么:
- 私钥的本质: 私钥的本质是一个数字,这个数字用 16 进制表示的话,长度是 64;转换为字节,是 32 字节。
- 公钥的本质: 用私钥生成Secp256k1曲线上的一个点,将 x 与 y 拼接起来,再在开头加上 <<04>> 后得到一个数字,这个数字就是公钥。用 16进制表示的话,长度是 130;转换为字节,是 65 字节。
地址:
阅读版—— http://dwz.date/a8dY
由于是「入门指南」,所以没有对 ECDSA 具体的签名过程进行详细阐述,只做黑箱处理。但是,对于进阶读者而言,了解 ECDSA 签名的实现逻辑还是有其必要的。
在一般介绍 ECDSA 原理的文章中,普遍使用数学语言。虽然非常严谨,但读起来还是比较费劲。所以,今天我在这里,通过伪代码的形式,介绍 ECDSA 的原理,以便大家更好的理解。
首先我们定义这件事儿里有几个角色:
私钥小姐与公钥先生
我们称其为 priv 与 pub。
要加密的信息 m
在区块链里一般 m = 交易,不过理论上只要是个东西就能加密。
G 点
G.x 0x79……98
G.y 0x48……B8
G.order 0xFF……41
具体的数值我们可以从网上搜到,但在这里我们不用管它,只要知道 G 点有三个参数:x, y, order 就行了!
接着我们定义两个操作:
Point.mult(num, Point)
点的乘法,参数是一个数字与一个 (x, y) 点,结果是一个点。我们可以把这个操作看做黑箱,而不用去深究这个操作究竟做了些啥。
calculate_rem(num1, num2)
取余操作
hash_and_sth(m)
我们对信息 m 做一些处理,具体咋处理的不用管,结果就是我们能拿 m 验证出来出来的内容是否正确,但不能拿处理出来的内容反推 m —— 传说中的 hash 函数。
我们现在来用伪代码愉快地生成数字签名吧!
我们首先用 gen_k() 函数生成一个取值范围为[1, order-1] 的随机数,称之为 k。
Point.mult(k, G) = Q_point = (x, y)。
calculate_rem(x, order)
calculate_rem(x, order) = r,如果 r 为 0,则回到第一步,重新生成 k。
calculate_s(k, hash_and_sth(m), priv)
calculate_s(k, hash_and_sth(m), priv) = s,如果 s 为 0,再次重新生成 k。
v = 27 + calculate_rem(y, 2)
有了 v,我们验签就更快了,不然要遍历好几个点去找哪一个点是对的。具体怎么做的可以暂且不理,有兴趣的话看:
r & s & v = signature
把三个东西连起来,得到数字签名!
和比特币存在差异,比特币在 ECDSA 签名后采用了 DER 编码模式,所以比特币的签名长度是不定的,在71 - 73 个字节之前。但是以太坊则使用的标准 ECDSA 流程,所以签名固定为 r(35字节)+ s(35字节)+v (1字节)=71字节。
此处 1 字节为 8 个二进制位,即 2 个十六进制位,即 0x00 - 0xFF,用十进制表示则是 0 - 255。
此外,由于签名中存在随机数 k,所以对同一信息用同一私钥,每次签出来的签名也是不一样的!
把上述过程用伪代码表示,则是:
@spec gen_sig(byte32, string) return byte71
def gen_sig(priv, m) do
q_point=
gen_k()
|> Point.mult(G)
r = calculate_rem(q_point, G.order)
s = calculate_s(k, hash_and_sth(m), priv)
v = 27 + calculate_rem(q_point.y, 2)
return r & s & v
end
数字签名验签过程……嗯,明日再谈吧(懒~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!