与哈希函数一起,数字签名理论为加密货币奠定了基础。

摘要:当然,高飞币有一个致命安全隐患,假设爱丽丝通过把她签署的声明发送给鲍勃,即将她的币转给鲍勃,但并没有告诉其他人,此时她也可以创建另一个签名,声明将同样一只币转给了查克,对于查克来说,这看起来是一个完全有效的交易。...

欢迎来到四叶草堂,我是龙笑生。数字签名(digital signatures)理论和哈希函数一起,为加密货币奠定了基础。更多精彩内容,敬请关注“四叶草堂”,今天继续分享《区块链:技术驱动金融》一书的精彩部分。

所有货币都需要通过某种方式控制供给,并需要实施各种安全属性以防止欺骗行为发生,就法定货币而言,中央银行这样的机构控制货币供给,并在实体货币上加上防伪标识,这些安全属性提升了攻击货币的门槛和难度,但并非不可能伪造,最终,执法部门仍需要介入,以防止货币系统规则受到破坏。加密数字货币也必须采取安全措施,以防御破坏系统状态的行为,同时加密数字货币还需要防止“混淆”,即对不同的人说出相互矛盾的话。例如,如果爱丽丝让鲍勃确信她向他支付了一个数字币,她就不能再说服卡罗尔,也给她支付同一个数字币。加密数字货币与法定货币的不同在于,其安全规则需要完全通过技术手段实现,而非依赖于中央机构。

哈希函数是一个数学函数,具有以下三个特性:● 其输入可为任意大小的字符串。● 它产生固定大小的输出,例如输出值大小为256位。● 它能进行有效计算,简单来说就是对于特定的输入字符串,在合理时间内,可以算出哈希函数的输出。此外,哈希函数达到密码安全,还需要具有以下三个附加特性:(1)碰撞阻力(collision-resistance);(2)隐秘性(hiding);(3)谜题友好(puzzle-friendliness)。

哈希函数的第一个特性是它要具有碰撞阻力,这里的碰撞指对于两个不同的输入,产生相同的输出。如果对于哈希函数H(·),没有人能够以较短时间找到碰撞,我们则称该函数具有碰撞阻力。对于一个256位输出的哈希函数来说,最坏的情况是你需要进行2256+1次哈希函数计算,平均次数为2128次,这简直是一个天文数字——如果一台电脑每秒计算10000个哈希值,计算2128个哈希值,需要花1027多年时间!为此,我们可以将哈希输出作为信息摘要(message digest)。以SecureBox为例,SecureBox是一个允许用户上传文件,并保证文件被完整下载的线上文件存储系统,假设爱丽丝上传了很大的文件,并希望能够在之后下载时确认下载的文件与她上传的文件相同。无碰撞哈希函数为这个问题提供了简单有效的解决方法,爱丽丝只需要记住原文件的哈希值,从SecureBox下载文件后,可以计算下载文件的哈希值,并与原文件哈希值进行对比,如果哈希值相同,那么爱丽丝可以说该文件就是她上传的那一个,但是如果不同,她则可以确定文件被破坏了。

哈希函数拥有的第二个特性是其隐秘性。隐秘性保证,如果我们仅仅知道哈希函数的输出y=H(x),我们没有可行的办法算出输入值x。在类似抛硬币的“正面”、“反面”实验中,如果输入值并非来自分散的集合,我们是否还能得到隐秘性?幸运的是,对于这个问题答案是肯定的!我们可以通过与另一个较为分散的输入进行结合,而将一个并不分散的输入进行隐秘。承诺方案就是应用了这一原理,我们首先产生一个临时随机数。然后将这个临时随机数与承诺信息msg一起代入承诺函数,计算承诺函数输出值com,然后公布该输出,这个过程就如同将封好的信封放到一个人人能看到的桌上那样。之后,我们公布用于产生承诺的临时随机数,并公布信息msg,此时任何人都可以验证这时公布的msg是否与之前的承诺信息一致,这个阶段就如同打开信封。

