本文主要介绍了随机数在区块链中的需求及重要性,主要介绍了VRF,Commit Reveal,BLS的原理及应用,之后会继续完善。
依靠随机数来分配社会资源,已经应用到日常生活的方方面面。从幼儿园入学资格、到初高中分配学校、再到买车买房、政府招标,都依赖随机摇号抽签。人的一生,很多重大的选择,其实都是随机数帮助决定的。从经济角度上来讲,随机数广泛应用于密码学、数值计算模拟、统计研究、乐透博彩、游戏抽奖等场合,具有极高的商业价值。
人们为产生随机数,也发明了掷骰子,转转盘,抛硬币等统计方法,通过计算机生成伪随机数,利用量子力学原理获取随机数等。这些方法虽然很好的解决了随机数的随机性、不可控制性、不可预测性等方面的问题,但是却缺乏去中心性与可证公平性。
自然地,人们希望找到一种更公平的随机数生成和发布机制。而区块链作为一个去中心化的平台,为可证公平的随机数生成提供了天然的基础。
但是在公有区块链上设计一个可用的随机数发生器难度更大。除了基本的随机数统计学要求外,公有链上一个可用的随机数发生器至少要满足无法预测,不可操控,难以串谋,可证公平,可审计这几个特点。
因此,如何在区块链上设计并实现可证公平的随机数发生器成为近年来一个重要的研究问题。自从Randao 团队在2015 年提出使用Commit Reveal 方案后,又分别有Vitalik Buterin 提出的Randao++ 方案、部分DApps 使用Oraclize 从链下服务获取随机数的方案,来实现区块链随机数生成。
伪随机数一般由确定的算法生成的,其分布函数与相关性均能通过统计测试。但与真随机数相比,它们由算法生成,而不是一个真实的随机过程。伪随机数也只是尽可能地接近其应具有的随机性,但是因为有“种子值”,所以伪随机数在一定程度上是可控可预测的。伪随机数可使用取中法、同余法、移位法、梅森旋转算法等方式产生。
真随机数的产生不可预计,也不可能重复产生两个相同的真随机数序列。真随机数一般使用物理现象产生,比如掷钱币、掷骰子、晃动鼠标、转转轮、使用电子元件的噪音、使用大气噪声、核裂变等。真随机数发生器的技术要求一般比较高,生产效率一般比伪随机数低。另外, 如果信息熵的信息量很有限,不一定能产生真随机数。真随机可以进一步区分为统计意义上的随机以及量子效应上的随机。一般认为,由于量子力学内在的随机性,其产生的随机数比传统物理学通过统计产生的随机数更“真”。
Linux内核提供了统计方式的真随机数生成器。它利用机器的噪音生成随机数,噪音源包括各种硬件运行时速,用户和计算机交互时速,比如击键的间隔时间、鼠标移动速度、特定中断的时间间隔和块IO请求的响应时间等。random利用大气噪音生成真随机数并对外提供。另外,通过监听真空内亚原子粒子量子涨落产生的噪音,澳大利亚国立大学的科学家们建造了随机数发生器并提供给互联网用户。
量子现象利用了在原子尺度下粒子的行为具有随机性,而且其本质还未被人类发现,因此可以将其看做一个具有良好不确定性的熵源;混沌现象是指在混沌系统中, 初始量的微小差异会导致未来的发展截然不同,因此除非获得初始时刻的全部准确信息,则无法预测未来的发展趋势(eg. random)。
中心化随机数发生器
Bitcoin Beacon
斯坦福和普林斯顿的Bonneau&Goldfeder 等于2015年提出可将比特币的区块数据作为一个不依赖第三方的公开随机源,并分析了区块头所包含的熵,以及根据该熵所生成的随机数的安全性。
用比特币区块数据生成随机数的问题在于,其通用安全性不够高,无法防止“块保留攻击(Block Withholding Attacks)”,即参与者可以贿赂矿工丢弃不利于自己的区块,从而在博彩类的应用中获得相对优势。比特币单个区块的奖励是固定的,因此,所有依赖于该方法获得的随机数有一个固定的安全上限,不能根据应用的具体情况动态调整,导致其适用性有很大的限制。此外,Bitcoin Beacon 方案中,普通用户无法参与区块的生成,虽然串谋的成本较高,但矿工并不能避免嫌疑。因此该方案仍然不是一个可证公平的随机数方案。
采用Verifiable Random Functions(VRF)选择出块人,委员会成员及解决分叉。
VRF的流程和特点:考虑如下情形:有一个公共的难以找到原象的函数F
,现在Bob给出一条信息x
,要求Alice用她的秘钥s
计算出F(s, x) = v
作为一个随机数输出,因为s
对公众不可见,所以Bob收到v
难以判断这个v
是否是Alice诚实计算F(s, x)
得出的。VRF实现了:让Alice在给出v
的同时也给出一个proof
和一个对应s
的公钥p
,Bob可以用p
和proof
来验证v
是否是F(s, x)
。
VRF的签发是由一个参与者完成的,因此该参与者可以选择不发布对自己不利的签名,和Bitcoin Beacon有相似的缺点,因此不适合用来作为可证公平的随机数发生器。
Dfinity的共识算法建立在随机数的基础上,通过BLS签名算法实现随机数的生成,由一组人产生签名,任何个人都无法预测签名结果,单个人无法阻止签名发布。
BLS 是一种门限签名技术。首先将用户分组,第一轮由一个组产生一个随机数, 之后每一轮选一个组对上一轮产生的随机数签名,作为这一轮的随机数输出,每个成员都无法提前预知签名结果。其中签名过程使用BLS 签名机制,保证在签名过程中没有个体能够提前预知签名结果,因此无法操纵随机数。
BLS 很好的解决了Withholding 攻击的问题,且生成随机数过程不可操纵,无法预测,很难串谋,是一个比较理想的随机数生成方案。
DAO是一种无中心的组织结构,组织规则由代码描述并强制执行,任何人可自由加入退出,不同参与者间地位平等,刚好可以满足我们对于公共随机数的设计目标。因此区块链技术以及DAO理论,可以用来支撑并指导公共随机数的设计和实现。
在区块链场景中,有的框架会用算法随机产生出块节点与验证节点(如Algorand),甚至解决分叉。按传统的随机算法,按一定的哈希规则随机轮询,选出一个节点来记账/验证。如果这个随机轮询的规则是谁都可以复现的,那么可以推测出将来的某个记账/验证节点,集中攻击它。
为了解决这个问题,就引入了VRF,只有自己能够完成这个哈希过程,而别人只能在他声明之后验证这个过程,防止有人可以提前推测出将来的记账节点。
在任何基于区块链的权益证明算法中,都需要某种机制,来随机从当前活跃验证者集合中选择能够产生下一个区块的验证者。举个例子,如果当前活跃的验证者集合由持有40以太币的Alice,持有30以太币的Bob,持有20以太币的Charlie与持有10以太币的David组成,那么你想让Alice成为下一个区块的创建者的概率为40%,而Bob的概率为30%等(在实践中,不仅要随机选择一个验证者,而是要(随机产生)一个无限验证者序列,只有这样如果Alice不在线的时候,就可以有其他人在过段时间替代她,但是这并没有改变问题的本质)。在非基于区块链的算法中,出于不同的原因也经常需要考虑随机性。
——以太坊Github《Proof of Stake FAQ》
基于PoS的区块链协议最基本的一个问题就是模拟领导者选举过程。为了在股东们之间的选举达到一个真正的随机性,系统中就必须要引入熵(entropy),但引入熵的机制可能会容易被敌手操作。例如,一个控制一群股东的敌手可能会试图模拟协议的执行,尝试不同的股东参与者的顺序以此来找到对敌对股东有力的继续者。这会导致一个叫做"grinding"的致命弱点,敌对参与者可能会使用计算资源来倾斜领导者选举。
——Ouroboros白皮书《Ouroboros: A Provably Secure Proof-of-Stake Blockchain Protocol》
2. VRF是什么?
VRF是可验证随机函数(verifiable random function),一方面具有伪随机性,另一方面它还具有可验证性(输出包括一个非交互零知识证明)
VRF 的方式是,实现本地抽签,各个节点自己抽签,如果抽中了之后,大家可以很容易地验证这个结果确实是你生成的。
eg. 假设现在是round 10(第10 轮),节点们可能会轮流抽签,以节点自己的私钥+ 一个全网都知道的随机数(比如是这轮的轮次10)作为输入,生成了一个随机数(0-100);设置一个条件:100 个节点轮流抽签,谁先抽出来的随机数大于10,就是这一轮的打包者。假设5 号节点抽到了11,可是只有5 号知道其他人不知道,因此他在广播这个随机的同时还需要广播一个零知识证明。通过零知识证明,全网只需要通过5 号的公钥就可以验证,接受5 号为这轮打包者。图解如下:
True表示验证通过,False表示验证未通过。所谓的验证通过,就是指proof是否是通过info生成的,通过proof是否可以计算出result,从而推导出info和result是否对应匹配、证明者给出的材料是否有问题。
Consensus:共识算法中安全性
VRF Sortition,Smart Contracts, 例如本体,Cardano,Dfinity,Algorand等,不同点在于如何产生输入以及输出怎样用。VRF的返回结果可以用来公开或私密地完成节点或节点群体的选择。eg. Dfinity利用mod操作来唯一,公开的确定一个group。Algorand,Ouroboros Praos是私密选择,即计算出哈希值后,如果哈希值小于某个阈值,节点可以私密地知道自己被选中。
本体-VBFT共识算法:
Algorand中:
Dfinity中:
交保证金提高门槛,并降低参与节点的数量,然后选打包者,选完打包者选公证人,对区块权重进行排序,选出区块。
Cardano的共识机制-Ouroboros Praos:
IOST的高效分布式分配片
使用了VRF来进行领头节点的选举,通过VRF得到随机数之后,会将结果进行广播,然后其他节点会进行统计,得到随机数值最小的作为分片领头节点。是一种交互式的选举方式。
Key Transparency
密钥管理系统,使消息传递在不相信服务端的情况下做到点对点的安全上的提升。
DNSSEC
DNS服务的安全性。
Commit Reveal 是一种在规定时间内可以有多人一起参与产生随机数的流程。
sha3(s)
所有希望参与随机数生成的生产者,在指定的时间窗口期内(例如以太坊的6个出块周期,大约72秒),向合约C发送m
个以太的保证金,同时附上其任意挑选的数字s
的sha3(s)
。
s
之前成功提交sha3(s)
的所有生产者,在第一阶段结束后,在第二阶段指定的时间窗口期内,向合约C发送各自在第一阶段选中的数字s
。合约C
检查数字s
是否合格的。如果合格,保存该s
到最终随机数生成函数的seeds
中。
全部的s_i
收集完成后,以f(s_1, s_2, ..., s_n)
作为最终的随机数,把随机数写入到C
的存储空间中,向所有请求该随机数的其他合约返回结果。把生产者在第一阶段发送的保证金退还,同时把本期随机数生成过程中,其他合约支付给C
的手续费作为奖励发送给本期的所有生产者。
方案约束:为了保证随机数结果不被操纵,兼顾安全和效率,合约C
有如下这些额外规则约束:
第一阶段中,如果先后有两个同样的sha3(s)
被提交,只接受第一个。
第一阶段中,有一个最小参与人数的设定,如果在窗口期时间内未能达到预设人数,则本期随机数构造失败。
如果提交的sha3(s)
结果被合约C
接受,则在第二阶段必须提交s
。
(a)如果在第二阶段的窗口期中某个参与者没能提交s
的话,则在第一阶段中发送的m
个以太会被没收,不再返还。
(b)如果在第二阶段未能收集到全部的s
,则本期随机数生成失败,退还其他合约支付的手续费后,将本期收集的保证金分发给在第二阶段成功发送s
的其它生产者。
Rando,低频率、高中奖额博彩(如乐透摇奖)
BLS 是一种多人蔘与生成随机数的方式,其目标是给消费者在可证公平的前提下以一种更高效的方式来提供随机数。
首先BLS 生成随机数涉及分组和初始化。分组就是把所有参与人随机分成M 组,每组N 人。初始化是分组结束后根据BLS 的签名机制为每个组员生成自己的私钥以及全组的公钥P。为了提高效率分组为线下完成,且分组结果会运行一段时间,然后定期重新分组,以保证公平性。
(1)思想:N
个成员组成一个组,一个组有一个逻辑上的私钥S
(使用S对消息签名的结果记为SIG
,S
对应公钥记为P
),而每个成员i
只拥有这个秘钥的一部分s_i
,完整的秘钥S
不存在于任何人手中,没人能直接计算出SIG
。签名时,每个人用自己的秘钥s_i
对一个信息签名得到sig_i
,只有收集了k
个(某个预先设定的值)成员的签名,才能够计算出签名SIG
。
(2)特点:秘钥由全网共同决定,无法预知,无法操控。
(3)初始化:要让BLS签名机制运行起来,需要一次初始化,生成成员的私钥和全组公钥。
i
生成自己的随机数组ran_i
(对其他人保密,包括同组成员)。f
计算出send_{ij} = f(ran_i , j)
,通过私密通道发送send_{ij}
给成员j
(对不同的j
,send_{ij}
不同;f
有单向性,用send_{ij}
和j
无法得到rani
)。对所有j(= 1, 2, ..., N)
,成员i
要对成员j
发送send_{ij}
(对于i = j
,则计算出send_{ii}
记录在本地)。j
收集数据send_{1j} , send_{2j} , ..., send_{Nj}
,用(BLS签名机制给出的)函数v
验证send_{ij} (i = 1, 2, ..., N)
的合法性(v(send_{ij} ) = 1
则合法,v(send_{ij}) = 0
则非法)。s_j
,s_j
对应的公钥pub_j
,和S
对应的公钥P
。pub_j
以及P
广播。(4)执行步骤:
i
用秘钥s_i
对消息M
签名得到sig_i
并广播sig_i
。j
收集其他成员广播的sig_i
,并用pub_i
验证,通过验证通过则作为有效签名接受。当收集到k
个有效签名(包括自己的签名sig_j
),则计算出最终签名SIG
并广播SIG
。
(1)思想:将全网分为h
个组,第一组生成一个随机数SIG_1
,使用SIG_1
选取下一个组,被选中的组签名这个随机数得到SIG_2
,使用SIG_2
选取下一个组,再对SIG_2
签名得到SIG_3
。如此重复,过程中已经参与过随机数生成的组不再参与随机数生成,直到第h
个组生成SIG_h
作为最终的随机数输出。
(2)具体流程:
h
个组G = g_1, g_2, ..., g_h
g_1
生成一个随机数SIG_1
并广播,将g_1
从G
中剔除。i = 2, 3, ..., h
,执行:取g_{work} = G (sig_{i−1}mod|G|)
,将g_{work}
从G
中剔除,g_{work}
对SIG_{i−1}
签名得到SIG_i
并广播。SIG_h
为最后输出的随机数。这个过程保证每一步的签名都是一个随机数,每个组都无法预测后续组的签名结果。只有最后一个组有操纵SIG_h
的优势,当最后一个组有不超过k
个非法成员,则SIG_h
是安全的,但是无法预测哪个组会担任SIG_h
的生成任务。
(1)安全性考虑
签名初始化时:若k
个成员串通,使用BLS签名机制生成这k
个人的秘钥并共享,独占这一组的签名权。
签名执行第二步:如果一个成员收集了k − 1
个其他成员的签名,并与自己的(还未广播的)签名组合计算出SIG
,发现SIG
对自己不利,则可以选择不广播自己的签名。如果因此造成全网只有k−1
个成员签名被广播,则签名会失败。当全网有多于N−k
个成员可能做出此行为,则这个情况有发生的可能性。
假设当k < N/2
,若全网有k
个成员对一个并非全网大多数成员同意的消息进行签名,则这k
个成员能够“伪造”集体意愿。
如果生成的随机数与全网大多数成员有直接的利益关系,那么在生成随机数的最后一步,很可能有超过一半的成员拒绝给出正确的签名SIG_h
使得随机数生成失败。
综合1 , 2 , 3点,BLS系统可以抵御max(k −1, N −k)
个非法成员。在DFINITY中,N = 400, k = 201
,当某个组内超过一半成员为非法成员,才会出现签名失败或伪造签名的情况。事实上BLS签名方法在将全网节点分组时使用VRF进行随机分组,在这个过程没有作弊的前提下能提供较高的容错率:以全网有10, 000用户为例,当3, 000人为恶意用户时,分组时某一组会有超过一半恶意节点的概率不足1e ^{−17}
,4000人为恶意用户时,这一概率为1^{e −5}
,而且概率会随着N
提高(k = N/2 + 1)
而进一步降低,但是无论N
取到多高,都无法做到50%容错,当恶意用户上升到50%左右时,上述概率会急速上升到50%附近。因此可知这一随机数生成机制并不适合用于与全网利益直接相关的问题之中,而对于只与全网部分节点(< 50%)利益相关的问题中,上述4个问题发生的可能性很低。
(2)安全策略
(3)方案评价
生成的过程在链外组织,响应速度快,通常只需要一个区块的时间就能生成随机数;消费者发起随机数生成请求,生产者在下一个块写入随机数,只需要发送两次交易就可以完成随机数的生成和调用,生产和使用成本都很低,适合用于高频,同时对于防串谋的需求不那么苛刻的场景。
Rando,Dfinity,高频率、 中低中奖额抽奖(如快速抽签)