区块链技术

PoET 1.0 Specification

2018-08-20  本文已影响365人  Toooooric

简介

时间消逝证明(PoET)共识方法为拜占庭将军问题提供了一种解决方案,该方案利用“可信的执行环境”来提高现有解决方案(如工作证明PoW)的效率.最初发布到Hyperledger的PoET参考实现是为一个抽象的TEE编写的,以保持它对任何TEE实现的灵活性。本规范定义了SGX的具体实现。下面的演示假设使用Intel SGX作为可信的执行环境.

在高层次上,PoET随机选择单个对等节点,以给定的目标速率执行请求。个体节点对指数分布的随机变量进行抽样,然后等待由抽样决定的一段时间。抽样最小的节点赢得选举.通过使用可信的执行环境、身份验证和基于非对称密钥加密的黑名单,以及一组额外的选举策略,可以防止作弊.

为了有效地实现分布式共识,好的抽彩函数具有以下几个特点:

PoET是为实现这些目标而设计的,它使用了在消费者和企业处理器中广泛可用的新的安全CPU指令.PoET使用这些特性来确保领导者选举过程的安全性和随机性,而不需要在大多数“证明”算法中高昂能源花费和专门硬件投资.

Sawtooth包含一个模拟安全指令的实现.这将使社区更容易使用该软件,但同时也放弃了拜占庭式的容错能力.

PoET的基本工作如下:
1.每个验证节点都从enclave(可信函数)请求等待时间.
2.对于特定交易区块,等待时间最短的验证节点被选为leader.
3.一个函数(如“CreateTimer”)为交易区块创建一个计时器,该计时器保证由enclave创建.
4.另一个函数(如“CheckTimer”)验证计时器是由enclave创建的.如果计时器已经过期,该函数将创建一个证明,该证明可用于证实验证节点的确等待了分配的时间后才声明领导者角色.

PoET领导者选举算法符合良好抽彩算法的标准。它将领导者选举随机分布在所有验证节点中,其分布类似于其他彩票算法.选择的概率与所提供的资源成正比(在本例中,资源是具有可信执行环境的通用处理器).执行证明提供了用于验证证书是在enclave中创建的(和验证节点已经等待了分配的时间).此外,较低的参与成本增加了验证节点总数将会很大的可能性,提高了一致性算法的鲁棒性.

定义

以下术语在PoET spec中使用,并在此定义以供参考.

P2P PoET SGX Enclave Specifications

P2P PoET SGX enclave使用如下数据结构:

WaitTimer {
  double requestTime
  double duration
  byte[32] WaitCertId:sub:`n`
  double localMean
}

WaitCertificate {
  WaitTimer waitTimer
  byte[32] nonce
  byte[] blockDigest
}

它使用如下全局变量:

WaitTimer activeWT // 唯一的活动WaitTimer对象
byte[64] PPK
byte[64] PSK
MCID // SGX单调计数器标识符

它导出如下函数:
generateSignUpData(OPKhash)
Returns

byte[64]  PPK
byte[432] report // SGX报告数据结构
byte[256] PSEmanifest
byte[672] sealedSignUpData  // (PPK, PSK, MCID)元组使用Sealkey加密

Parameters

byte[32] OPKhash // OPK的SHA256摘要

描述
1.生成新的ECC密钥对(PPK, PSK)
2.创建单调计数器,并将其标识符保存为MCID
3.使用SGX sgx_seal_data()函数用SealKey(使用MRENCLAVE策略)加密(PPK, PSK, MCID) sealedSignupData=AES-GCM_{SealKey} (PPK | PSK | MCID)
4.创建SGX enclave report,在report_data字段中存储SHA256(OPKhash|PPK)
5.获得SGX PSE清单:PSEManifest
6.保存(PPK, PSK, MCID)作为enclave中的全局变量
7.将active WaitTimer实例activeWT设置为NULL
8.返回(PPK, report, PSEmanifest, sealedSignUpData)


!实现注意
通常情况下,可以创建的单调计数器的数量有上限。处理这种限制的一种方法是销毁以前创建的单调计数器,如果这不是第一次调用generateSignupData函数


unsealSignUpData(sealedSignUpData)
Returns

byte[64]  PPK

Parameters

byte[672] sealedSignUpData // (PPK, PSK, MCID)使用Sealkey加密后的数据 

描述
1.使用sgx_unseal_data()函数用SealKey(使用MRENCLAVE策略)将sealedSignUpData解密为(PPK、PSK、MCID)
2.保存(PPK, PSK, MCID)作为enclave中的全局变量
3.将全局active WaitTimer实例activeWT设置为NULL
4.返回PPK

createWaitTimer(localMean, WaitCertId_n)
Returns