哈希函数的第三个安全特性为谜题友好特性。直觉上,谜题友好可以这样解释,如果有一个人想找到y值所对应的输入,假定在输入集合中,有一部分是非常随机的,那么他将非常难以求得y值对应的输入。这个直觉是:如果H有一个n位输出,那么它的可能取值有2n个。解决这个谜题要求找到一个位于集合Y(通常比所有输出值集合小很多)内的输出值,Y的大小决定了谜题的难度,如果Y是所有n位字符串的集合,这个谜题就毫无意义,然而,如果Y只有一个元素,那么这个谜题难度最大。如果一个哈希函数具备谜题友好特性,这就意味着对于这个谜题没有一个解决策略,比只是随机地尝试x取值会更好。

哈希指针是一种数据结构,简单来说,哈希指针是一个指向数据存储位置及其位置数据哈希值的指针。一个普通的指针可以告诉你数据存储的位置,哈希指针不但可以告诉你数据存储的位置,并且还可以给你一种方式,让你验证数据没有被篡改过。如果对手修改了区块链中任意部位的数据,那么将会导致下一个数据块的哈希指针不正确,如果我们锁定区块链的头部数据,那么即使对手修改了所有哈希指针使其与修改过的数据一致,他也无法修改头部数据,从而我们就可以检测到篡改行为。这样做的结果是,如果对手想要篡改区块链中任意地方的数据,而且保证整个内容一致,他需要篡改所有的哈希指针直至最开始的地方,最终将碰到障碍,因为他不能篡改链表头部的指针,因此,我们可以搭建一个包含很多区块的区块链网络,链表头部的哈希指针被称作创世区块(genesis block)。

另一个我们可以用哈希指针建立的数据结构是二叉树。使用哈希指针的二叉树也叫作梅克尔树(Merkle trees),以其发明者拉尔夫·梅克尔的名字命名。在梅克尔树的数据结构中,所有的数据区块都被两两分组,指向这些数据区块的指针被存储在上一层的父节点(parent node)中,而这些父节点再次被两两分组,并且指向父节点的指针被存储在上一层的父节点中,一直持续这个过程,直到最后我们到达树的根节点。与我们之前建立的区块链不同,梅克尔树的另一个特点是它可以实现简洁的隶属证明,假设某人想要证明某个数据区块隶属于梅克尔树,我们只要记住树根节点,然后他展示给我们数据块信息,以及从该数据区块通向树根节点的那些区块,我们可以忽略树的其余部分,这样做是因为这些区块已经足够让我们验证通往树根节点过程中所有的哈希值。

数字签名(digital signatures)是密码学中的第二个重要部分,该理论和哈希函数一起,为加密货币奠定了基础。我们对数字签名有两个特性要求,使其与我们对手写签名的预期一致,第一,只有你可以制作你自己的签名,但任何看到它的人都可以验证其有效性;第二,我们希望签名只与某一特定文件发生联系,因此该签名不能用于表明你支持另一份不同的文件。对于手写签名来说,第二条就如同确保别人不能将你的签名从一份文件上剪下来,贴到另一份文件的末尾那样。数字签名方案由三个算法构成:● (sk, pk) :=generateKeys(keysize), generateKeys方法把keysize作为输入,来产生一对公钥和私钥。私钥sk被安全保存,并用来签名一段消息;公钥pk是人人都可以看到的,拿到它就可以用来验证你的签名。● sig:=sign(sk, message) ,签名过程是把一段消息和私钥作为一个输入,输出信息就是签名。● isValid:=verify(pk, message, sig) ,验证过程是通过把一段消息和签名信息与公钥作为输入,如果返回的结果是真,证明签名属实;如果返回的结果为假,证明签名消息为假。

要将算法概念转化为现实中可执行的数字签名机制,我们还需要考虑许多实际问题,例如,很多签名算法是随机的(特别是比特币使用的算法),因此我们需要随机性的良好来源,不良随机性会使你认为安全的算法变得不安全。另一个实际问题是关于信息大小,在实践中,你能够签署的信息大小是有限制的,有一个简单的方法可以解决这个限制:对信息的哈希值进行签署,而非对信息本身进行签署。如果使用输出值为256位的加密哈希函数,那么我们可以有效地签署任何长度的信息。我们可以将信息的哈希值作为信息摘要,哈希函数具有碰撞阻力,因此这种方式是安全的,如果你签署了哈希指针,那么该签名覆盖(或者说保护)整个结构——这不仅仅是哈希指针本身,还包括哈希指针指向的整个区块链,比如,如果签署了区块链末尾的哈希指针,其结果就是你有效地数字签署了整条区块链。

