公钥加密算法有两种,RSA 和 ECC,RSA 简单易懂但效率低,ECC 效率高,用 256 位秘钥抵得过 RSA 3072 位秘钥,但 ECC 数学原理复杂,实现也比 RSA 难。
要理解 ECC 椭圆曲线加密算法,就得顺藤摸瓜,一路搞定下面这些原理。
1. 射影平面坐标系。比之笛卡尔的 XY 坐标系,多了一条无穷远点的直线。方程式里加了个 Z,但这并非三维坐标系。
2. 射影平面上的加法,使用阿贝尔群的加法法则。
3. Weierstrass 函数:y^2*z+a1*x*y*z+a3*y*z^2=x^3+a2*x^2*z+a3*x*z^2+a6*z^3 在射影平面坐标系中的曲线,便是我们所谓的椭圆曲线。当然,要把 Z 替换成 XY,方程式简化成:y2 = x3 + ax + b
于是得到了这样的曲线:
4. 这样的曲线是连续的,其上的每个点都是实数,没法用于加密运算。在其上任意取一点,点的值是不精确的,带着小数,不好做运算。于是,将该曲线挪到 “有限域” 上,所谓有限域,就是 0 到 p-1 之间的整数, p 是一个整数。再对方程式 y2 = x3 + ax + b,引入模运算,成为 y^2 mod p = (x^3 + ax + b)mod p,这个方程式也可以写为: y^2 = x^3 + ax + b + kp。
这个方程式用来加解密的过程,就不解释了,网上资料不少,密码学的书中也有。
其原理基于,射影平面上的加法算法,其正向过程是简单容易的,而加法的逆向过程,则是困难的。我们可以用打台球来比喻,确定一个球的初始位置为 p1,对 p1 进行 n 次击球(假设 n 次击球的力度和方向一致),最终获得位置为 p2。已知 p1 和 n,则获得 p2 非常容易,进行 n 次击球便可。但若已知 p1 和 p2,要倒推出 n 来,则很难。这个道理,人人皆知。 椭圆曲线在射影平面上的加法之不可逆,和上面的台球游戏类似。
用来加解密和签名的 ECC 曲线,由如下几个参数确定:(p,a,b,G,n,h)。 p 便是有限域的整数范围, a,b 则是确定曲线的形状, G 是曲线上选择的初始点,n 则是用来进行加法的次数, h 是协因子,不知道干嘛用的,一般取 1。
比特币所用 Secp256k1 曲线的参数如下:
p = 2^256 − 2^32 − 2^9 − 2^8 − 2^7 − 2^6 − 2^4 − 1 = 2^256 – 2^32 – 977
a = 0
b = 7
这就是中本聪挑选的曲线,并非一条流行通用的曲线。去掉模运算,用 x y 方程简单表示为 y^2 = x^3 + 7。
Secp256k1 中 “sec” 的意思是 Standards for Efficient Cryptography,"p" 则代表有限域参数 p,256 代表 p 的位数,而 “k” 则大有深意。
“k” 代表 Koblitz,这是椭圆曲线加密算法发明人 Koblitz 的名字,在这里指的一类曲线,这一类曲线的参数是刻意挑选出来的。比如上面的 a 和 b,一个 0,一个 7,一看就知道是刻意挑选出来的。
k 后面的 1 代表序号。
与 “k” 对应的叫 “r”,所谓 r 指代 Random,就是随机数的意思。大家就明白了,曲线所用参数是随机挑选出来的。比如 Secp256r1 的参数如下:
p = 2^224(2^32 − 1) + 2^192 + 2^96 − 1
a = 115792089210356248762697446949407573530086143415290314195533631308867097853948
b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
这个 Secp256r1 还有一个名字,叫 NIST P256,NIST 是 National Institute of Standards and Technology,也就是美国国家标准技术委员会,隶属商务部,专门为政府机构制定技术标准。所以,Secp256r1 那算是闪耀着官方光环的技术。这个标准是 1999 年 NIST 发布的。
既然 p,a,b这些参数都是随机挑选出来的,那么自然应该更安全了。理论上是这样的,但“随机” 这两个字可不是那么容易的,不是上嘴唇一碰下嘴唇就能出来一个随机数。 计算机里的随机数一直是个难题。
Secp256r1 的随机数生成是用哈希算法 SHA1 实现的,用SHA1算法对某个字符串进行哈希,每次都能生成非常随即的数字。 而 Secp256r1 的 p,a,b 做 SHA1 的字符串是:c49d360886e704936a6678e1139d26b7819f7e90。
密码学界以及加密学应用技术行业的疑心由此而起:NIST 为何挑选了这个字符串?
哈希运算的特点,大家都清楚,NIST 无法根据一条既定曲线,返过去计算出 SHA1 的种子字符串。
所以大家就怀疑,NIST 很可能测试了无数的种子字符串,最终选择了一条较弱的曲线。这是一种暴力的挑选方法,据传 NIST 测试了 10 亿条曲线。2014 年密码学者 Daniel J. Bernstein1 和 Tung Chou 便发表过文章 “How to manipulate curve standards: a white paper for the black hat” 介绍了如何操控 ECC 曲线标准的制定。
大家的担心虽然并无实证,但 NIST 在椭圆曲线上做手脚,并非第一次,而且之前那次是有实锤证据的。2007 年 NIST 发布了 130 页的技术标准文书: NIST Special Publication 800-90,其中介绍了 “Deterministic Random Bit Generators”,也就是随机数生成的技术,和上面所说用 SHA1 生成随机数类似。 介绍的技术中,有一种叫 Dual_EC_DRBG,也就是用双椭圆曲线生成随机数的技术。 技术原理和用椭圆曲线做加法进行加密类似。
还用台球做比,为了生成随机数,在巨大巨大的 “有限域” 台球桌上摆放两个台球在 p1 和 p2 位置。对在 p1 的第一个台球进行 n 次击打,n是一个秘密数字,获得位置 p1‘,这就是生成的随机数。完事后 p2 也进行 n 次击打,获得位置 p2’,将 p2‘ 替代 n,作为下一次生成随机数的秘密数字。最后,将 p1 和 p2 摆回最初的位置 p1 和 p2,等待下次。
从原理上来说,这种算法生成随机数是没问题的。就是比起其它随机数生成算法,效率要慢一些,有些密码学家就提出这个问题,这种算法的效率比该标准中的其他算法要慢三个数量级。
诡异的是,Dual_EC_DRBG 是 NSA 推荐到 NIST,并强力支持的。 NSA 是谁?大名鼎鼎的美国国家安全局,与美国民间密码学界斗争多年的强力部门。
2007 年,牛逼的 CRYPTO 大会上,密码学者 Dan Shumow 和 Niels Ferguson 指出,Dual_EC_DRBG 不仅是慢的问题,它有后门啊,NIST 指定的算法也许没问题,但 P1 和 P2 这两个初始位置有问题:这两个参数之间是有关系的,可以推算的。
这真是打了 NIST 和 NSA 的脸。当然,密码学者们并没有实锤证据,到底这个是 NIST 和 NSA 恶意设计,还是一个为他们工作的科研人员私下作恶。
直到 2013 年棱镜门爆发,斯诺登披露的政府文件显示,NSA 刻意在加密算法中植入后门。之后,路透社披露,NSA 收买了 RSA 公司,在其软件中植入 Dual_EC_DRBG,以利于破解加密技术,对互联网信息进行窃听。一切水落石出真相大白,就是 NSA 协同 NIST 捣的鬼。
比特币中对 Secp256r1 弃而不用,选择了 Secp256k1,而中本聪开发比特币软件,是在 2008 年之前。所以应当是在 2007 年 CRYPTO 大会上对 Dual_EC_DRBG 的责难,引起了中本聪的警觉。那时候棱镜门还没爆发,对于 NSA 的恶意操纵,还并没有证据。
机构作恶,人们无可奈何,无人脸红,也无人为其负责。放个后门,放了就放了吧,大家躲着走就是。