WaitTimer waitTimer
byte[64] signature // waitTimer的ECDSA PSK签名

Parameters

double localMean // 估计本地平均等待时间
byte[32] WaitCertId_n // WaitCertificate拥有者ECDSA的SHA256摘要
                      // signature

描述
1.增加单调计数器MCID,在全局变量计数器中存储值
2.计算tag=AES-CMAC_{PoetSealKey} (WaitCertId_{n})
3.将最低的64位标签转换为双精度数字[0,1]:tagd
4.计算duration=minimumDuration-localMean*log(tagd)
5.设置requestTime等于SGX可信时间值
6.创建WaitTimer对象WaitTimer=WaitTimer(requestTime,duration,WaitCertId_{n},localMean)
7.使用PSK计算waitTimer的ECDSA签名:signature= ECDSA_ {PSK}(waitTimer)
8.设置全局active WaitTimer实例activeWT等于WaitTimer
9.返回(waitTimer,signature)

createWaitCertificate(blockDigest)
Returns

WaitCertificate waitCertificate
byte[64] signature // waitCertificate的ECDSA PSK签名

Parameters

byte[] blockDigest # 使用发起者私钥的ECDSA签名的SHA256
                   # 验证节点想要的交易区块的摘要
                   # 将要提交

描述
1.如果activeWT等于NULL,退出
2.读取单调计数器MCID,并将其值与全局变量值进行比较.如果值不匹配,退出
3.将SGX可信时间读入变量currentTime.如果当前时间小于waitTimer.requestTime + waitTimer.duration,退出(持续时间还没有过)
4.如果当前时间大于waitTimer.requestTime+waitTimer.duration+T_{WT},退出
5.生成随机的nonce
6.创建WaitCertificate对象WaitCertificate=WaitCertificate(waitTimer,nonce,blockDigest)
7.使用PSK计算waitCertificate的ECDSA签名:signature=ECDSA_ {PSK}(waitCertificate)
8.activeWT设置为NULL
9.返回(waitCertificate,signature)

注册阶段

参与者通过下载PoET SGX enclave和区块链的SPID证书作为验证节点进行连接.验证节点的客户端运行以下注册过程:

1.开始PoET SGX enclave: ENC
2.生成注册数据:(PPK,report,PSEmanifest,sealedSignUpData)=ENC.generateSignUpData(OPKhash)
报告体中的report_data(512位)字段包括(OPKhash | PPK)的SHA256摘要
3.询问SGX Quoting Enclave (QE),以获得报告上的可链接引用(使用验证器网络的Basename)
4.如果在IAS API中启用了Self Attestation:请求对可链接引用和PSE清单的认证到IAS.发送给IAS的AEP必须包含:

IAS发回一个签名的AVR,其中包含输入AEP的副本和EPID假名
5.如果IAS API中启用了Self Attestation:向已知参与者广播自验证连接请求(OPK,PPK,AEP,AVR)
6.如果IAS API中没有启用Self Attestation:向已知参与者广播连接请求(OPK, PPK, quote, PSEmanifest)

在参与选举之前,验证节点必须等待c个区块在分布式帐本上发布.

验证节点的服务器端运行以下注册过程:

1.等待连接请求
2.在收到加入请求后,进行验证:

