



公钥密码学诞生于20世纪70年代,是现代计算机和信息安全的数学基础。
自从公钥密码学诞生以来,人们已经发现了一些合适的数学函数,如素数指数和椭圆曲线乘法。这些数学函数实际上都是不可逆的,这意味着它们很容易在一个方向上计算,但却不可能在相反的方向上被倒推。基于这些数学函数,密码学可以创建不可伪造的数字签名。比特币使用椭圆曲线加法和乘法作为其加密的基础。
在比特币系统中,我们使用公钥密码学来创建一个控制访问比特币的密钥对。这对密钥由私钥和从私钥衍生出的公钥组成。公钥用于接收资金,而私钥用于签名交易以支出资金。
公共和私钥之间存在一种数学关系,允许使用私钥在消息上生成签名。这个签名可以在不泄露私钥的情况下通过公钥进行验证。
在大多数钱包实现中,为方便起见,私钥和公钥被一起存储为密钥对。但是,可以从私钥计算公钥,所以只存储私钥也是可以的。
比特币钱包包含了一系列密钥对,每个密钥对由一个私钥和一个公钥组成。私钥( k )是一串数字,通常是随机生成的。我们使用椭圆曲线乘法这种单向加密函数,从私钥生成公钥( K )。
为什么在比特币中使用非对称加密?它并不被用于对比特币交易“加密”(保密)。相反,非对称加密技术最有用的特性是能够生成数字签名。可以将私钥应用到比特币交易上生成数字签名。该签名只能由拥有私钥的人生成。然而,任何人只要拥有公钥和交易信息,都可以使用它们来验证签名的真伪。这种非对称加密的有用特性使得任何人都可以验证每个交易上的每个签名,同时确保只有私钥的所有者才能生成有效的签名。
私钥实际上就是一个随机挑选的数字。对私钥的控制构成了用户对相应比特币公钥所有资金控制的基础。私钥用于创建签名,这些签名用来证明交易中使用的资金的控制权以消费比特币。私钥必须始终保密,因为将其泄露给第三方,等同于将由该密钥保护的比特币的控制权交给他们。私钥还必须备份且防止意外丢失,因为一旦丢失,私钥就无法恢复,由它保护的资金也将永远丢失。
比特币私钥只是一个数字。你可以用硬币、铅笔和纸来随机生成你的私钥:抛硬币256次,用纸和笔记录硬币正反面出现的次序得到的256位二进制数字可作为私钥在比特币钱包里使用。然后,公钥可以从私钥生成。不过要小心,私钥任何非纯随机的过程都会显著降低私钥的安全性以及它控制的比特币。
生成密钥的第一步也是最重要的一步,是要找到一个安全的随机性来源(计算机科学家称之为熵源)。创建一个比特币密钥几乎就是“在1到2 256 之间选一个数字”。只要选取这个数字的方法既不可预测也不可重复,那么具体怎么选都没有关系。比特币软件使用符合密码学安全性随机数生成器来产生256位的熵。
更准确地说,私钥可以是从0到 n -1(包括0和 n -1)之间的任何数字,这里的 n 是一个常数( n =1.1578×10 77 ,略小于2 256 ),它被定义为比特币中使用的椭圆曲线的阶(参见4.1.2节)。为了创建这样的密钥,我们随机挑选一个256位的数,并检查它是否小于 n 。从编程的角度来看,一般是通过在一个密码学安全的随机源中取出一长串随机字节,对其使用SHA256哈希算法进行运算,这样就可以方便地产生一个256位的数字。如果运算结果小于 n -1,那么我们就有了一个合适的私钥。否则,我们就用另一个随机数再重复一次这个过程。
不要自己写代码或使用编程语言提供的简易随机数生成器来获得一个随机数。要使用密码学安全的伪随机数生成器(Cryptographically Secure Pseudorandom Number Generator,CSPRNG),并且需要有一个来自具有足够熵值源的种子。使用随机数生成器的函数库时,必须仔细研读其文档,以确保它是密码学安全的。正确实施CSPRNG是密钥安全性的关键所在。
以下是随机生成的私钥( k ),显示为十六进制格式(256位显示为64个十六进制数字,每4位表示一个数字):
比特币的私钥空间(2
256
)大小是一个难以想象的大数字,约等于10
77
。给你一些实际的概念作对比,目前可见宇宙估计含有10
80
个原子。
椭圆曲线密码学(Elliptic Curve Cryptography,ECC)是一种基于离散对数问题的非对称密码学或公钥密码学,该问题由椭圆曲线上各点之间的加法和乘法表示。
图4-2是一个椭圆曲线的例子,与比特币使用的椭圆曲线相似。
图4-2:一个椭圆曲线
比特币使用的是一个特定的椭圆曲线和一组数学常数,它是由美国国家标准与技术研究所(National Institute of Standards and Technology,NIST)制定的标准secp256k1定义的。secp256k1曲线由下述函数定义,该函数可产生一条椭圆曲线:
y 2 =( x 3 +7)over(F p )
或
y 2 mod p =( x 3 +7)mod p
该模 p (模质数 p )表示这条曲线定义在有限域上,该有限域的阶为质数 p ,亦可表示为F p ,其中 p =2 256 -2 32 -2 9 -2 8 -2 7 -2 6 -2 4 -1,这是一个非常大的质数。
由于这条曲线是在有限素数域上定义的,而非实数域,因此它看起来像是二维平面上散乱的点阵,这使得它难以直观地呈现。然而,曲线的数学性质与定义在实数域上的椭圆曲线是相同的。举个例子,图4-3显示了同一椭圆曲线在一个远小于secp256k1的有限素数域17上的情形,呈现为网格上的点阵图样。而比特币椭圆曲线secp256k1可以被想象为在一张难以想象的巨大网格上,形成的一个更为复杂的点阵模式。
例如,以下是一个在secp256k1曲线上的点P,其坐标为( x , y ):
图4-3:椭圆曲线密码学:在有限域 F ( p ),其中 p =17的情况下可视化椭圆曲线
示例4-1展示了你如何使用Python自行验证这一点。
示例4-1:使用Python验证这个点是否在椭圆曲线上
在椭圆曲线的数学原理中,有些点被称为“无穷远点”,这大致对应于0在加法中的作用。计算机中,有时用 x = y =0表示(虽然这不满足椭圆曲线方程,但这是一个可以检查的简单独立的例子)。
在椭圆曲线上也有一种运算,被称为“加法”,它具有一些与小学生学习的实数传统加法相似的性质。给定椭圆曲线上的两个点P 1 和P 2 ,就存在第三个点P 3 =P 1 +P 2 ,同样也在椭圆曲线上。
在几何学上,P 3 是通过在P 1 和P 2 之间画一条直线来计算的。这条线将与椭圆曲线在另外一个完全不同的地方相交。我们将这个交点称为P 3 ′=( x , y )。然后,相对于 x 轴做反射,得到点P 3 =( x , -y )。
下面几个特殊案例阐释了为何需要“无穷远点”。
如果P 1 和P 2 是同一个点,那么“介于”P 1 和P 2 之间的直线应该延伸为在这一点P 1 上的曲线的切线。这条切线将恰好在曲线上的一个新点与曲线相交。你可以使用微积分的方法来确定切线的斜率。神奇的是,尽管我们仅关注曲线上那些具有两个整数坐标的点,但这些方法依旧适用!
在某些情况下(例如,如果P 1 和P 2 的 x 值相同但 y 值不同),切线将会是完全垂直的,这种情况下P 3 =“无穷远点”。
如果P 1 是“无穷远点”,那么P 1 +P 2 =P 2 。同样地,如果P 2 是无穷远点,那么P 1 +P 2 =P 1 。这展示了无穷远点如何扮演零的角色。
可以证明+运算是满足结合律的,这意味着(A+B)+C=A+(B+C)。这表明我们可以不用括号就无歧义地写成A+B+C。
现在我们已经定义了加法,我们可以对乘法用拓展加法的标准方法进行定义乘法。对于椭圆曲线上的一个点P,如果 k 是一个整数,那么 k P=P+P+P+…+P( k 次)。注意,在这种情况下 k 有时被混淆而称为“指数”。
公钥通过椭圆曲线乘法从私钥计算而来,这一过程是不可逆的: K = k × G ,其中 k 是私钥, G 是一个常量点,称为生成点,而 K 是生成的公钥。反向操作,即“求解离散对数”——若要通过已知的 K 计算 k ,则难度和尝试所有可能的 k 值(即穷举搜索)一样。在我们展示如何从私钥生成公钥之前,让我们更详尽地了解一下椭圆曲线密码学。
椭圆曲线乘法是密码学家所称的“陷门”函数:它在一个方向上(乘法)很容易完成,但在逆向上(除法)则不可能做到。拥有私钥的人可以轻松创建公钥,并将其与世界共享,同时知晓没有人能够逆向该函数,从公钥计算出私钥。这个数学技巧成为不可伪造且安全的数字签名的基础,证明了对比特币资金的控制权。
从一个以随机生成的数字 k 形式存在的私钥开始,我们将它乘以曲线上预定的一个点,称为生成点 G ,以产生曲线上另一个点,这个点就是相应的公钥 K 。生成点作为secp256k1标准的一部分被指定,且对于比特币中的所有密钥而言始终是相同的:
K = k × G
在比特币系统中, k 表示私钥, G 为生成点,而 K 是由此产生的公钥——一个曲线上的点。由于所有比特币用户的生成点 G 总是相同的,因此私钥 k 与 G 的乘积总会得到相同的公钥 K 。 k 与 K 之间的关系是固定的,但仅能从一方向计算,也就是从 k 到 K 。这就是为何比特币公钥( K )可以与任何人共享,而不会透露用户的私钥( k )。
私钥可以转换成公钥,但是公钥不能转换回私钥,因为这种数学运算只能单向进行。
我们在实施椭圆曲线乘法时,将先前生成的私钥 k 与生成元点 G 相乘,来找到公钥 K :
公钥 K 被定义为一个点 K =( x , y ):
K =( x , y )
其中,
为了直观地展示一个点与一个整数相乘,我们将使用定义在实数域上的简单椭圆曲线——记住,数学规则是相通的。我们的目标在于找到生成点 G 的 k 倍点 kG ,这相当于将 G 与其自身连续相加 k 次。在椭圆曲线中,将一个点与其自身相加等同于在该点上画一条切线,并找出它与曲线的另一交点,然后将这个交点关于 x 轴进行对称反射。
图4-4展示了在曲线上通过几何操作得出 G 、2 G 、4 G 的过程。
许多比特币实现使用了libsecp256k1密码学库(
https://oreil.ly/wD60m
)来进行椭圆曲线数学运算。