随机数的生成在计算中一直很重要。尽管本地和云计算已经有了可靠的伪随机数生成器(PRNG),但区块链带来了新的挑战。总的来说,区块链和Web 3的目标之一是网络中的计算机不需要彼此信任。
从基本的意义上说,网络中的计算机在没有相互信任的情况下运行的方式是让多台计算机执行相同的软件,并且只有在某些多数(通常但不总是1/2或2/3,出于超出本文范围的原因)同意执行的结果的情况下,才接受结果。
对于更新帐户余额这样的程序来说,这并不太难。从账户a的余额中减去一个数字,再加上相同的数字减去账户b的交易费用就可以了。但如果存在随机性呢?
为什么这很重要?
1. 协议: 大多数权益证明算法使用随机函数来选择下一个验证器。如果随机性是可预测的或可偏置的(稍后会详细讨论),则验证器集可能会损坏。
2. 应用: 几乎所有的应用(游戏、投票(候选顺序)等)都使用随机数生成,用户不能依赖有偏见的应用。
首先,简单介绍伪随机数的产生。虽然有许多算法,但大多数PRNG都是以“种子”开始的——一个基于某种值的0和1选择的序列,例如,如何在屏幕上移动鼠标。PRNG将种子作为一个特殊曲线上的起始点,而里面的算法会绕着曲线弹跳,输出一系列确定性的但看起来是随机的数字(即根据最后的n个值的知识,除了曲线的概率分布函数外,没有办法可靠地预测n+1值)。
我们想要满足两个性质的随机性:
不可预测——被动的对手无法通过观察系统提前预测结果。
不可偏颇——积极的对手不能通过操纵或隐瞒结果来偏颇系统。
因为计算机不能生成真正的随机数,我们要么需要一种方法来同意PRNG种子数,要么需要某种外部形式值来满足不可预测性和不可偏性。
已经使用的一种方法是使用哈希函数的输出。它们是确定的,但是在实际执行之前,无法判断输出是基于输入的。为什么我们不同意使用当前或未来块头的哈希值中的一些位作为随机数呢?假设你进行了抛硬币游戏。您可以只取块头哈希的最小有效位(LSB),然后使用0或1作为结果。既然所有的电力都花在哈希值上了,为什么不充分利用哈希值呢?
但是,如何让块哈希值生成器发布这个块呢?在工作证明区块链中,发布有效块的动机是块奖励。例如,如果哈希的LSB是1,那么块生成器将赢得1000美元,但是他的有效块以0结束,而当前块的奖励等于300美元。在这种情况下,他可以选择不传播这个块,因为如果他让另一个矿商找到这个块,那么期望值就是500美元。
因此,在这里,挖掘人员赢得赌注的概率大于50%(即从他的网络哈希功率百分比到1的跨度的50%)。
这可能只会产生50.001%的最终概率,但在高频交易和其他概率活动中,这种规模的优势可以比竞争对手带来数百万美元的利润(我要进一步说明,任何与协商共识意见有关的资料都应专门用于协商共识意见。工作证明经常被批评为“浪费”能量,一些解决方案是将这些CPU周期用于双重且通常是利他的目的,例如protein folding。浪费的能量实际上是保证链安全的因素:如果protein folding突然变得有价值,那么链安全将是第二优先考虑的问题。一旦您将其他激励措施(如将应用程序的输出引入协商共识参数)引入,其中一个(协商共识或应用程序)将被操纵。
我们的第一个目标(不可预测性)是一个更容易实现的目标,并且已经在分布式计算中得到了解决。多玩家游戏就是这样一种应用:你希望游戏具有不可预测性,但它需要在许多本地机器上执行,并且游戏的整体状态需要在参与者之间保持一致。第二种比较困难,因为你怎么能强迫别人说出他们不喜欢的结果呢?
理想情况下,我们应该有一个可验证的PRNG(我们假设PRNG是不可预测的)。可验证函数的计算时间和验证时间分别为p和np。这本质上意味着计算解决方案可能是高度密集的,但是验证它是否正确是很容易的。
一个很好的应用是验证器选择方案,每个人都检查她是否是验证器,如果是,她就可以计算并提出一个块。每个人都可以检查自己的验证器状态并验证实际验证器的合法性,这比任何人从头开始计算验证器是谁都要快(并在验证器提出块之前尝试贿赂或攻击验证器)。
最近,Dan Boneh在一篇关于可验证延迟函数的论文中提出了解决这个问题的方法。VDF提出了一些只能在单个CPU线程上计算的函数(通常基于多次平方数),以防止拥有更多CPU的对手使用并行处理来计算解决方案。使用nsteps进行计算的VDF的解决方案可以在log(n)步骤中验证,因此诚实的节点可以比对手计算新解决方案的速度更快地验证解决方案是正确的。
Boneh关于VDF的论文直到2018年才发表,甚至他们也承认他们的示例函数需要改进。这是最前沿的工作,我们可以期待许多进步。
解决第二个特征(不可偏性)是困难的,因为您不能强迫某人执行计算或显示结果。目前最主要的方法是提交公开方案。我们的目标是公开地就PRNG种子达成一致,这样就没有人可以通过秘密地改变种子或拒绝传播解决方案来对结果产生偏见。
首先,每个人都同意使用伪随机函数。稍后,很容易验证每个人都使用了正确的函数,因为我们都可以自己运行函数并验证结果。现在我们需要同意使用什么种子,但是我们不希望任何人提前知道种子。
举个例子,让我们做一个有三方参与的提交-显示方案:应用程序所有者(例如在线赌博站点)、用户和执行计算的节点。每一方都能产生一颗种子,但不会透露出来。相反,每一方都显示了种子的哈希值。
此时,每一方都有自己的种子和另一方种子的哈希值。接下来,每个人都展示他或她真正的种子。伪随机函数的最终种子是 S = S1 XOR S2 XOR S3
如果你是S3,你接收S1和S2,你现在可以创建一个新的S3 ‘,它可以翻转任何需要的位来得到你想要的最终种子。但是您已经发送了S3的哈希值,如果您尝试在事后更改S3,那么所有人都会知道!每个人都致力于在知道其他种子之前创建的种子,即使一方不透露计算结果,其他人也有必要的信息来计算函数输出并达成一致。
委员会披露方案仍然有一个缺陷:最后一个披露的人可以比其他人先看到最终结果,如果结果不好就决定不披露。原则上,有两种方法可以解决这个问题:技术上的和经济上的。例如,一个技术解决方案可以使用一个智能合约来保存单个种子,然后在双方确认各自收到了每个种子的哈希值后显示所有种子。从经济上讲,你可以对那些不公开身份的进行惩罚。
这都是相当高的水平,这仍然是一个开放的问题;新的解决方案可能有弱点。随机性和决定论是对立的,因此说服人们相信由他们不信任的人产生的随机数将是分散计算中一个不断发展的挑战。
[1]在集中式计算中,我们依靠监管机构和国家来惩罚不公平的行为,但我们的目标是通过计算来完成这一任务,因为攻击要么是不可能的,要么代价高昂。
[2]一些应用程序实际上是这样做的,不要使用它们!
[3]人类可能会纠结于这样一个问题:“300美元肯定比1000美元的50%机会更有价值吗?”但对于一台可能押注数千次的电脑来说,答案是显而易见的。
[4]在权益关系证明中攻击更加容易。更改任何参数都会更改输出的哈希值。例如,将时间戳更改1毫秒。现在您需要做的就是贿赂验证器。
[5]如果将电子游戏看作分布式状态机,那么它就是一个很好的例子。状态可以由每个角色的坐标、状态、健康状况、财富、武器收藏等来表示。尽管所有用户都有不同的硬件和不同的连接速度,但这种状态需要尽可能接近实时地由所有用户计算和商定。这或多或少是通过一个中央游戏服务器作为某种管弦乐队指挥来完成的,以确保每个人都在运行适当的软件。将状态设置为帐户的键值存储,并将导体替换为使用资源证明,这样基本上就可以利用以太坊了。
{6}将一个数多次提升到指数的原因是每一步都依赖于前一步的结果,这在普通代数中不是这样,但在具有溢出或模运算的固定大小的位数组中是这样。
[7]XOR本质上是一个开关。0不做任何事情,1切换开关。即0 XOR 0 = 0, 0 XOR 1 = 1, 1 XOR 0 = 1, 1 XOR 1 = 0。假设应用程序将使用前100个随机数,攻击者想通过操纵S来获得优势。要选择这个S,攻击者需尝试数十亿个种子,然后使用前100个输出最有利的那个。要选择S3 ’,将所需的S与S1 XOR S2进行比较,S3 ‘在它们一致的地方为0,在它们不一致的地方为1。
评论
查看更多