前言
- 对于一个没有密码学经验,大学本科只学过数论的小白来说,想完全理清VRF是一件非常痛苦的事情。
- 因为它不仅涉及到了椭圆曲线,签名算法相关的内容,场景和参与方也都具有相当的复杂性。
- 然而本文要把其中的每一个概念全都理清楚,是对初学者非常友好的一篇博客。
背景要求
- 只需要对区块链有一定的理解即可。
Motivation
- 尽管现在有很多通过可验证随机数技术来解决链上随机数生成的问题,但是在综合不同的应用场景后,可验证随机数的核心能力在于区块链的共识问题。
- 区块链共识解决的核心问题在于解决分叉,如比特币的Pow共识通过计算难题以及认可最长链来规定比特币链中的世界状态;最新的Chia币用Pos(Proof of space)来解决共识问题。
- 但如
Dfinity
或者Algorand
共识就使用VRF作为链共识,其核心在于出现分叉的时候,使用一个可验证随机数作为判断出块的标准。其中Dfinity
还是用BLS门限签名机制,人和人无法预测签名结果,单个人无法阻止签名发布。
Requirement
唯一性
- 对于任何确定的VRF公钥和任何输入M,有一个唯一的VRF输出P。
抗碰撞性
- 无法找到两个不同的VRF输入
M1
和M2
具有相同的VRF散列P。
随机性要求
- 随机性确保当对手验证者看到VRF散列输出R,而没有相应的VRF证明P时,R与随机值无法区分,即R如随机值一样。
- 其实就是说,不能从不同的输入和输出中提取到任何有效的信息,从外部看来,找不到输出证明结果与输入之间的关系。
- 但是值得注意的是,
VRF
的核心在于不可预测性,但是在统计学上的随机性VRF目前没有给出证明。
Terminology
- 这里用于描述下列术语:
- SK: VRF中的私钥
- PK: VRF中的公钥
- alpha: 用于被VRF进行hash的值。
- beta: VRF的hash输出
- pi: VRF的证明
- prover: 证明者拥有着VRF私钥SK和公钥PK。
- Verifier: 验证者拥有公钥。
Process
- 简要的具体流程如下:
- 证明者生成一对秘钥:PK、SK。(注:公钥加密的数据只能由秘钥解密)。
- 证明者计算:
beta = VRF_Hash(SK,alpha);
VRF_hash算法是确定性算法,会对相同的(SK,alpha)产生相同的输出。 - 证明者计算:
pi = VRF_Prove(SK,alpha);
- 证明者把
result
和proof
交给验证者。 - 验证者计算
beta=VRF_proof_to_hash(pi)
是否成立,VRF允许任何人进行验算,注意这一步实际上等于VRF_hash(SK,alpha) = VRF_proof_to_hash(VRF_prove(SK,alpha))
- 证明者把PK, info递交给验证者。
- 验证者计算
True/False = VRF_verify(PK,alpha,pi)
问题1:秘钥和公钥我理解了,但是他们是怎么生成的?
- 在VRF中, 秘钥和公钥可以基于传统的RSA进行生成,RSA是通过大素数乘积易于相乘,难以分解的特性产生的。由RSA生成的VRF称为RSA-FDH-VRF。
- 同样的,还有基于圆锥曲线实现的VRF,被记为ECVRF;基于不同的圆锥曲线可以有不同的算法,例如sm2,secp256k1,爱德华曲线,扭曲爱德华曲线,蒙哥马利曲线和Ed25519。
- 如果你只需要使用,你并不需要了解这方面的细节。
问题2:VRF_Hash函数产生的beta作用是什么?这个hash函数的内容是?alpha使我们自己定义的吗?
VRF_Hash(SK,alpha)
中的(SK,alpha)
即为伪随机数生成器中的种子。beta
即为生成的随机数结果。- 在底层共识设计中,
alpha
将由一些无法预测的值代入,例如上一轮的链上产生的随机数,这样会导致下一轮链的参与者也无法预知自己会产生的随机数。
问题3:我听说Alogrand等公链都在使用可验证随机数的算法,但是当我加入很多节点的时候,我自然就会获得更大的可能性满足下一轮随机数的要求(女巫攻击),这该怎么避免呢?
- 这个会有一套POS的共识机制来限制有资格的参与者。
- algorand 对恶意节点的容忍比例与共识委员会的期望大小有关,委员会期望大小越大,对恶意节点的容忍比例就越高,按照论文的计算,在委员会期望大小为 2000 的时候,能容忍恶意节点持有不超过 20% 的代币。
问题4:VRF_Prove
函数能简要的介绍一下吗?
- 首先,
VRF_Prove
会针对PK和SK的生成方式来给出,例如RSA
对应的即是函数RSAFDHVRF_prove(K, alpha_string)
- 同样的
EC(椭圆曲线)
则会对应ECVRF_prove(SK, alpha_string)
。 - 它会利用
SK
生成一个可以用公钥进行验证的信息,但是不会暴露私钥的信息。 - 具体的数学内容需要仔细研读才能够理解。