【小知识】怎么远程抛一枚硬币?

问题描述

抛硬币是一种非常简单流行的随机试验。抛出一枚硬币,应声落地,正反即知。

Alice和Bob最近有点纠纷,他们打算让上天决定是谁错了。但他们现在不在同一个地方,而且也没法视频。

因此现在,Alice和Bob需要在远程语音通话时抛一枚硬币。

然而,两个人都有可能为了获胜而说谎。

那么如何设计一个机制,使得这个抛硬币过程能够可靠地实现呢?


解决方法

如果啥都不考虑,第一反应显然是这样的:

Alice和Bob先商量好哪面朝上代表谁赢,比方说,正面朝上Alice赢,反面朝上Bob赢。

接着Alice抛硬币,把结果告诉Bob。

然而,就算抛掷结果是反面朝上,Alice也可以说谎告诉Bob是正面朝上,Bob也没法证明Alice说谎了。

而如果让Alice先抛硬币并宣布结果,然后Bob再说自己心里选的是哪一面,Bob同样也可以说谎。

这样看来,可靠的远程抛硬币似乎不可能做到,是吗?

其实是可以做到的。

一个正确的解决方案是这样的:

  1. Alice和Bob私下各自选择一个随机词,例如分别为bubblejetknockback

  2. Alice私下决定用“反面”(tails)代表自己获胜。

  3. Bob 将他选择的单词knockback发送给Alice。

  4. Alice计算一个字符串的哈希密文,其中包括两人选定的单词和自己选择的获胜面(例如bubblejet knockback tails),并将该密文(例如3fe97d8e6456a1dce4508d00251345e3)发送给Bob。

  5. Bob 进行物理上的抛硬币,并向 Alice 宣布结果,正面或反面。

  6. Alice透露她加密的字符串是bubblejet knockback tails

  7. Bob自行确认3fe97d8e6456a1dce4508d00251345e3确实是bubblejet knockback tails的密文。

  8. 双方现在可以确定Alice赌的“反面”是否与Bob的抛硬币结果相匹配。


再聊聊

为什么这个机制能保证双方都无法造假(更准确地说是有效造假)呢?

Wiki上是这样说的:

Bob, by providing his own random word, guarantees that Alice is not able to precompute an image pair of “tail/random string” or “head/random string”, for two different random words. Bob is also unable to reverse Alice’s hash to see what her chosen outcome was before flipping the coin, and to lie effectively about its outcome, because he does not know Alice’s random word at that point in the process.

Bob通过提供他自己的随机词,确保Alice无法预先计算出两个不同的随机词的“反面/随机字符串”或“正面/随机字符串”的像对。此外,Bob也无法通过反向解密Alice的哈希值来查看她在抛硬币之前选择的结果,也不能有效地关于结果撒谎,因为他在该过程中不知道Alice的随机词。

这里通过举例子来更详细地谈谈为什么两个人的随机词都是必要的:

如果Alice不用随机词。那么Bob就可以将knockback tailsknockback head的哈希值都算一遍,然后对照一下Alice发来的哈希值,就知道Alice选的是哪一面代表获胜,Bob就可以在物理抛硬币后对Alice撒谎。

如果Bob不用随机词。那么Alice就存在提前构造出两个哈希碰撞的字符串(其中一个以head结尾,一个以tails结尾)的可能性。在Bob公布结果物理抛硬币的结果后,Alice可以选择对自己有利的那个字符串告知Bob,Bob也无法从哈希值上发现任何问题。


Commitment scheme - Wikipedia