1. 程式人生 > >Fabric 1.0原始碼分析(46)ECDSA(橢圓曲線數字簽名演算法)

Fabric 1.0原始碼分析(46)ECDSA(橢圓曲線數字簽名演算法)

# Fabric 1.0原始碼筆記 之 ECDSA(橢圓曲線數字簽名演算法)
## 1、橢圓曲線演算法概述
### 1.1、無窮遠點、無窮遠直線、射影平面
* 平行線相交於無窮遠點;* 直線上有且只有一個無窮遠點;* 一組相互平行的直線有公共的無窮遠點;* 平面上任何相交的兩直線,有不同的無窮遠點;* 全部無窮遠點溝通一條無窮遠直線;* 平面上全部無窮遠點和全部普通點構成射影平面。
### 1.2、射影平面點定義
對於普通平面上點(x, y),令x=X/Z,y=Y/Z,Z≠0,則投影為射影平面上的點為(X : Y : Z)。如點(1,2)在射影平面的座標為:(Z : 2Z : Z) Z≠0,即(1 : 2 : 1)或(2 : 4 : 2)均為(1, 2)在射影平面上的點。Z=0時,(X : Y : 0)即為無窮遠點,Z=0即為無窮遠直線。
### 1.3、橢圓曲線方程

橢圓曲線的定義:一條橢圓曲線是在射影平面上滿足方程Y²Z+a1XYZ+a3YZ²=X³+a2X²Z+a4XZ²+a6Z³的所有點的集合,且曲線上的每個點都是非奇異(或光滑)的。該方程為維爾斯特拉斯方程,是一個齊次方程。所謂“非奇異”或“光滑”的,即滿足方程的任意一點都存在切線。
橢圓曲線存在無窮遠點(0, Y, 0),可以在平面座標系中用橢圓曲線、加一個無窮遠點來表示。令x=X/Z,y=Y/Z,代入橢圓曲線方程,即橢圓曲線普通方程:y²+a1xy+a3y = x³+a2x²+a4x+a6。
### 1.4、橢圓曲線上的加法
任意取橢圓曲線上兩點P、Q (若P、Q兩點重合,則做P點的切線)做直線交於橢圓曲線的另一點R’,過R’做y軸的平行線交於R。我們規定P+Q=R。
根據這個法則,可以知道橢圓曲線無窮遠點O∞與橢圓曲線上一點P的連線交於P’,過P’作y軸的平行線交於P,所以有 無窮遠點 O∞+ P = P 。這樣,無窮遠點 O∞的作用與普通加法中零的作用相當(0+2=2),我們把無窮遠點 O∞ 稱為 零元。同時我們把P’稱為P的負元(簡稱,負P;記作,-P)。
根據這個法則,可以得到如下結論 :如果橢圓曲線上的三個點A、B、C,處於同一條直線上,那麼他們的和等於零元,即A+B+C= O∞ 。k個相同的點P相加,我們記作kP。如:P+P+P = 2P+P = 3P。
### 1.5、有限域橢圓曲線

橢圓曲線是連續的,並不適合用於加密;所以,我們必須把橢圓曲線變成離散的點,我們要把橢圓曲線定義在有限域上。* 我們給出一個有限域Fp* Fp中有p(p為質數)個元素0,1,2,…, p-2,p-1* Fp的加法是a+b≡c(mod p)* Fp的乘法是a×b≡c(mod p)* Fp的除法是a÷b≡c(mod p),即 a×b^(-1)≡c (mod p),b^(-1)也是一個0到p-1之間的整數,但滿足b×b^(-1)≡1 (mod p)* Fp的單位元是1,零元是0
同時,並不是所有的橢圓曲線都適合加密。y²=x³+ax+b是一類可以用來加密的橢圓曲線,也是最為簡單的一類。下面我們就把y²=x³+ax+b這條曲線定義在Fp上:
選擇兩個滿足下列條件的小於p(p為素數)的非負整數a、b,4a³+27b²≠0 (mod p) 。則滿足下列方程的所有點(x,y),再加上 無窮遠點O∞ ,構成一條橢圓曲線。 y²=x³+ax+b (mod p) 其中 x,y屬於0到p-1間的整數,並將這條橢圓曲線記為Ep(a,b)。
Fp上的橢圓曲線同樣有加法,但已經不能給以幾何意義的解釋。
```無窮遠點 O∞是零元,有O∞+ O∞= O∞,O∞+P=P P(x,y)的負元是 (x,-y),有P+(-P)= O∞ P(x1,y1),Q(x2,y2)的和R(x3,y3) 有如下關係:   x3≡k2-x1-x2(mod p)   y3≡k(x1-x3)-y1(mod p)   其中若P=Q 則 k=(3x1²+a)/2y1 若P≠Q,則k=(y2-y1)/(x2-x1)```
例 已知E23(1,1)上兩點P(3,10),Q(9,7),求1)-P,2)P+Q,3) 2P。
```1) –P的值為(3,-10) 2) k=(7-10)/(9-3)=-1/2,2的乘法逆元為12 因為2*12≡1 (mod 23)     k≡-1*12 (mod 23) 故 k=11。     x=112-3-9=109≡17 (mod 23);     y=11[3-(-6)]-10=89≡20 (mod 23)     故P+Q的座標為(17,20) 3) k=[3(3²)+1]/(2*10)=1/4≡6 (mod 23)     x=62-3-3=30≡20 (mod 23)     y=6(3-7)-10=-34≡12 (mod 23)     故2P的座標為(7,12) ```
如果橢圓曲線上一點P,存在最小的正整數n,使得數乘nP=O∞,則將n稱為P的階,若n不存在,我們說P是無限階的。 事實上,在有限域上定義的橢圓曲線上所有的點的階n都是存在的。
### 1.6、橢圓曲線上簡單的加密/解密

