BTCV繁华资讯 > 货币新闻 > 以太网2.0的洗牌算法_btcv-繁华资讯

以太网2.0的洗牌算法_btcv-繁华资讯

作者:_btcv-繁华资讯来源:_btcv-繁华资讯 货币新闻 2020年09月19日

如果你想学沙狐舞,那你就错了。但是相信我,Eth2中的洗牌同样令人兴奋。洗牌列表是以太网2.0中的一个基本操作。它主要用于在每12秒的时隙中伪随机地选择验证者以形成一个委员会,并且在每

简介

想学推诿舞,就走错地方了。但是相信我,Eth2中的洗牌同样令人兴奋。

混洗列表是以太坊2.0里一个基本运算。它主要用于在每12秒的slot里伪随机挑选验证者来组成委员会,以及在每个slot里选出信标链区块的提议者。

混合似乎很简单。虽然它有一些需要注意的隐患,但这些隐患在计算机科学中很容易理解。金本位大概就是费雪-叶芝洗牌。那我们为什么不用在Eth2里呢?我会在文末详细说明,但简单说就是——轻客户端。

我们用的混洗算法是swap-or-not,而不是Fisher-Yateshttp://www . sogou.com的选择就是基于这个原本用来构造加密方案的论文。我最近在Eth2客户端库特重写了我们的实现,所以我想趁热把它写出来。

Swap-or-Not混洗算法

一轮的操作过程每一轮的流程都是一样的,下面我只演示一轮的流程,比看起来简单多了。

混洗以轮次进行。

首先我们选择一个轴指数P,基于轮次等种子数据,伪随机选择。选中此轴后,此轮固定。

