椭圆曲线密码学是比特币算法中相当重要的一个密码学算法. 对于普通的开发者, 理解椭圆曲线密码学不是必须的, 因为的确已经有太多的 SDK 帮我们屏蔽了这些细节. 但是, 密码学是比特币的基石. 要真正进入区块链的世界, 深入理解其底层的密码学算法是必须的.
基础知识
椭圆曲线(英语:Elliptic curve,缩写为 EC)为一代数曲线,被下列式子所定义:
y2 = x3 + ax + b
其是无奇点的;亦即,其图形没有尖点或自相交。
若 y2=P(x), 其中P为任一没有重根的三次或四次多项式,然后可得到一亏格1的无奇点平面曲线,其通常亦被称为椭圆曲线。更一般化地,一亏格1的代数曲线,如两个三维二次曲面相交,即称为椭圆曲线。
椭圆曲线密码学(Elliptic Curve Cryptography, 缩写为 ECC), 椭圆曲线加密法是一种基于离散对数问题的非对称加密法,可以用对椭圆曲线上的点进行加法或乘法运算来表达。ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。ECC的另一个优势是可以定义群之间的双线性映射,基于Weil对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。
椭圆曲线加法和无穷远点. 在椭圆曲线的数学原理中,有一个点被称为“无穷远点”,这大致对应于0在加法中的作用。计算机中,它有时表示为X = Y = 0(虽然这不满足椭圆曲线方程,但可作为特殊情况进行检验)。
还有一个 + 运算符,被称为“加法”,就像小学数学中的实数相加。给定椭圆曲线上的两个点P1和P2,则椭圆曲线上必定有第三点 P3 = P1 + P2。 几何图形中,该第三点P3可以在P1和P2之间画一条线来确定。这条直线恰好与椭圆曲线相交于另外一个地方。此点记为 P3’= (x,y)。然后,在x轴做翻折获得 P3=(x,-y)
下面是几个可以解释“穷远点”之存在需要的特殊情况。
若 P1和 P2是同一点,P1和P2间的连线则为点P1 的切线。曲线上有且只有一个新的点与该切线相交。该切线的斜率可用微积分求得。即使限制曲线点为两个整数坐标也可求得斜率!
在某些情况下(即,如果P1和P2具有相同的x值,但不同的y值),则切线会完全垂直,在这种情况下,P3 = “无穷远点”。
若P1就是“无穷远点”,那么其和 P1 + P2= P2。类似地,当P2是无穷远点,则P1+ P2 = P1。这就是把无穷远点类似于0的作用。 事实证明,在这里 + 运算符遵守结合律,这意味着(A+B)+C = A+(B+C)。这就是说我们可以直接不加括号书写 A + B + C,而不至于混淆。 因此,我们已经定义了椭圆加法,我们可以对乘法用拓展加法的标准方法进行定义。给定椭圆曲线上的点P,如果k是整数,则 kP = P + P + P + …+ P(k次)。注意,在这种情况下k有时被混淆而称为“指数”。
在椭圆曲线中,点的相加等同于从该点画切线找到与曲线相交的另一点,然后翻折到x轴。
下图显示了在曲线上得到 G、2G、4G 的几何操作。
比特币中的 ECC
通过椭圆曲线乘法可以从私钥计算得到公钥,这是不可逆转的过程:K = k * G 。其中k是私钥,G是被称为生成点的常数点,而K是所得公钥。其反向运算,被称为“寻找离散对数”——已知公钥K来求出私钥k——是非常困难的,就像去试验所有可能的k值,即暴力搜索。
比特币使用了secp256k1标准所定义的一种特殊的椭圆曲线和一系列数学常数。该标准由美国国家标准与技术研究院 (NIST)设立。secp256k1曲线由下述函数定义,该函数可产生一条椭圆曲线:
y2 mod p = (x3 + 7) mod p
上述mod p(素数p取模)表明该曲线是在素数阶p的有限域内,也写作Fp,其中p = 2^256 – 2^32 – 2^9 – 2^8 – 2^7 – 2^6 – 2^4 – 1, 这是个非常大的素数。因为这条曲线被定义在一个素数阶的有限域内,而不是定义在实数范围,它的函数图像看起来像分散在两个维度上的散落的点,因此很难可视化。
从私钥生成公钥
私钥可以是1和n-1之间的任何数字,其中n是一个常数(n=1.158 * 10^77,略小于2^256),并被定义为由比特币所使用的椭圆曲线的阶.
以一个随机生成的私钥k为起点,我们将其与曲线上预定的生成点G相乘以获得曲线上的另一点,也就是相应的公钥 K。生成点是 secp256k1 标准的一部分,比特币密钥的生成点都是相同的.
{K = k * G}
其中 k 是私钥,G 是生成点,在该曲线上所得的点 K 是公钥。因为所有比特币用户的生成点是相同的,一个私钥 k 乘以 G 将得到相同的公钥 K。k 和 K 之间的关系是固定的,但只能单向运算,即从 k 得到 K。这就是可以把比特币地址(K 的衍生)与任何人共享而不会泄露私钥(k)的原因。
计算公钥的本质就是找到生成点 G 的倍数 kG。也就是将 G 相加 k 次。在椭圆曲线中,点的相加等同于从该点画切线找到与曲线相交的另一点P’,然后以 X 轴对称得到 点 P.