考慮如下等式:K=kG [其中 K,G為Ep(a,b)上的點,k為小於n(n是點G的階)的整數]。不難發現,給定k和G,根據加法法則,計算K很容易;但給定K和G,求k就相對困難了。這就是橢圓曲線加密演算法採用的難題。我們把點G稱為基點(base point),k(k<nn為基點G的階)稱為私有金鑰(privte key),K稱為公開金鑰(public key)。
補充:如上內容參考自* [【資訊保安】ECC加密演算法入門介紹](https://yq.aliyun.com/articles/23897)* [ECC橢圓曲線詳解(有具體例項)](https://yq.aliyun.com/articles/23897)
## 2、橢圓曲線介面及實現
### 2.1、橢圓曲線介面定義
```gotype Curve interface {    Params() *CurveParams //返回曲線引數    IsOnCurve(x, y *big.Int) bool //(x,y)是否在曲線上    Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int) //(x1,y1)和(x2,y2)求和    Double(x1, y1 *big.Int) (x, y *big.Int) //2*(x,y)    ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int) //返回k*(Bx,By)    ScalarBaseMult(k []byte) (x, y *big.Int) //返回k*G,其中G為基點}//程式碼在crypto/elliptic/elliptic.go```
### 2.2、CurveParams結構體定義及通用實現
CurveParams包括橢圓曲線的引數,並提供了一個通用橢圓曲線實現。程式碼如下:
```gotype CurveParams struct {    P *big.Int //% p中的p    N *big.Int //基點的階,如果橢圓曲線上一點P,存在最小的正整數n,使得數乘nP=O∞,則將n稱為P的階    B *big.Int //曲線方程中常數b,如y² = x³ - 3x + b    Gx, Gy *big.Int //基點G(x,y)    BitSize int //基礎欄位的大小    Name string //橢圓曲線的名稱}//程式碼在crypto/elliptic/elliptic.go```
CurveParams涉及如下方法:
```gofunc (curve *CurveParams) Params() *CurveParams //返回曲線引數,即curvefunc (curve *CurveParams) IsOnCurve(x, y *big.Int) bool //(x,y)是否在曲線上func (curve *CurveParams) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) //(x1,y1)和(x2,y2)求和func (curve *CurveParams) Double(x1, y1 *big.Int) (*big.Int, *big.Int) //2*(x,y)func (curve *CurveParams) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) //返回k*(Bx,By)func (curve *CurveParams) ScalarBaseMult(k []byte) (*big.Int, *big.Int) //返回k*G,其中G為基點//程式碼在crypto/elliptic/elliptic.go```
### 2.3、幾種曲線
```gofunc P224() Curve //實現了P-224的曲線func P256() Curve //實現了P-256的曲線func P384() Curve //實現了P-384的曲線func P521() Curve //實現了P-512的曲線//程式碼在crypto/elliptic/elliptic.go```
## 3、橢圓曲線數字簽名演算法
結構體定義:```gotype PublicKey struct { //公鑰    elliptic.Curve    X, Y *big.Int}type PrivateKey struct { //私鑰    PublicKey    D *big.Int}type ecdsaSignature struct { //橢圓曲線簽名    R, S *big.Int}//程式碼在crypto/ecdsa/ecdsa.go```
涉及如下方法:
```gofunc (priv *PrivateKey) Public() crypto.PublicKey //獲取公鑰func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) //使用私鑰對任意長度的hash值進行簽名func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) //生成一對公鑰/私鑰func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) //使用私鑰對任意長度的hash值進行簽名func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool //使用公鑰驗證hash值和兩個大整數r、s構成的簽名//程式碼在crypto/ecdsa/ecdsa.go```
## 4、本文使用到的網路內容
* [初學者如何理解射影平面](https://wenku.baidu.com/view/3d245b608e9951e79b892768.html)* [ECC橢圓曲線詳解(有具體例項)](http://www.cnblogs.com/Kalafinaian/p/7392505.html)* [說說橢圓曲線](http://blog.sina.com.cn/s/blog_564e1db00102vq25.html)* [橢圓曲線密碼學簡介](http://www.8btc.com/introduction)* [【資訊保安】ECC加密演算法入門介紹](https://yq.aliyun.com/articles/23897)* [橢圓曲線演算法:入門(1)](http://www.jianshu.com/p/2e6031ac3d50)





網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN