滑溜溜的椭圆加密

直接看网上的教程因为没有合理的顺序提示,所以是懵逼的。 建议按照参考列出的顺序去解读

前言

最近一直在开发调试基于eos的dapp,每天都会生成密钥对,这么反反复复,不经让我这种野路子对密钥的生成原理产生了极大的兴趣。 所以,这篇就来大话理解下eos里,或者说区块链世界中常用的密码学算法:椭圆曲线加解密 ECC,全称Elliptic Curve Cryptography ECDH,ECDSA是ECC的一种实现。

曲线

名字都是椭圆曲线加密了,那核心的东西当然就是曲线啦。 所以我们的椭圆曲线加密算法,建立在一个“有限域上的二元三次曲线上的点”。

推荐一个曲线可视化把玩工具 https://cdn.rawgit.com/andreacorbellini/ecc/920b29a/interactive/reals-mul.html

曲线方程长这样

y^2=x^3+ax^2+b mod p x, y, a, b都是小于素数p的非负整数

一个曲线,和曲线上离散的点,离散的点的范围是多少? 是 0~p-1 的素数,现实中p可能会很大很大。

我们选定一个基点G,祖宗点。 由他可以派生出有穷个 经过G运算出来的点P1,P2,P3…Pn

其实,根据G求P,有两种方法,一个是几何解法,就是看图一个一个推。 还有一个就是代数解法,即:

有限域GF(p)上的椭圆曲线y² = x³ + ax + b,若P(Xp, Yp),

Q(Xq, Yq),且P≠-Q,则R(Xr,Yr) = P+Q 由如下规则确定:

  Xr = (λ² - Xp - Xq) mod p

  Yr = (λ(Xp - Xr) - Yp) mod p

  其中λ = (Yq - Yp)/(Xq - Xp) mod p(若P≠Q), λ = (3Xp² + a)/2Yp mod p(若P=Q)

就是说我们在知道了G后是可以推导出P的。

怎么用

其实在签名的过程中,我们会用到两次曲线函数 而两次曲线函数都会用到一个G点。

G*dA = Qa (G点倍乘) dA是私钥,Qa是公钥

签名的结构一般是这样的:

{ 
    message: 'tell me what you want',
    messageHash:
   '0xfac27c24e5b94701d4114956dfbac24be4a4ce809da3182f130434369322fe1e',
    v: '0x1b',
    r:
   '0xb0091fa9eeb6a297c2f003a4a6a2824477d189f4a31b5882b78e44bec15e189f',
    s:
   '0x6783a54a11b525b450c8fe643a661495bb9ef64916faf1c3a1513a57ed93ca3d',
    signature:
   '0xb0091fa9eeb6a297c2f003a4a6a2824477d189f4a31b5882b78e44bec15e189f6783a54a11b525b450c8fe643a661495bb9ef64916faf1c3a1513a57ed93ca3d1b' 
}

上面是用web3js直接sign出来的结果。 message和messagehash不用说,就是源数据和散列化后的,主要是r和s。(R、S)这个对是构成签名的要素。

我们找一个随机数k,来作为点乘倍数,用这个k来计算P P=k*G, Px即代表 (R、S)中的R。 那S怎么来的呢?是有公式的:

S =(hash + dA * R)/k mod p

这个就是第二次使用曲线的地方。

现在我们用曲线签名了一个消息,那我们怎么验证这个消息发送的正确性呢?那就需要我们的公钥了。我们手上有个公钥:Qa 我们用公钥Qa + 签名算出来的S + 原文hash + G + R来算出一个点P2。如果P2的x和原来我们上面的点Px一样的话,就说明这个签名其实是有效的。

P = S ^ -1 * z * G + S ^ -1 * R * Qa

安全性论证

参考

  1. https://zhuanlan.zhihu.com/p/34363494
  2. http://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/
  3. https://www.jianshu.com/p/87bd28cd89e5
  4. http://blog.51cto.com/11821908/2057726
Table of Contents