早前寫過一篇文章分析 RSA 算法原理後,想了解下更復雜點的橢圓曲線密碼學原理,於是有了密碼學的第二篇筆記。基於橢圓曲線的密碼體系已經在密鑰交換(如ECDHE)和數字簽名(ECDSA)中得到廣泛應用,如比特幣就在其數字簽名算法中用到了橢圓曲線,在配置nginx的CipherSuite時亦會經常看到 ECDHE 的身影。相較於 RSA,橢圓曲線密碼體系可以使用更短的 key 達到更高的安全性。本文主要參考資料 [Elliptic Curve Cryptography: a gentle introduction],如有錯漏,懇請指正。
1 橢圓曲線概述
首先要說明的一點是,橢圓曲線不是橢圓。橢圓方程是下面這樣的:
而通常我們討論的橢圓曲線的曲線方程是一個二元三次方程,它有多種形式,在橢圓曲線密碼體系中,最常用的是如下的Weierstrass通用式(curve25519 等其他類型的橢圓曲線本文不討論):
之所以取名叫橢圓曲線,是因爲該曲線方程跟求橢圓弧長的積分公式相似。從曲線方程和圖像易知,橢圓曲線關於X軸對稱。判定式不等於零是爲了橢圓曲線不存在奇異點,即處處光滑可導,這樣才能進行橢圓曲線上的加法運算。下面是一些適合用於加密的橢圓曲線,其中 。
2 數學基礎
橢圓曲線加密算法涉及數學中的羣論、有限域等內容,這節簡要介紹下相關數學理論。亦可以跳過直接看第3節,遇到相關名詞再查閱即可。
2.1 羣 (Group)
在討論羣之前,先說說集合。集合簡單來說就是把一堆東西放在一起,如自然數集合。當然光有一堆東西還不夠,東西之間相互作用才能更好的描述大千世界。於是,自然數集合通過加減運算衍生出整數集合、整數集合經過乘除又可以衍生出有理數,而後通過無理數的加入又衍生出實數集合、負數開方引入了複數集合。羣則是集合和一個二元運算。
羣: 是一個集合 連同一個二元運算 表示爲 。要成爲一個羣,該集合和運算需要滿足如下4個要求:
- 封閉性:對於 中任意的 和 ,運算 的結果也在集合 中。
- 結合律:對於 中任意的 ,等式 成立。
- 單位元: 中存在一個元素 ,對於 中任意元素 ,等式 成立。
- 逆元:對於 中任意元素 , 中都存在另一個元素 ,使得 ,其中 e 是單位元。
而如果再滿足交換律,則該羣就被稱爲是一個阿貝爾羣。
- 交換律:對於 中的任意元素 ,等式 成立。
根據羣的定義,整數的加法運算 就是一個羣,而且還是一個阿貝爾羣。而自然數的加法運算 就不是一個羣。整數加法運算構成羣,因爲它滿足羣的定義:整數加法的封閉性、結合律、交換律都成立。整數加法運算中單位元是 0。所有整數 n 都有加法逆元 -n。
在密碼學中一般都需要一個有限的羣,定義如下:
有限羣: 如果一個羣裏的元素有限的,則稱該羣爲有限羣,羣中元素數目稱爲羣的階。羣 的階用記號 表示。
2.2 域 (Field)
爲了使一個結構同時支持四種基本算術(即加減乘除),我們需要一個包含加法和乘法羣的集合,這就是域。當一個集合爲域的時候,我們就能在其中進行基本算術運算了。
域 是具有下面特性的元素集合:
- F 中所有元素形成一個加法羣,對應羣的運算是 ,單位元爲 0,對於元素 ,加法逆元表示爲 。
- F 中除0外的所有元素構成一個乘法羣,對應羣的運算是 ,單位元是 1。對於元素 a,乘法逆元表示爲 。
- 對 F 中的元素混合使用這兩種羣操作時,分配律始終成立。即對所有的 ,都有
所以域中元素只要形成加法羣和乘法羣並滿足分配律就行,因爲羣中元素都有逆元,減法/除法可以轉換爲加/乘元素的逆元實現。實數集合 是一個域,加法羣中單位元是 0,每個實數 都有加法逆元 ,乘法羣中單位元是 ,每個非零實數都有乘法逆元 。而整數集合就不是域,因爲大部分元素沒有乘法逆元,不能構成一個乘法羣。
在密碼學中,通常只對有限元素的域感興趣,這種域稱爲有限域(Finite Field)。有限域中我們經常用到的是素數域,所謂素數域,就是階爲素數的有限域。比如當 p 爲素數時,整數環 就是一個素數域,可以記作 。在素數域 中進行算術運算,需要遵守整數環的規則,即加法是模 p 加法,而乘法是模 p 乘法。
整數環 由下面兩部分構成:
- 集合 ,共 個元素。
- 集合中兩種操作 (模加法)和 (模乘法),即對於所有的 ,滿足:
例如對於 有:
- 加法:
- 加法逆元: ,因爲
- 乘法:
- 乘法逆元:,因爲 。
3 橢圓曲線中的羣論
橢圓曲線上的點經過一種特定的加法運算可以讓橢圓曲線在實數域構成一個羣。
3.1 點加法
無窮遠點:定義一個無窮遠點 ,即經過橢圓上任意一點的與X軸垂直的直線都經過該點。可能有人疑惑垂直於X軸的直線是平行線,爲啥可以定義爲都經過 點?因爲在非歐幾何中,可認爲平行線在無窮遠處會交於一點。
橢圓曲線點加法:橢圓曲線上經過 和 兩個點的直線與橢圓曲線的交點記作 ,根據定義有 以及 。繼而定義橢圓曲線點加法:,即加法結果是經過點 且與 X 軸垂直的直線與橢圓曲線的另外一個交點,簡單來說,就是交點 關於 X 軸的對稱點。
橢圓曲線羣:定義爲橢圓曲線在實數域上的點集以及點加法
封閉性:元素是橢圓曲線上的點,且根據加法定義,加法運算得到的點都在橢圓曲線上,滿足封閉性。
單位元:選取無窮遠點作爲單位元,記爲 ,易證得 。(因爲 )。
逆元:因爲橢圓曲線過於X軸對稱, 的關於 X 軸對稱的點 就是 的逆元。因爲 。
交換律: 。
結合律: ,通過幾何作圖可以驗證得到的兩個點確實相同,更嚴格的證明需要用到 [Cayley–Bacharach theorem],即假設兩條三次曲線有9個交點,如果第三條三次曲線經過前兩條三次曲線的8個交點,那麼它也必定通過第9個交點。
由此可知,橢圓曲線上的點在橢圓曲線加法運算上構成了一個阿貝爾羣。增加了單位元后,橢圓曲線方程改爲:
由定義可知,,所以,最終加法只需要計算交點 的逆元 即可。幾種特殊情況說明:
- 1)如果 不是切點且不是互爲逆元,則有第三個交點 ,故 。
- 2)如果 或者 是切點,則 就是橢圓曲線的一條切線。假如 是切點,則有 。
- 3)如果 和 連線垂直於X軸,即 ,則跟曲線沒有第三個交點,可以認爲是交於無窮遠點 ,故而 。
- 4)如果 ,則過它們的直線就是橢圓曲線過點 的切線,該直線一般來說跟橢圓曲線有另一個交點 。如果恰好該切線如圖4這樣跟曲線沒有其他交點,則可以認爲交點爲 ,即此時 。
3.2 代數加法
上一節定義了橢圓曲線幾何上意義的點加法,需要轉換爲代數加法以方便計算。要注意的是,這並不是兩個點的座標簡單相加。
假設直線 PQ 的斜率 ,然後將直線方程 代入曲線可以得到:, 轉換成標準式,根據韋達定理 ,即而可求得 ,想了解具體推導過程的可參見 [cubic-equations]。
斜率 計算需要區分兩種情況,當 P=Q 時求橢圓曲線在 P 點的切線斜率(求導)即可:
可以簡單驗證,比如橢圓曲線是 ,通過參考資料1的 [可視化工具] 可得 。容易驗證,與代數加法公式計算結果一致。
對於特殊情況中有一個是切點的情況,如 ,計算方式不變,易得 。而對於特殊情況 ,採用切線斜率亦可驗證公式正確。
3.3 標量乘法
在實際加密算法中,我們通常需要多次通過橢圓曲線加法來實現一次加密,如下圖所示:
圖中打點的過程就是:
而在實際加密算法中,我們常常是使用一個點自己疊加,即初始直線變成橢圓曲線的切線即可,像下面這樣:
我們定義對一個點 P 進行 n 次加法得到 nP,稱之爲標量乘法。如前面例子中 。
不過,當 n 很大時,執行 n 次加法需要 時間,效率有問題。因爲橢圓曲線點加法在實數域構成阿貝爾羣,滿足交換律和結合律,於是可以通過 [Double-and-add] 算法進行優化。比如 ,其二進制表示爲 ,通過優化只要7次倍乘和4次加法計算即可,時間複雜度降到 。這是一個很好的單向函數,正向計算容易,而反向和蠻力計算複雜。
令 ,則 Q 作爲公鑰,n 爲私鑰。如果要破解該密鑰,問題就是 "Q = nP,如果已知 P 和 Q,如何求解 n"? 這個問題是比較困難的。不過由於在實數域上曲線連續,可能會更容易找到一些規律進行破解。而且實數域上數值大小沒有限制、浮點數等問題而導致計算效率問題,在實際應用中常將橢圓曲線限制到一個有限域內,將曲線變成離散的點,這樣即方便了計算也加大了破解難度。
4 有限域橢圓曲線
4.1 點加法
前面提到爲了安全性和便於實現,需要將橢圓曲線限制到一個有限域內,通常用的是素數域 (即對於點 爲素數)。於是破解就會變成一個離散對數問題,這比連續曲線上的對數問題會難很多。素數域下橢圓曲線定義如下:
下面是曲線 和 的圖像。可以發現,橢圓曲線變成了離散的點,且關於 對稱。
定義 上橢圓曲線點加法 如下,公式跟實數域上相比只是多了模 操作。
斜率 m 計算同樣分兩種情況:
橢圓曲線在素數域 上的點加法依然構成阿貝爾羣。單位元依舊是無窮遠點,元素 的逆元變成 。而交換律、結合律、封閉性則可以通過素域上的模加法、模乘法來證明。實數域的橢圓曲線點加法定義是有明確幾何意義的,從幾何上好證明。而橢圓曲線在 就沒有明顯的幾何意義了,觀察可發現 三點滿足 ,羣律的證明過於繁瑣,略去(其實是沒有找到一個簡易的證明)。
以前面曲線爲例,,則有 ,且 和 都在橢圓曲線上。從圖形上看, 在直線 上。
4.2 橢圓曲線羣的階
在有限域下,橢圓曲線加法羣的元素是有限的,元素數目就是羣的階。
如橢圓曲線 ,其在素數域 中元素有 ,階爲24(23個素數域中的點 + 1個無窮遠點),如果 p 很大的話,則通過蠻力計算階是很難的,好在使用 [Schoof算法] 可以在多項式時間內計算出羣的階。計算橢圓曲線在有限域上點的數目可以參見 [Counting points on elliptic curves]。
Schoof算法運用了 Hasses 定理。Hasses定理給出了橢圓曲線在 的階的範圍,可以看出,當 p 很大時,階跟 p 的值是比較接近的。
Hasses 定理:令 是 上的橢圓曲線, 上的點的數量 滿足如下條件:
4.3 循環子羣
跟實數域一樣,在素數域裏面也是選取一個點 P,然後計算倍乘 nP 作爲公鑰。還是以 爲例,,我們採用素數域下新的計算公式計算 。
可以發現 ,即 P 的標量乘法得到的點集是原橢圓曲線羣的一個子集,則它是原橢圓曲線羣的一個子羣,而且是循環子羣。子羣中元素個數稱爲子羣的階(示例子羣的階爲8),點 P 稱爲該子羣的基點或者生成元。循環子羣是橢圓曲線密碼體系的基礎,我們期望子羣中元素越多越好,如何找到一個合適的子羣尤爲重要。
首先要解決一個問題,就是已知 下的橢圓曲線上的點 P,如何求得 P 的倍乘運算後生成的子羣的階? 根據拉格朗日的羣論定理,子羣的階是父羣的階的約數。求解曲線上點 P 生成的子羣的階可以用下面方法:
- 首先,使用Schoof算法求得橢圓曲線羣的階 。
- 找到 所有的約數。
- 對 所有的約數 ,計算 。
- 其中 中最小的 就是子羣的階。
以示例曲線爲例,父羣的階是 ,則以曲線上的點生成的子羣的階只能是 。對於點 ,故其生成的子羣的階就是 8,而點 生成的子羣的階則正好等於父羣的階24。
4.4 尋找基點
在加密算法中,我們期望找到一個階高的子羣。不過,通常不是先去找個基點,然後計算子羣的階,因爲這樣過於不確定,算法上不好實現。相反地,先選擇一個大的子羣階,然後再找生成該子羣的一個基點就容易多了。
前面提到,子羣的階 n 是父羣的階 N 的約數,即有 ,h 是一個整數,我們稱之爲子羣的餘因子(cofactor)。因爲 ,所以有:
通常會選擇一個素數作爲子羣的階,即 n 是素數。可以發現,點 生成了階爲 n 的子羣( 除外,因爲這個子羣的階爲1),不等於 的點 就是我們尋找的基點。具體步驟如下:
- 1)計算橢圓曲線的階 。
- 2)選擇子羣的階 。 是 的約數,且要選擇素數。通常是越大越好,如 。
- 3)計算餘因子 。
- 4)從橢圓曲線隨機選取一個點 ,計算 。
- 5)如果 ,則返回第 4 步重新選一個點計算。
需要注意,上面算法裏的 n 必須是素數,否則計算的基點 G 生成的子羣的階可能是 n 的約數而不是 n,不符合要求。以曲線 爲例,,我們選擇 ,則 ,隨機選取一個點 ,計算 ,恰好滿足要求。
4.5 域參數
如前所述,橢圓曲線加密算法工作在素數域下的橢圓曲線循環子羣中,需要的域參數(Domain Parameter)包括 :
- p: 素數域的大小。
- a, b: 橢圓曲線 的係數。
- G:生成子羣的基點。
- n:子羣的階。
- h:子羣的餘因子。
如比特幣用來做數字簽名中採用的橢圓曲線 [secp256k1] 的域參數如下:
- p = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F =
- a = 0, b = 7,即曲線方程是 。
- G = (0x79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798,
0x483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8) - n = 0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141
- h = 1
5 橢圓曲線在密碼學的應用
5.1 ECDH(E)
在 ECDH 跟(Diffie–Hellman Key Exchange)有點類似,只是不再通過簡單的模冪運算,而是通過素數域下的橢圓曲線的標量乘法來實現。流程如下:
- Alice 和 Bob 生成各自的公私鑰。假設 Alice 的私鑰是 ,公鑰則爲 ,Bob 的則是 和 。他們用的同一個基點 、同一個整數有限域,同一條橢圓曲線。
- Alice 和 Bob 通過不安全的信道交換公鑰 和 。
- Alice 計算 ,Bob 計算 ,共享密鑰就是 。對稱加密算法 AES 或者 3DES 只用 的一個座標如x座標作爲密鑰即可。
- 要想破解密鑰就好比"已知 求 a 和 b?",當 和 很大的時候,破解是很困難的,這也被稱爲橢圓曲線的離散對數問題,即 ECDLP。
ECDHE (Ephemeral ECDH) 與 ECDH 不同之處在於,它的公私鑰並不固定,而是每次會話臨時生成,這樣就能具有前向安全性,實際項目中也用的更多。
5.2 ECDSA
ECDSA 是 DSA 算法的變種,常用於數字簽名。Alice 通過橢圓曲線算法生成公私鑰 ,對要簽名的消息通過哈希算法生成摘要 (z爲整數),然後 Alice 用私鑰 按照下面步驟對摘要 生成簽名。 Bob 通過公鑰 驗證簽名。
生成簽名
- 1)Alice 選取一個隨機數 k,其中 ,n爲子羣的階。
- 2)計算 ,G 是曲線的基點。
- 3)計算 ,如果 ,則回到第1步重新選擇一個 k 重試。
- 4)計算 。如果 ,則回到第1步重新選擇一個 k 重試。
- 5) 就是最終的簽名對。
校驗簽名
- 1)計算 。
- 2)計算 。
- 3)計算 。
- 4)如果 ,則簽名有效。
證明
因爲 ,於是:
而之前定義有:。
因此 ,這與生成簽名時一致,故而證明完畢。
實例分析
還是以爲例,,選取 。選擇 ,則 。假設要簽名的消息摘要 。經過計算發現,驗證成功。
生成簽名:
- 選擇隨機數 。
- 。
- 。
- 。
- 所以簽名對就是 。
驗證簽名:
- 。
- 。
- 。
- 。
注意事項
- ECDSA 中用的子羣的階 n 必須是素數,否則 可能不存在。
- 選擇 k 的隨機數生成器一定要設計好,不能有漏洞。如果隨機數生成不夠隨機或者可預測,則可能出現兩個相同的隨機數,繼而會有兩個相同的簽名,如 。則根據公式可以計算出 k,繼而就能計算出私鑰 了。
5.3 TLS密鑰交換
TLS裏面加密用的 Cipher Suite有很多,常見的如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,意思是: 使用ECDHE進行密鑰交換,RSA做服務驗證,SHA256用於簽名摘要生成,AES128-GCM用作對稱加密。
現在 TLS 密鑰交換和簽名通常有三種方式:RSA,ECDHE_RSA 以及 ECDHE_ECDSA,區別如下。關於 TLS 的具體流程分析,這篇文章 [The Illustrated TLS Connection-Every byte of a TLS connection explained and reproduced] 有詳細論述,強烈推薦。
- RSA: 密鑰交換無需數字簽名,不過由於其沒有前向安全性,已經用的不多。
- ECDHE_RSA:使用ECDHE密鑰交換,RSA數字簽名,目前使用比較廣泛。在ECDHE中,客戶端和服務端都會生成各自的橢圓曲線密鑰對,服務端給客戶端發送它的橢圓曲線公鑰的時候使用RSA證書私鑰做數字簽名,客戶端使用RSA證書中的公鑰驗證簽名。
- ECDHE_ECDSA:使用ECDHE密鑰交換,ECDSA數字簽名,需要使用 ECC 證書。
6 總結
本文介紹了橢圓曲線密碼學原理。通過定義有限域下面橢圓曲線的一種點加法,並證明該橢圓曲線在實數域和素數域下該點加法都構成阿貝爾羣。由此定義了標量乘法,,通過隨機數生成算法隨機選擇一個正整數 k 作爲私鑰,從而得到公鑰 Q 和 私鑰 k。文章最後簡要分析了 ECDHE 和 ECDSA 的數學原理和應用。
如文中所述,橢圓曲線的構建和選擇需要注意如下幾點:
- 素數域 p 和 子羣的階 n 不能太小,否則會有破解風險,建議 256 位以上。
- 素數域大小 p 和 n 需要滿足 ,否則會有風險,詳見 [Weak Curves In Elliptic Curve Cryptography]。
- ECDSA 的橢圓曲線子羣的階 n 必須是素數,且隨機數生成算法一定要夠隨機不可預測,否則會有泄露私鑰的風險,原理前文已經說過。如 [這篇文章] 就描述瞭如何使用隨機數碰撞獲取私鑰恢復以太坊錢包的。
- 美國國家安全局曾經推薦使用 secp256r1,它的曲線方程的係數比 secp256k1 複雜許多。然而由於該曲線的設計過程不透明,在生成曲線參數a和b中使用的隨機算法種子是個很奇怪的數字,很早就被懷疑有後門,在棱鏡門後懷疑聲更甚。巧的是,中本聰在設計比特幣的時候也恰好繞過了使用該曲線。這裏有篇文章 [a-tale-of-two-elliptic-curves] 介紹了這兩種曲線。棱鏡門之後,Daniel J. Bernstein 教授早年設計的 curve25519 曲線大火,該曲線係數來源明確,也已經被越來越多的機構採納。
參考資料
- https://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introduction/
- http://www.andrew.cmu.edu/user/tnayak/papers/EllipticCurves.pdf
- https://arstechnica.com/information-technology/2013/10/a-relatively-easy-to-understand-primer-on-elliptic-curve-cryptography
- Understanding Cryptography
- https://tools.ietf.org/html/rfc7748
- https://tls.ulfheim.net/
- https://juejin.im/post/5a9400fcf265da4e976eb4b9
- https://www.zhihu.com/question/23091609