日报标题:诸葛亮想和曹操猜拳,可两人身处异地无法见面
小时候和伙伴一起猜拳定胜负的场景还历历在目吧?记得当时往往因为“慢出” 产生争执。 解决争执的方法通常是重新猜拳,或者是找第三个小伙伴来仲裁。然而这些方法有着本质上的局限, 因为没有任何办法能保证两个人完全同时出拳:在猜拳高手的眼中,即使晚出 0.01 秒, 也可以观察到对手的动作,克敌制胜!不过这并不是一篇武侠小说,所以我们今天讨论的话题是: 如何完成公平的猜拳?!?
两人可以见面
一个最简单的解法是: 每人把自己的决定(石头,剪刀,布)写到一张纸上。再装进一个信封里。然后两人见面,把信封拆开。这样就无法改变自己的决定了。这样的猜拳结果是完全公平的,因为决定已经装在信封里,就无法再更改了!
三国演义中, 诸葛亮和周瑜商量赤壁之战的对策,各在手中写一个“火” 字,使用的是同样的方法。诸葛亮在这里有两个目标:要传达给周瑜自己火攻的计策,同时又想测试一下周瑜是否也想到火攻。周瑜的想法也一样:既要传达这个计策,又想测试对方的能力。这样一来,两方产生了一个有趣的小博弈,看一段原文:
瑜邀孔明入帐共饮。瑜曰:“昨吾主遣使来催督进军,瑜未有奇计,愿先生教我。”孔明曰:“亮乃碌碌庸才,安有妙计?”瑜曰:“某昨观曹操水寨,极其严整有法,非等闲可攻。思得一计,不知可否,先生幸为我一决之。”孔明曰:“都督且休言。各自写于手内,看同也不同。” 瑜大喜,教取笔砚来,先自暗写了,却送与孔明。孔明亦暗写了,两个移近坐榻,各出掌中之字,互相观看,皆大笑。原来周瑜掌中字,乃一‘火’字,孔明掌中,亦一‘火’字。瑜曰:“既我两人所见相同,更无疑矣。幸勿漏泄。”孔明曰:“两家公事,岂有漏泄之理?吾料曹操虽两番经我这条计,然必不为备。今都督尽行之可也。”饮罢分散,诸将皆不知其事。
这里周瑜和诸葛亮掌心写字的方法和使用信封是异曲同工的。
两人不能见面
现在我们把难度提高一点: 诸葛亮想和曹操猜拳,但是两人身处异地无法见面。这种情况下如何保证公平呢?
如果诸葛亮把自己的信封用快马送给曹操,那曹操可以拆开看到诸葛亮的出拳之后再写自己的信。所以之前的解法就失效了。信封这个解法不行了,不过如果用一点密码学,还是可以异地猜拳。我们假设诸葛亮有一个抵抗冲撞的哈希函数(collision-resistant hash function) f(x),满足如下的条件:
(1) 从 x 很容易计算 f(x)。
(2) 非常难找到两个 x, y 满足 f(x) = f(y).
诸葛亮先确定一个选择 m {石头,剪刀,布} 。然后再选择一串随机数 r, 把自己的承诺 y = f(r , m) 发给曹操。曹操同样把自己的“承诺" y' 发给诸葛亮。
诸葛亮等自己收到曹操的承诺 y'以后,再把随机数 r 和自己的出拳 z 发送过去。曹操等收到承诺之后,做同样的事。
曹操通过计算 f(r, m) = y 来确保诸葛亮没有作弊。
现在双方可以比较彼此的出拳,来决定谁胜谁负!问题是: 为什么这样可以杜绝一方作弊?
假设诸葛亮想要作弊,那他必须在收到曹操的所有信息之后再发送(r,z)。现在假设诸葛亮想把自己的出拳改成 m' , 那么他必须找到另一个随机数 r',满足
f(r , m) = f(r', m').
然而!根据对函数 f 的假设,在有生之年诸葛亮是找不到 r' 的。所以他没有办法作弊:任何他能找到的 r', 曹操计算出的承诺 f(r',m') 都和 y 对不上,所以曹操能看出他有没有“慢出”!
承诺系统 (Commitment Scheme)
上面介绍的”公平的远程猜拳“方法用到的实际是密码学的一个重要原型 Commitment Scheme。它起源于两篇文章: 1979 年 Blum 的 coin flipping over the telephone (如何通电话猜硬币)和 1981 年 RSA 三巨头的 Mental Poker (如何通电话玩扑克)。可以看出来,commitment 最大的优势是用来远程进行公平的博弈,而不需要一个第三方裁判的存在。
这里再介绍一个经典的应用场景:假设一件古董的买方和卖方的出价底线分别是 a 元和 b 元,他们希望达成如下的协定:如果 a < b,那么交易失败;如果 a >= b, 那么交易在中间价格 (a + b)/2 上成交。
这个看似简单的合同怎么在实际生活中执行呢?当然买家不能把自己的底线 a 透露给卖家,因为如果 a > b,那么卖家可以出价 a, 从而在高位成交;反之也同理。如何隐藏自己的底线价格呢?用 commitment!原理和之前的异地猜拳完全一样。就是买卖双方(1) 先公开自己出价的 commitment,然后(2) 公开价格。由于 commitment 具有隐藏性,所以在步骤(1)之后双方都无法推测对方的价格;又由于 commitment 具有不可更改的特性,所以任何一方都无法在步骤(2)中更改自己之前承诺(commit) 的价格 !
为何不用微信猜拳?
看到这里肯定有人要问了: 那微信猜拳呢? 它比上面的用 commitment 的解法简单粗暴多了:我可以直接发送一个猜拳的表情,然后这个表情会随机变化成石头剪刀布中的一个。为什么还需要引入承诺系统呢?
其实最大的不同在于:微信在猜拳里扮演的是一个 公正的第三方, 即对话的双方需要都信任微信不会作弊。其实在有公正的第三方存在的情况下,上面提到的所有问题都可以简单解决。从之前那个古董买卖的例子来看,如果有一个买卖双方都信任的交易行,那么他们只需要把自己的报价 a,b 提交给交易行,交易行作为一个诚实可靠的机构,会诚实的比较报价并得出最终结论。
然而这个公正第三方往往不是免费的:无论是法官,交易中介,古董拍卖行,都是收取手续费的。 而且这些第三方也不是百分之百可以信任:他们有可能和博弈双方的其中一边合作,来损害另一边的利益。
而上面的通过 commitment 来博弈的方法是不需要公正第三方的!这也是为什么它在现代密码学中的应用如此的广泛。比如
数字货币(参见旧文 Zerocash: 数字货币领域的暗科技 )
多方计算
零知识证明
等等...都是以后可以展开聊很多的话题,今天就先到这里吧。