基于该枢轴点,我们在p和0之间的中间点选择镜像索引m1,即m1=p/2。(为了方便解释,我们就忽略麻烦的舍入问题。(

以太坊2.0的混洗算法

轴点和第一个镜像索引

选择一个轴心点并找出第一个镜像索引

对于镜像索引m1和枢轴索引p之间的每个索引,我们随机决定是否替换这些元素。

例如,对于索引i1,如果我们选择不替换它,那么我们将继续选择下一个索引。

如果我们决定替换,那么我们将用i1’上的列表元素替换i1’上的列表元素,也就是它在镜像索引上的图像。也就是说,i1和i1’=m1-(i1-m1)被替换,使得从i1和i1’到m1的距离相等。

我们对m1和p之间的每个指数做出相同的交换或不交换的决定。

以太坊2.0的混洗算法

从第一个镜像索引到轴的交换或不交换决定

从第一个镜像索引到轴心点,替换与否

在作出从m1到p的所有索引决定之后,我们现在找到以m2为中点的第二个镜像索引,即从p到列表末尾具有相同距离的点。即m2=m1 n/2。

以太坊2.0的混洗算法

第二镜像索引

计算第二个镜像索引

最后,我们重复交换或不交换的过程,考虑从所有点到轴的P替换的决定,即P到第二反射镜m2的决定。如果我们选择不替换,继续下一个。如果我们选择替换,那么我们用镜像索引m2上j1’上的镜像替换J1上的元素。

以太坊2.0的混洗算法

从轴到第二镜像索引的交换或不交换决策

从轴心点到第二个镜像,替换与否

在这轮结束时,我们考虑了m1和m2之间的所有指数,即所有指数的一半,每一个指数在另一半都有一个特定的指数,无论它是否被替换。所以所有索引都考虑过一次是否替换。

下一轮从增加(或减少)轮次开始,这样我们就会有一个新的轴指数,然后开始循环上述过程。

以太坊2.0的混洗算法

在同一轮中从一面镜子移到另一面镜子的过程

组合起来

有趣之处

在决定是否替换时,该算法会巧妙地选择较高的候选索引或其镜像。这意味着当i_1位于轴下方时,选择I _ 1而不是I _ 1’。当I_k位于轴上方时,将选择i_k '而不是I _ k。这意味着我们可以灵活地遍历列表中的索引:我们可以将0到m1和P到m2分成两个独立的循环,或者将它们组合在同一个从m1到m2的循环中,就像我上面描述的那样(并且实现了)。这两种方法的结果是一样的:我想i_1还是镜像I _ 1’都无所谓;替代与否给出同样的结果。

巧妙的地方

轮次的原创论文中提到,要在在Eth2,上述的过程会进行90次。6lg“开始有更好的选择性密码攻击(CCA)安全边界”需要三轮,其中N是列表的长度。在维塔利克的注释规范中,他说:“密码学专家建议,我们可以在N中仅仅一轮就提供足够的安全性。

Eth2中验证器的绝对最大数量,也就是我们需要洗牌的列表的最大数量,大约是222(420万)。维塔利科给出的估计值是88轮,文中的估计值是92轮(假设4log2N是自然对数)。因此,我们现在处于一个大致正确的范围内,尤其是因为我们最终可能没有那么多活动的验证器。

根据列表长度调整轮次可能会得到有趣的结果,但我们不会这样做,这可能是不必要的优化。

有趣的是,当最小权威审核信标链的规范时,他们发现在选择块支持者的洗牌中存在偏差(参考问题F)。但结果他们错误地使用了只有10轮的洗牌配置。当他们将洗牌配置增加到90回合(我们在主网络中使用的回合)时,偏差消失了。

lg

洗牌算法要求我们每轮随机选择一个轴点,每轮随机选择是否替换每个元素。

在Eth2中,我们肯定会从一个种子值产生随机性,这样同一个种子总会产生同样的洗牌结果。

轴索引是通过散列与8字节SHA2的轮次串联的种子产生的,轴索引是通过散列与轮次串联的8字节种子值SHA2产生的,所以它通常在每轮中变化。

用于决定是否替换元素的决定性数字是从以下元素中提取的:种子的SHA256散列、循环和列表上元素的索引。

(伪) 随机

这种洗牌算法比Fisher-Yates算法慢很多。如果费希尔-耶茨算法需要效率洗牌,我们的算法平均需要N90/4次。我们还应该考虑伪随机性的产生,这是算法中代价最大的部分。费希尔-耶茨需要接近NN数字的随机性,而我们需要log2N数字。根据我们在Eth2中需要的N值范围,超出的数字相当多(90(log2N+N/2)一百万的时候,Eth2需要的数字大约是http://的两倍)。

N

如果效率不高,为什么要选择这种实现方式?

N

这种算法的亮点是,如果只关注少数几个索引,就不需要计算整个列表的洗牌。事实上,我们可以将该算法应用于单个索引,以找出哪个索引将被替换。

因此,如果我们想知道索引217的元素在哪里被混洗,我们可以仅对索引运行该算法,而不混洗整个列表。此外,相反,如果我们想知道哪些元素被混洗到索引217,我们可以向后运行算法来找到元素217(反向意味着从高到低运行轮次,而不是从低到高)。

总之,我们可以在一个恒定的时间内计算出元素I在哪里混洗,元素I的来源在哪里(逆向操作),计算时间不依赖于列表的长度。Fisher-Yates洗牌没有这个特点,也不能洗牌单个索引,所以他们往往需要反复洗牌整个列表。

Eth2规范写的是如何应用算法洗牌单个索引。其实一下子把整个列表洗牌只是一种优化!如果我们愿意,我们可以只对列表中的一个元素进行轮流洗牌:(反向)运行洗牌以找出哪个元素结束于索引0,再次运行洗牌以找出哪个元素结束于索引1,以此类推。

我们不这样做的原因是因为一次需要生成一个256位的哈希,丢弃255位是很浪费的。如果我们使用一个1位的散列或预言,在列表中洗牌一个元素的效率几乎和洗牌整个列表一样。

为什么选择swap-or-not这种算法

这个特性之所以有意义,在于轻客户端。轻客户端相当于Eth2信标链和碎片链的观察者。他们不存储整个状态,而是希望安全地访问链上的数据。要验证他们数据的正确性,也就是不存在欺诈,一个必要的步骤就是计算出证明数据的委员会。

也就是说,使用了洗牌算法,我们不希望light客户端存储或洗牌整个验证者列表。有了交换或不交换,他们只能计算出自己需要的少量委员会成员,这将大大提高整体效率。

对单一元素进行混洗

如果你和我一样喜欢GitHub的考古特性,可以在这里查看一下关于Eth2求洗牌算法的初步讨论,在这里宣布最终的赢家。

如果想从另一个角度看交换或不交换的洗牌算法,可以看看Protolambda发布的更直观的解释。

做到真正的“轻”客户端

在这张图中,2019年,我在EthCC上听了贾斯汀德雷克(Justin Drake)的对换不洗牌(swap-or-not shuffle),在库特客户端实现了第一版对换不洗牌(当时也叫Artemis)。

以太坊2.0的混洗算法

作者|本爱丁顿

标签: btcv