比特币中的密码学知识-哈希函数篇

Hash & Digital Signature

Posted by AlbertWu on January 17, 2018

最近重读了《区块链-技术驱动金融》这本书,借此机会想来谈谈对于比特币中运用到的密码学知识做一个记录和分享。

为了避免所谓的通货膨胀,每种货币在发行时都会控制供给量,并且需要设立安全机制避免欺骗行为的发生。就实体货币,也就是法定货币而言,货币的发行由类似央行这样的机构控制,并且通过加上防伪标识提升货币安全性。但是没有密不透风的墙,货币并非不可伪造对吧。

对于Bitcoin此类加密数字货币的发行在最初就设定为2100万枚,从2009年创世区块的诞生,每个区块产生50个新的比特币,大约每四年减半,经历33个四年后不再产生新的比特币。而其安全性,则有密码学提供,在比特币的安全机制设立中只用到了少量理论知识在本篇文章中主要介绍哈希算法(Hash)及数字签名(Digital Signature)技术。

哈希函数

在这一部分,我主要会聊到哈希函数的几大特性,之后谈下SHA-256的实现,最后谈下哈希指针在区块链中的应用。

哈希函数是一个数学函数,拥有以下三个基本特性:

  • 输入为任意大小的字符串
  • 产生固定大小的输出
  • 能进行有效运算,即在合理的时间内可以算出哈希函数的输出。准确说,对于n位字符串,其哈希计算的复杂度为O(n)。

加密的哈希函数的三个附加特性:

首先先对哈希函数的三个附加特性做一些详细说明。

碰撞阻力 (Collision-resistance)

简单点理解,碰撞阻力越大就是指在一定时间内无法找到两个不同输入拥有同一个输出,反之可以找到。一个安全的哈希函数要保证在一个很长的时间内无法找到两个不同的输入拥有同一个输出。在这里,一个很长的时间可以理解为穷尽世界所有计算机的算力也要算到世界毁灭这种时间长度。常见的加密哈希函数有MD5 (已被淘汰), SHA-1, SHA-2, SHA-256等。

值得注意的是世界上没有任何一个哈希函数具有防碰撞特性,因为哈希函数的基本特性保证了输入空间远远大于输出空间,所以根据抽屉原理必定会产生碰撞,只不过有些阻力大,有些阻力小罢了。

  • 应用:信息摘要 (message digest)

假定哈希函数H具有碰撞特性,x和y是两个不同输入,那么同时可以假定H(x)和H(y)也不同。

假定Alice上传了很大的文件,并且希望在之后下载是确认和她上传的文件完全一致,Alice仅需比较上传文件的哈希值和下载文件的哈希值保持相同即可。因为一旦文件在传输过程或者云端存储过程中受到恶意修改,那么文件的哈希值必然改变,则会导致上传文件与下载文件的哈希值不相同。

隐蔽性 (Hiding)

简单点理解就是不能在已知哈希函数输出y=H(x)的情况下,通过可行的计算得到输入值x。其应用于数字签名很像,在下一章节关于数字签名的介绍中会提到。

谜题友好 (Puzzle-friendliness)

假定一个哈希函数具备谜题友好特性,这就意味着对于这个谜题没有一个解决策略,比只是随机地尝试输入更好。

安全哈希算法

安全哈希算法 (Secure Hash Algorithm 256)。其核心思想是将一个源文件切成n个512比特的信息区块 (不足512比特则补零),然后通过update函数将一个256比特和512比特的值作为输入,输出一个256位比特的值,经过n次update运算则将源文件进行加密哈希运算,生成256比特的final值,工作过程可见下图说明。其中init值由官方文档给出,是确定的。

alt text

在此处涉及到将接受固定长度的哈希函数update转化为可接受任意长度输入的哈希函数,我们称这个转换过程为MD变换 (Merkle-Damgard Transform)

哈希指针及数据结构

哈希指针就是一个纸箱数据存储位置及其位置数据哈希值的指针,可以用下图来表示

alt text

区块链则是使用了哈希指针构建的一个链表。在区块链中,每一个区块不但包含了该区块的数据还包含了一个哈希指针,告诉我们上一个区块的值和该值的哈希值,可以用下图来表示。

alt text

有个小故事就是创世块留言这是广为流传的中本聪在创世块的coinbase写下“The Times 03/Jan/2009 Chancellor on brink of second bailout for banks” 这句话正是泰晤士报当天的头版文章标题。

那么区块链通过哈希指针的形式构造出来有什么好处呢?,最明显的应用就是“防篡改日志”。也就是说我们要建立一个存储很多数据的日志数据结构,使我们能将数据附加到日志的末尾。但是如果有人篡改日志前面的数据,我们可以检测到。

  • 区块链如何实现防篡改特性

假设黑客想要篡改第k个区块链的交易,会导致第k+1个块的H(k)错了,所以为了掩饰,还要修改k+1块的值,如此下去,会一直延续到最近的块,也就是链表的头部,也就是图中最右边的那个H( ),只要我们将链表的头部保存在对手无法改动的地方,那么这个策略必定失败。所以哈希指针技术保证了区块链交易历史的安全性。下图可能会帮助你理解。

alt text


Creative Commons License
This work is licensed under a CC A-S 4.0 International License.