如果连接请求是自验证的(IAS API中启用了自验证):(OPK, PPK, AEP, AVR)
a.使用IAS报告密钥验证AVR的合法性并引用合法性
b.验证引用中的report_data字段包含(OPKhash | PPK)的
SHA256摘要
c.验证AVR中的nonce等于WaitCertId_{n},即最近提交的块的摘要.可能发送方还没有看到WaitCertId_{n},并且可能正在发送WaitCertId_{n'},n'<n.在这种情况下,应该敦促发送方通过附加新的块和重试来更新他/她看到的账本.接收验证节点也可能没有看到WaitCertId_{n},在这种情况下,他/她应该尝试更新他/她看到的账本并再次验证
d.验证引用中的MRENCLAVE值等于PoET_MRENCLAVE(允许存在多个值)
e.验证AVR中的PSE Manifest SHA256摘要等于AEP中PSEmanifest的SHA256摘要
f.验证引用中的basename等于分布式账本basename
g.验证引用中的属性字段具有允许的值(通常情况下,enclave必须处于初始化状态,而不是调试enclave)

如果连接请求没有自我验证(IAS API中没有启用自我验证):(OPK, PPK, quote, PSEmanifest)
a.创建含有引用和PSEmanifest的AEP:
  a.isvEnclaveQuote:base64编码引用
  b.pseManifest:base64编码的pseManifest
b.发送AEP到IAS.IAS发回一个签名的AVR
c.验证收到的AVR证明来确保引用和PSEmanifest的有效性并保存EPID假名
d.验证引用中的report_data字段包含(OPKhash | PPK)的SHA256摘要
e.验证引用中的MRENCLAVE值等于PoET_MRENCLAVE(允许存在多个值)
f.验证引用中的basename等于分布式账本basename
g.验证引用中的属性字段具有允许的值(通常情况下,enclave必须处于初始化状态,而不是调试enclave)

如果验证失败,退出.
如果验证成功,但引用中使用EPID假名标识的SGX平台已经注册,则忽略连接请求,退出.
如果验证成功:
a.将新参与者的注册证书(OPK, EPID 假名, PPK, current WaitCertId_{n})传递给上层,以便在端点注册中心注册
b.转到1

选举阶段

假设最近一个有效块的标识符是WaitCertId_{n}.广播消息由验证节点与其PPK签名.为了参与选举阶段,验证节点在客户端运行以下程序:
1.启动诗PoET SGX enclave: ENC
2.从磁盘读取sealedSignUpData,并将其加载到enclave: ENC.unsealSignUpData(sealedSignUpData)
3.调用(waitTimer,signature)=ENC.createWaitTimer(localMean4,WaitCertId_{n})
4.等待waitTimer.duration秒
5.调用(waitCertificate,signature)=ENC.createWaitCertificate(blockDigest)
6.如果createWaitCertificate()调用成功,广播(waitCertificate, signature, block, OPK, PPK),其中区块是由blockDigest标识的交易区块

在服务器端,验证器等待传入元组(waitCertificate, signature, block, OPK, PPK).当收到时进行以下有效性检查:
1.通过检查端点注册中心来验证PPK和OPK属于注册验证节点
2.使用发送方的PPK验证签名是否有效
3.通过检查端点注册中心来验证发送方提交的PPK少于K个区块(否则发送方需要重新签名)
4.通过与本地计算的localMean进行比较验证waitCertificate.waitTimer.localMean是正确的
5.使用OPK验证waitCertificate.blockDigest是一个有效的ECDSA签名的SHA256块散列
6.根据预期分布验证发送方已经赢得选举的频率(请参阅z-test文档)
7.验证发送方至少在c个提交区块之前注册,即满足c块启动延迟

一个有效的waitCertificate被传递给上层的账本层,拥有最小waitCertificate. waitTimer.duration的waitCertificate决定了选举的获胜者.

撤销

有两种机制可以将EPID Key被IAS撤销的验证节点列入黑名单.第一是验证节点定期地影响每个验证节点,尽管这种影响并不频繁.第二是异步撤销检查,每个验证节点可以在任何时候对其他验证节点的EPID Key执行.

1.周期性再生的PPK
如果验证节点的EPID Key被IAS撤销,那么它将无法获得任何有效的AVR,因此无法注册.强制验证节点定期使用新注册证书重新签名,会使其EPID Key被撤销的验证器退出系统.验证节点必须在提交K块后重新签名,如果没有,则被认为是被撤销的.
2.异步注册引用验证
验证节点可以(在任何时候)要求IAS对另一个验证节点注册的引用进行认证,以检查他/她的EPID Key是否已经被撤销.如果是这样,返回的AVR将指示key被撤销.从IAS获得AVR的验证节点可以在黑名单事务中传播它,以便所有验证节点都可以检查AVR的准确性并继续黑名单.为了限制使用黑名单交易来阻止恶意验证节点的活性,我们可以通过不同方式控制它们提交的速率:

安全考量

1.T_{WT}激励:
验证器最多只有T_{WT}秒来使用WaitTimer,即在WaitTimer本身过期后在其上获得WaitCertificate.强制执行此约束,以避免在一段时间内没有交易构建块的情况下,几个验证节点在等待WaitTimers的持续时间后可能会暂停,并且只在有足够的交易可用时才生成WaitCertificate.这时,他们都将发出他们的等待证书,这会产生大量的流量,可能还会导致分叉.设置timeout缓解了这个问题.

2.Enclave危险:
一个能够任意赢得选举的危险的SGX平台不能影响系统的正确性,但可以通过发布无效交易来阻碍进展.通过限制验证节点(由其PPK确定)在给定时间内赢得选举的频率,可以减轻这个问题(请参阅z-test文档).

3.WaitTimer持续时间操作:
a.在注册后设置c块参与延迟,可以防止验证器生成不同的OPK、PPK对,并选择下一个WaitTimer持续时间的最小值,如下所示:

b.WaitCertificate中的nonce字段被设置为一个随机值,以便验证节点不能控制结果WaitCertId_{n}.在选举中获胜的验证节点可以尝试不同的blockDigest输入值来创建WaitCertificate,并广播WaitCertificate,它的WaitCertId_{n}导致下一个WaitTimer持续时间最小.
c.在选举阶段(客户端)的步骤1中的调用createWaitTimer()由PoET enclave的内部状态绑定到对createWaitCertificate()的后续调用.更准确地说,在调用createWaitCertificate()(并且持续时间已经过去)之后,只允许对createWaitCertificate()进行一次调用,因为全局active WaitTimer对象activeWT的值在createWaitCertificate()的末尾设置为null,以便后续调用失败.因此,只能将一个交易块(由输入参数blockDigest标识)附加到WaitCertificate对象.这可以防止恶意用户在每次不重新创建WaitTimer(并等待其持续时间)的情况下创建多个WaitCertificates(每个waitcertificate都具有不同的nonce),从而产生不同的WaitCertId摘要.因此,只要WaitTimer的持续时间不太小,那么在当前选举中获胜的恶意验证节点对其下一个WaitTimer持续时间的控制就非常有限.
d.对单调计数器值的检查确保只有一个enclave实例在WaitTimer持续时间过期之后能获得WaitCertificate.这再次防止恶意用户运行enclave的多个实例以创建多个WaitCertificates(每个都具有不同的nonce),从而产生不同的WaitCertId摘要并选择一个会导致新WaitTimer持续时间最低的值的证书.
e.在生成PPK和PSK的同时创建一个带有id MCID的单调计数器,并使用带有封印密钥的AES-GCM对三重(MCID、PPK、PSK)进行加密,并保存在永久存储中.恶意验证器不能运行多个enclave实例(在注册之前)来创建多个单调计数器,而最终必须仅使用一个计数器.由于单调计数器与PPK绑定在一起,PSK通过带有封印密钥的AES-GCM加密,当验证器与PPK注册时,它自动提交使用与PPK、PSK一起创建的单调计数器.

4.注册AEP重播:
在AEP中使用nonce字段(设置为WaitCertId_{n})来防止旧AEPs的重播.

对多用户或多账本SGX Enclave服务的注释

通过将用户名和账本名作为输入参数输入到generateSignUpData()unsealSignUpData()中,可以为多个用户或总账使用相同的enclave。然后将注册元组(username, ledgername, PPK, PSK, MCID)密封到磁盘上,并使用用户名和账本名生成文件名.任何时候,只要用户对服务进行身份验证,后者就可以打开enclave并使用对应于该用户(和账本)的文件中的注册元组.

数目规模和局部平均计算

Parameters:
1.targetWaitTime:期望的平均等待时间.这取决于网络直径,并被选择以达最小化碰撞的概率.
2.initialWaitTime:引导阶段使用的初始等待时间,直到账本包含sampleLength块.
3.sampleLength:需要在账本上完成引导阶段并进入稳定阶段的块数.
4.minimumWaitTime:等待时间的下限。

人口规模计算方法如下:
1.sm=0
2.sw=0
3.foreach存储在账本上的等待证书wc
sw=sw+wc.waitTimer.duration-minimumWaitTime
sm=sm+wc.waitTimer.localMean
4.populationSize=sm/sw

假设b是当前存储在账本上的块数,则局部均值计算如下:
1.若b<sampleLength,则r=1.0·b/sampleLength
localMean=targetWaitTime·(1-r^2)+initialWaitTime·r^2
2.否则localMean=targetWaitTime·populationSize

z-test

z检验用于检验验证器以高于预期的平均率赢得选举的假设.
parameters:
1.zmax:测试值,测量与期望平均值的偏差。选择以便获得所需的置信区间\alpha.示例配置是:
a.ztest=1.645<->\alpha=0.05
b.ztest=2.325 ->\alpha=0.01
c.ztest=2.575 ->\alpha=0.005
d.ztest=3.075 ->\alpha=0.001
2.testIdentifier:测试中的验证节点标识符
3.blockArray:一个数组,其中包含验证节点标识和估计的规模大小(id,populationEstimate).每一对代表一个已发布的交易区块
4.minObserved:测试标识符需要观察的最少胜选次数

z-test如下计算:

observed = expected = blockCount = 0
foreach b = (id, populationEstimate) in blockArray:
    blockCount += 1
    expected += 1 / populationEstimate

    if id is equal to testIdentifier:
        observed += 1
        if observed > minObserved and observed > expected:
            p = expected / blockCount
            σ = sqrt(blockCount * p * (1.0 - p))
            z = (observed - expected) / σ
            if z > zmax:
                return False
return True

如果z-test失败(返回False),那么测试中的验证节点将以高于预期的平均率赢得选举.

上一篇 下一篇

猜你喜欢

热点阅读