可自行验证(provably fair)是一种密码学方法,让玩家可以在事后检查,平台没有改过一局的结果。它用 SHA-256 哈希,在开局前锁定一个随机种子,开局后再把种子揭晓:揭晓的种子和事先锁定的哈希对得上,这一局就没有被动过。这篇先用直白的方式讲这个概念,再给想看的人讲数学,最后说清楚可自行验证能证明什么、不能证明什么。
「可自行验证」到底是什么意思?
「可自行验证」只代表一件很明确的事:你可以在事后证明,平台在你下注之后,没有改这一局的结果。
就这样。不是「游戏是公平的」,不是「你会赚」,也不是「机会很好」。只是:平台在你下注前就锁定了结果,而你可以检查它有没有守住这个锁定。
这个保证,比大部分玩家以为的窄。但它也是真的;在一个默认什么都不公开的行业里,就算是一个窄的保证,只要有数学撑着,也值得弄懂。
这个概念是在加密货币赌博的圈子里长出来的。早期的平台要解决一个信任问题:中间没有任何监管机构,怎样让一个国家的玩家相信,另一个国家的服务器没有作弊?答案是密码学,具体来说,是哈希函数。
今天,用可自行验证(公开种子,每局都能重新算)设计的,有游戏商的游戏,比如 Spribe 的 Aviator、Mines 和 Plinko;也有网站自己运营的崩盘游戏,比如 Stake Crash。很多其他常见的游戏用的是别的机制。JetX 在揭晓结果前先用哈希锁定它,却没有公布重新算出结果的方法,所以它是先公布哈希,而不是可自行验证。Spaceman 和 High Flyer 靠测试实验室认证的随机数生成器,玩家没办法一局一局检查。每种做法都有长处和短处,下面会讲。
不用数学,可自行验证怎么运作?
想象一个封好的信封。
-
开局前,平台把爆点写在一张纸上,放进信封,封好,放在桌上。每个人都看得到这个封好的信封,但没人看得到里面写了什么。
-
你下注。信封已经封好了。平台改不了里面的内容。
-
这一局进行。倍数往上升,然后爆了。
-
这一局结束后,平台打开信封。每个人都看得到,里面的数字和爆点一样。信封在大家下注前就封好了,所以平台没有改结果。
整个概念就是这样。在现实世界里,你需要一个大家都信得过的第三方来保管信封。在数字世界里,信封换成了加密哈希函数:一种往一个方向算很容易、反过来几乎不可能算回去的数学运算。
哈希就是封好的信封,种子就是里面那张纸。这一局结束后,平台揭晓种子,任何人都可以把它拿去算哈希,确认和开局前公布的哈希对得上。对得上,就代表锁定守住了。
用数学讲:SHA-256 和 HMAC 怎么运作?
给想看技术细节的读者,这里讲大致的样子。可自行验证的崩盘游戏,通常用以下两种设计之一。某一款游戏用的是哪一种,写在它自己的公平性说明里;下面的描述是通用的,不是在描述任何一个具名的网站。
设计 1:事先锁定的哈希链,用在大家共用的局。事先产生一长串哈希,每一个都是下一个的哈希。最后一个哈希在开局前公布,然后这条链倒着用,每局用一个哈希。每一个揭晓的局哈希,算一次哈希后,都必须等于前一个揭晓的哈希,所以只要换掉或插入任何一局,链就会断。
设计 2:服务器种子、客户端种子和 nonce,每个玩家各自一套。
- 服务器种子:游戏服务器产生的一串随机字符。在它停用之前,一直保密。
- 服务器种子哈希:服务器种子的 SHA-256 哈希,在用它玩任何一局之前就公布。
- 客户端种子:玩家通常可以自己设定的一串字符,这样服务器就不是控制所有的输入。
- Nonce:一个计数器,每下一注就加一。
每一注,游戏都会以服务器种子作为密钥,对客户端种子和 nonce 算一个带密钥的哈希(HMAC-SHA256),再用它公开的一条公式,把这个哈希变成结果。每款游戏的公式都不一样。常见的做法,是把哈希的一部分读成一个均匀分布的随机数,再把它转换成:升到任何一个倍数的机会,都和这个倍数成反比。
种子停用后的验证。服务器种子揭晓后,玩家可以:
- 用 SHA-256 算出揭晓的服务器种子的哈希。
- 确认这个哈希和开局前公布的一样。
- 用揭晓的服务器种子、自己的客户端种子和 nonce,重新算出任何一注的 HMAC。
- 套用游戏公开的公式,确认结果和当时发生的一样。
如果第 2 步对不上,锁定就被破坏了。如果每一步都对得上,就代表用这个种子下的每一注,游戏都守住了锁定。
一个算给你看的例子(示意数值,不是来自任何真实的游戏):
Server seed (revealed later, illustrative):
"illustrative-server-seed-7c41"
SHA-256 of the server seed (published before play):
"85a9b32448bc3b3bbe6087200611cc1838ba4e2f569a73a5e643a84eeabc8a6f"
Client seed: "illustrative-client-seed"
Nonce: 42
HMAC-SHA256(key = server seed, message = "illustrative-client-seed:42"):
"c1b8ab5363a5d7bde17398e8a48818a5bdd42bbdb58739c3beba377041ebf52a"
上面两个哈希都是真的:你可以自己重新算一遍。最后一步,从这个 HMAC 变成倍数,取决于某一款游戏公开的公式,所以我们不在这里放一个编出来的倍数。第一步,也就是拿种子和公布的哈希对比,你可以用我们的哈希检查工具来检查。
可自行验证能证明什么,又不能证明什么?
这是这篇文章最重要的一节。可自行验证证明的,是一件特定、范围很窄的事。玩家、记者,甚至一些平台,常常把它能做到的说大了。
可自行验证能证明的:
- 每一局的爆点,在大家下注之前就定好了。
- 平台没有在看到你的下注之后改爆点。
- 同一个服务器种子,算出来的哈希永远一样:这种一致性,可以用数学检查。
可自行验证不能证明的:
-
它证明不了游戏的返还率就是平台说的那样。平台可以把返还率设在 90%(这对玩家很不公道),每一次哈希检查却照样都能通过。哈希证明的是锁定,不是参数公平。
-
它证明不了随机性的质量好。如果服务器种子产生得很差(熵很低),知道种子怎么产生的人,就可能预测出爆点。哈希照样对得上,因为锁定确实守住了。
-
它证明不了平台没有在换种子上动手脚。平台可以挑特定的时机换服务器种子:比如,有人下了一大注之后、这一局开始之前。这叫换种子攻击,标准的哈希检查发现不了。《种子更换》解释了这个想法,以及要用什么数据才能检验它。
-
它证明不了客户端种子没有被动过。如果客户端种子是平台产生的(而不是让玩家自己选),理论上平台可以挑那些会产生有利结果的客户端种子。好的做法,是让玩家自己设定客户端种子。
所以除了检查哈希,数局数也很重要。哈希检查告诉你,平台守住了一个锁定。大量局的计数,附上样本量和 95% 误差范围公布,告诉你整体的返还率和分布,和官方说的对不对得上。一款游戏过了最低样本量,实验室就一款一款公布这些计数;见游戏列表。
哪些攻击可以绕过可自行验证?
要弄懂可自行验证的限制,就要弄懂它挡不住的几种具体攻击:
改参数。平台设了一个没有公开、或者说得不实的返还率。每一局都验证得过,因为哈希链是诚实的;但把哈希变成倍数的数学公式里,藏了一个参数,让分布往平台那边偏。要发现它,就要拿观察到的爆点分布,去和官方说的返还率对应的理论分布对比。这就是实验室的局数计数在量的东西:每个收手目标的返还率,以及分布的形状,每一项都附上误差范围。
挑时机换种子。平台盯着进来的大额下注,挑一个能让接下来几局都爆得很低的时机,换服务器种子。每一局单独看都验证得过,因为新种子的哈希在那几局之前就锁定了;但换种子的时机,和玩家的行为有关联。要发现它,就要用统计分析,看换种子是不是扎堆出现在大额下注的时候。《种子更换》详细讲这一点。
熵太低。平台产生的服务器种子熵很低,比如用了一个弱的伪随机数生成器(PRNG),或者一个可以预测的种子。这样产生的爆点,照样通过哈希验证,看起来也可能完全随机,但知道种子怎么产生的人,就能预测它们。风险在于可以被预测,而不是分布看起来很怪,所以种子应该来自一个强的随机来源,而让玩家自己设定客户端种子也有帮助。
这些攻击,没有一种能轻易大规模进行而不被发现。但它们是可能的,这也是为什么光有「可自行验证」还不够。它是一个必要的底线,不是一个足够的保证。
你怎么自己检查一局可自行验证的游戏?
检查不需要任何特别的软件。大致上是这样:
- 记下锁定,也就是开局前显示的东西:服务器种子哈希,或者公布的哈希链末端。
- 等它揭晓。正在用的种子,要等它停用并揭晓之后才能检查。
- 检查锁定。算出揭晓的数值的 SHA-256,和开局前公布的哈希对比。我们的哈希检查工具在你的浏览器里做这件事,不会传任何东西给我们。
- 重新算出结果:如果游戏公开了它的公式,就重新算一次,再和你看到的爆点对比。
想看一步一步的详细说明,还有可以直接复制粘贴的代码,见《自己动手验证哈希》。
关于验证,最重要的不是技术过程,而是背后的诱因。可自行验证有用,不是因为每个玩家都检查每一局,而是因为每个玩家都可以检查。可能被检查,而且是真的可能,就是让平台保持诚实的机制。
可自行验证能帮你预测下一局吗?
不能。一个种子要等它产生的局都结束了,才会揭晓,所以验证永远是往回看的。说能从哈希或最近几局读出下一局结果的软件,看不到那个保密的种子;见预测软件和机器人的检查。过去的结果也不会改变下一局:历史记录说明的是过去的表现,它预测不了下一局。规律和好运时段的检查解释了为什么。
这一页对你有用吗?
匿名:不用账号,也不设 cookie。