Fork me on GitHub

区块链学习笔记(二)

0. 说在前面

今天打算把这两天从《精通比特币》这本中了解的两种算法记录下来,希望我以及和我一样的数学小白能理解这两种算法的意义。简单的概括一下,椭圆曲线方程算法是一种从私钥生成公钥的非对称加密技术,是密码学的一种算法;哈希二叉树是区块链中存储交易记录的一种高效的数据结构,它结合了哈希表与二叉平衡树,使得验证交易的时间随交易数量增加上升得很慢。下面我会尽可能白话地讲解这两个知识点,本身他们不存在什么联系,我只是在看了前半本书后,对这两个知识点记忆比较深刻,同时也是比较懵懂的情况下,查了一些书籍,根据一些博客的介绍,才对这两个知识点慢慢有了一定的了解,要原谅一个小白的学习效率。

1. 椭圆曲线方程

椭圆曲线方程这篇博客讲的很详细,我只是在理解它的基础上加以解释。接下去,我会按照我理解的逻辑描述椭圆曲线方程。简单的来说,椭圆曲线方程的存在,是为了构建一类数,这类数满足我们设定的四则运算,比如自然数,实数。所以椭圆曲线方程是构建这类数的一个工具,是为了使这类数的四则运算很难逆转,也就是无法从结果推知计算过程。

射线平面坐标系

其实,椭圆曲线方程与椭圆无关,他是一种直角坐标系中的曲线,是由满足每个方程的点对组成。为了使构建的数域更加的完成,我们首先要引入射线平面坐标系。在学习平面几何的时候,我们都知道两条平行线永不相交,这是没有给出证明,也就是说这是一个公设,那为什么不能认为两个平行线相交于无穷远点。所谓无穷远点,也是构建出来的(数学就是这么多假设,这么多设想,想想多少星星是数学算出来的,好可怕)。

无穷远点有如下定义:

    每条直线上只有一个无穷远点;
  同一平面上的平行线有相同的无穷远点;
  相交的直线的无穷远点不同;
  平面上所有无穷远点构成一条直线;
  射影平面包括无穷远点和平常点。

avatar
我们都知道,平面上的曲线都是可以用方程来表示的,那么射影平面中椭圆曲线也是可以用方程来表示,椭圆曲线就是一群在射影平面上满足威尔斯特拉斯方程(Weierstrass)点。

$Y^2Z+a_2XYZ+a_3YZ^2=X^3+a_2X^2Z+a_4XZ^2+a_6Z^3$

椭圆曲线上每一个点都必须是光滑的,也就是有切线,当Z为零时,就是无穷远点。Z不为零时,椭圆曲线方程上的点称为平常点,所以每一个平常点都有切线。

有没有可能通过一种运算方法把椭圆曲线上的点联系起来,这在数学上称为群,也就是说可以曲线上的点可以通过曲线上的其他点应用这种四则运算得到。由此,我们定义了椭圆曲线加法。任意取椭圆曲线上两点P、Q(若P、Q两点重合,则作P点的切线),作直线交于椭圆曲线的另一点R’,过R’做y轴的平行线交于R,定义P+Q=R。这样,加法的和也在椭圆曲线上,并同样具备加法的交换律、结合律。

到这里,我们在射影平面上构建了椭圆曲线,并且在椭圆曲线上构建了一个数群。但是这个数群时连续的,连续的数群时无法用来加密。

有限域的椭圆曲线方程

所谓有限域的理解,其实很简单就是只选择椭圆曲线上的部分点,将曲线上的所有点除以某个素数p然后取其余数,这样,椭圆曲线上的数组成了一个p阶的数域。并且这个数域中的所有数都符合先前建立的四则运算。这样,有限域的椭圆曲线方程便建立,并且是一个离散的形如自然数的数据集。

下面,我们给出一个有限域Fp,这个域只有有限个元素。

Fp中只有p(p为素数)个元素0,1,2 …… p-2,p-1;

Fp 的加法(a+b)法则是 a+b≡c (mod p);即,(a+c)÷p的余数 和c÷p的余数相同。

Fp 的乘法(a×b)法则是 a×b≡c (mod p);

Fp 的除法(a÷b)法则是 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。

这样就可以通过计算K=kG来进行加密。公开的密钥算法都是基于数学上的难题来达到加密的目的的,比如计算两个素数的乘积比较容易,但是要对这个乘积进行因式分解就比较困难了。同样这里也是,已知k和G计算K,相对比较容易,而通过K和G计算k就比较困难,其中G为椭圆曲线上的一个平常点。

哈希二叉树

所谓哈希二叉树,又叫做默克尔树,是一种区块中存储交易信息的数据结构。这种数据结构最大的好处就在于,每个交易都可以单独直接删除,只保留这个交易的Hash值即可。这样,对整个区块来说,并没有改变他的密码学安全性和完整性,但是数据量可以大大减小。(Hash值32个字节,而一笔交易一般要400多个字节)。如果一个区块中只有一个交易没有后续交易,那么删除其他所有交易,整个区块的数据量会大大减小。因此,在UTXO的记账模式中,使用默克尔树结构,通常就无需担心数据量一直增长导致数据过大的问题了。

哈希就是把任意数据映射程固定长度的数据的函数,如MD5等。

默克尔树是哈希表的一种拓展。或者说哈希表可以看作一种特殊的默克尔树,即树高为2的多叉默克尔树。默克尔树的叶节点是一个个数据块,有相应的哈希与它对应。然后往上走,把每一个叶节点得到的哈希合并成字符串,在运算这个字符串的哈希,这样就得到了一个子哈希。这样最终推算到根节点。这样当叶节点为单数时,在遇到最后一个叶节点时,会复制该叶节点,然后计算这两个叶节点的哈希合并字符串的哈希,生成子哈希。

默克尔树与哈希表的不同在于,默克尔树可以通过分支验证,而不用下载整个列表。这样就节省搜索耗时和存储资源。