3. 复制证明与时空证明
在Filecoin协议中,存储供应商必须让客户相信,他们的数据已经被完好存储。在实际操作中,存储供应商会生成存储证明(Proofs-of-Storage,POS)给区块链网络(或客户本身)进行验证。
本节中,我们将展示和概括在Filecoin中所使用的复制证明(Proof-of-Replication,PoRep)和时空证明(Proof-of-Spacetime,PoSt)实现方案。
3.1 动机
存储证明(POS)方案,例如可证明数据拥有(PDP)以及可恢复性证明(PoR)方案,它允许用户(即审核人V)将数据外包给服务器(既证明人P)以检查服务器是否依然存储数据D。用户可以用比下载数据还便捷的方式,来验证外包给服务器数据的完整性。服务器通过对一组区块进行随机采样和传送少量数据,来生成概率性的拥有证明,以此作为给用户的怀疑/响应协议。
PDP和PoR方案只允许证明人在怀疑/响应的时候拥有某些数据。在Filecoin中,我们需要更强大的保障,来阻止恶意矿工通过攻击获得不应得的奖励。常见的三种攻击类型有:女巫攻击(Sybil attack)、外包攻击(outsourcing attacks)、生成攻击(generation attacks)。
3.2 复制证明
复制证明(PoRep)是一个新型的存储证明,它允许服务器(证明人P)向用户(审核人V)证明:数据D已被复制到它专有的物理存储上了。我们的方案是一种交互式协议,证明人P:(a)承诺存储数据D的n个不同的拷贝(独立物理拷贝),然后(b)通过怀疑/响应协议来使审核人V相信P确实已经存储了每个拷贝。我们目前已经知道,PoRep在PDP和PoR方案中,阻止女巫攻击、外包攻击、生成攻击的能力会有所提高。
注意,想要PoRep正式的定义,以及了解它的属性和深入研究的,我们推荐参考[5]
【定义六】 PoRep方案允许有效的证明人P来说服审核人V:数据D的独立物理副本R已被p存储。PoRep协议是多项式时间算法的元组:
(Setup, Prove, Verify)
- Setup(1λ, D) → R, SP , SV, 其中SP和SV是为方案专门设定的P和V变量,λ是一个安全参数。PoRep.Setup用来生成副本R,以及给予P和V必要的信息来运行PoRep.Prove 和 PoRep.Verify。一些方案可能会要求证明人或者第三方交互来运算PoRep.Setup。
- Prove(SP, R, c) → πc,其中c是审核人V发出的随机质疑, πc是证明人产生的访问R的证明,R是D的特定副本。PoRep.Prove由P运行,为V生成πc。
- Verify(Sv, c, πc)→ {0, 1},用来检测证明是否正确。PoRep.Verify由V运行,并使V相信P已经存储了R。
3.3 时空证明
存储证明方案允许用户检查存储提供商当时是否存储了外包数据。我们如何使用PoS方案来证明在一段时间内数据被存储了?一个非常自然的答案是要求用户重复(例如,每分钟)对存储提供商发送请求。然而这样的交互所需要的通信复杂度会成为一些系统的瓶颈。像Filecoin这样,存储提供商会被要求提交证明到区块链网络。
为了解决这个问题,我们介绍一个新的证明,时空证明(Proof-of-Spacetime),它可以让审核人检查存储提供商是否在一段时间内存储了他的外包数据。这就对证明人产生了直观的要求:(1)生成连续的存储证明(在本文中是“复制证明”)来作为确定时间的一种方法。(2)递归执行来生成简单的证明。
【定义七】 (时空证明)Post方案可使有效的证明人P能够说服一个审核人V相信P在一段时间内存储了数据D。PoSt是多项式时间算法的元组:
(Setup, Prove, Verify)
- Setup(1λ, D) → R, SP , SV, 其中SP和SV是为方案专门设定的P和V变量,λ是一个安全参数。PoRep.Setup用来生成副本R,以及给予P和V必要的信息来运行PoRep.Prove 和 PoRep.Verify。一些方案可能会要求证明人或者第三方交互来运算PoRep.Setup。
- Prove(SP, R, c) → πc,其中c是审核人V发出的随机质疑, πc是证明人产生的访问R的证明,R是D的特定副本。PoRep.Prove由P运行,为V生成πc。
- Verify(Sv, c, πc)→ {0, 1},用来检测证明是否正确。PoRep.Verify由V运行,并使V相信P已经存储了R。
3.4 PoRep和PoSt实际应用
我们对PoRep和PoSt在现有系统上的应用很感兴趣,希望能构建一个实用性系统,但不依赖任何的中心式第三方或者硬件。我们给出了一个PoRep架构(见“密封的复制证明”[5]),它需要在Setup过程中执行缓慢的顺序计算密封来生成副本。PoRep和PoSt的协议草图详见图4,Post证明步骤的底层机制的见图3。
3.4.1 构建加密区块
防碰撞散列。我们使用一个防碰撞散列函数:CRH : {0, 1}* → {0, 1}O(λ)。以及另一个一个防碰撞散列函数MerkleCRH,它可以将字符串分割成多个部分,构造二叉树并将递归应用到CRH,最后输出根。
zk-SNARKs。我们对PoRep和PoSt的实现依赖于零知识的简洁非交互式知识论(zero-knowledge Succinct Noninteractive ARguments of Knowledge,zk-SNARKs)[6,7,8]。因为zk-SNARKs非常简洁,证明短并且容易验证。形式上来说,就是让L作为NP语言,并用C做为L的判决电路。中心式信任方执行一次设置会产生两个公共密钥:证明密钥pk和验证密钥vk。证明密钥pk可使任何(非信任的)的证明人都能生成证明π来证明x∈L,x是任一实例。非交互式证明π是零知识的,也是知识证明的。任何人都可以使用验证密钥vk来验证π证明。尤其zk-SNARK的证明是可公开验证的:任何人都可以验证π,而不需要与生成π的证明者进行交互。π证明具有恒定的大小,并且可以在| x |的线性时间内得到及时验证。
zk-SNARKs是一个三项式时间算法:
(KeyGen, Prove, Verify)
- KeyGen(1λ,C)→(pk, vk)。输入安全参数为λ,回路为C,pk和vk是KeyGen的概率样本。这两个密匙是公共参数,可用于证明/审核Lc上的成员。
- Prove(pk, x, w)→π。在输入pk、输入x并看到NP声明w后,如果x∈LC,证明人Prove会输出非交互式证明π。
- Verify(vk, x,π)→{0, 1}。当输入vk,x和证明 π,如果有x∈LC,审核人verifier输出1。
建议有兴趣的读者阅读[6,7,8],那里有对zk-SNARK系统的概念和实现更详细的介绍。通常来说系统会要求KeyGen是由中心式可信任参与方来运行的。新型可扩展计算的完整性和隐私性(SCIP)系统[9]展示了一个很有前景的、可以避免这个步骤的发展方向,才有了上面的信任假设。
3.4.2 密封操作
密封操作的作用是:(1)通过要求证明人存储公钥下数据D的伪随机序列,强制副本成为成为相互独立的拷贝,这样提交n个副本后就会产生n个独立的磁盘空间(并占用副本大小n倍的储存空间)。(2)在运行PoRep.Setup的时候强制生成副本,实质上会比预估的质疑响应花费更多的时间。有关密封操作的更正式定义,请参见[5]。上述的操作可以用SealτAES?256实现,SealτAES?256中的τ需要比常规的“质疑-证明-审核”序列多花费10-100倍的时间。所以对τ的选择非常重要的,因为运行SealτBC可能比证明人随机访问R要花费更多时间。
3.4.3 PoRep构建实践
本节将描述PoRep协议的组成,并在图4展示简化的协议草图。我们略过了具体实现方法和优化细节。
创建副本。Setup算法通过密封操作,和正确生成副本的证明,来实现副本的生成。证明人生成副本,并将输出(不包括R)发送给审核人。
证明存储。Prove算法生成副本存储的证明。证明人收到来自审核人的随机质疑c。该审核人在树根为rt的Merkle树R中确定叶子节点Rc。证明人生成关于Rc,和其延伸到叶子Rc的Merkle路径的知识证明。
审核证明。考虑到副本的Merkle树根,和原始数据的散列,Verify算法会审核存储证明的有效性。证明是公开可验证的:分布式系统的节点保持了账本和客户对特定数据的关注,这样就能验证这些证明。
3.4.4 PoSt构建实践
本节将描述Post协议架构,并在图4中给出一个简单协议草图。本节忽略实现过程和优化细节。Setup和Verify算法和前文的PoRep架构相同,所以这里只描述Prove。
证明时空。Prove算法为副本生成时空证明。证明人接收来自于审核人的随机质疑,并顺序生成复制证明,证明输出后,经过特定次数的迭代t,可作为其他的输入(见图3)。
Figure 3: Illustration of the underlying mechanism of PoSt.Prove showing the iterative proof to demonstrate storage over time.
3.5 在Filecoin中的应用
Filecoin协议采用时空证明来审核矿工提供的存储。因为没有指定的审核人,并且我们希望网络中的任何成员都有审核权,所以为了在Filecoin中使用PoSt,我们把方案改为了非交互式的。我们的审核人在公开的代币模型中运行,所以我们可以从区块链中随机地发出质疑。