与数字签名并行的一个有用技巧,是从数字签名模式中拿出一个公共验证密钥,并将其与一个人的身份对等。如果你见到一条消息的签名被公钥pk正确验证,那么你可以认为公钥就是代表某一个参与者,从这个角度来说,公钥就是身份。将公钥视为身份的一个结果是,你可以随时制定新的身份——可以简单通过数字签名方案中的generateKeys程序,生成新的密钥对sk和pk,pk是你可以使用的新的公共身份,sk是相应的密钥。你可以不经过中央机构而生成一个身份的概念可能看起来有悖常理,毕竟,如果有人刚好就生成了跟你一样的密钥,他不就能偷走你的比特币吗?我们的回答是,别人生成一个与你的256位密钥相同的概率如此之小,在实践中,我们不需要担心它会发生。

高飞币的规则是:● 高飞可以通过签署声明表示他使用唯一的货币编号来创建一个新币。● 币的所有人可以通过签署声明表示“将这个币转给X”(其中X为公钥),将其转给另一个人。● 任何人都可以验证一只币的有效性,跟随哈希指针追溯到它是由高飞创建,并验证过程中所有签名。当然,高飞币有一个致命安全隐患,假设爱丽丝通过把她签署的声明发送给鲍勃,即将她的币转给鲍勃,但并没有告诉其他人,此时她也可以创建另一个签名,声明将同样一只币转给了查克,对于查克来说,这看起来是一个完全有效的交易。鲍勃和查克似乎都可以有效表示自己是那个币的所有人,这个就是所谓的双重支付(double spending)——爱丽丝将同样一只币花了两次。我们知道货币是不能这样花的,事实上,双重支付是任何加密货币需要解决的主要问题之一,高飞币没有解决这一问题,因此不安全。高飞币很简单,其货币转移机制其实与比特币非常相似,但是因为它并不安全,因此并不适合作为加密货币。

为解决双重支付问题,我们设计另外一个加密货币——财奴币(ScroogeCoin),财奴币是以高飞币为基础创建的,但在数据结构方面更复杂。一个叫财奴的指定实体将负责公布包含所有发生过的交易历史记录的仅增账目(append-only ledger),账目的仅增特性保证了写入这个账目的任何数据都会永久保留下来,为执行这个仅增功能,财奴建立一个区块链,并对区块链进行数字签名,因此就形成了一系列数据块,每个数据块都包含交易ID、交易内容,以及上一个区块的哈希指针,财奴数字签名是针对最后一个哈希指针(它约束整个结构中所有的数据),并将签名与区块链一起发布。现在,我们来看一下财奴币的核心问题,财奴币的工作原理是人们可以看见哪些币是有效的。它可以防止双重支付,因为每个人都可以查看区块链,看到所有交易是否有效,每一只币确实是只被消耗了一次,但其问题是财奴的权利太大了。财奴虽然不能创建虚假交易,因为他无法伪造其他人的签名,但是他可以停止支持其他用户的交易,不为他们提供服务并让他们的货币无处可花。为了改善财奴币,并建立一个可行系统,需要解决的主要技术问题是:我们是否能让系统“去财奴化”?也就是说,我们能否放弃中心化的财奴人物?我们能够有一个在很多方面像财奴币一样运作的加密货币,但没有中央信任机构吗?为回答这些问题,我们需要解决所有用户如何在交易历史记录发生后,一致同意采用一个公开区块链,他们必须一致同意哪些交易有效、哪些交易是实际发生了,最后,新币的铸造也需要通过去中心化的方式进行掌控。如果可以解决所有这些问题,那么我们就创建了一个如同财奴币那样的货币,但是没有中心化的机构管理,这样的一个系统就与比特币非常相像了。

相关推荐