用于P2P卡游戏的密码学

时间:2011-07-01 20:01:56

标签: encryption cryptography playing-cards

我正在考虑编写适合半流行纸牌游戏的电脑。我想让它在没有中央服务器的情况下运行,而我正在尝试提出一种方案,在不必信任客户的情况下就会使作弊变得不可能。

我看到的基本问题是每个玩家都有几堆牌(平局牌,当前牌和弃牌牌)。任何一个玩家都不可能改变这些桩的构成,除非游戏规则允许(即绘制或丢弃牌),玩家也不能知道他们或他们的对手的桩是什么。

我觉得应该有一些方法可以使用公钥加密等方法来实现这一目标,但我仍然在我的方案中找到漏洞。任何人都可以建议一个协议或指向我关于这个主题的一些资源吗?

[编辑] 好的,所以我一直在考虑这个问题,这是我想出的一个想法。如果你可以戳它的任何漏洞,请告诉我。

在随机播放时间,玩家拥有一堆卡片,其价值为他们所知。他们采用这些值,将随机盐连接到每个值,然后哈希它们。他们记录盐,并将哈希传给他们的对手。

对手连接他们自己的盐,再次哈希,然后将哈希洗牌并将牌组传回原来的牌手。

我相信在这一点上,牌组已被随机化,玩家都无法了解这些价值观。然而,当一张牌被抽出时,对手可以揭示他们的盐,允许第一个玩家确定原始值是什么,并且当牌被玩时,玩家展示他们自己的盐,允许对手验证牌值。 / p>

6 个答案:

答案 0 :(得分:8)

你的问题是密码学中着名的Mental Poker Problem (这是我在大学里最喜欢的加密课程之一) 是可能的,它已经解决了(部分地,像所有事情一样,加密,Ron Rivest,只要你不介意一个巨大的表现很受欢迎。

查看维基页面了解更多详情。

答案 1 :(得分:5)

我想描述一个很快就出现在我心中的想法。我不知道它是否满足您的所有需求,所以请随时对此发表评论。

假设玩家A拥有卡A1A2A3,......来自数字01所代表的集合,...... N-1。这些卡也可能被分成堆,但这不会改变以下内容。

您可以改为使用其中两个[A1, A2, A3, ...][A1_a, A2_a, A3_a, ...]而不是使用单个列表[A1_b, A2_b, A3_b, ...]来处理这些卡片,其中一个是播放器A而另一个是播放器B 0...N-1。它们是以这样的方式生成的,每个都是随机的(在A1_a + A1_b = A1范围内),但两者都是相关的,以便A2_a + A2_b = A2N,...(所有操作模{{1} }})。

  • 因此没有玩家真正知道这些牌无法获得补充牌(即他无法合理地更换牌)
  • 每当你需要知道一张牌时,两个玩家都会显示相应的价值并添加模数N
  • 你可以很容易地实现“画一张牌”之类的东西,两个桩都必须以同样的方式对待

答案 2 :(得分:5)

传统的Mental Poker计划有点矫枉过正。由于没有共享套牌,您的情况实际上要容易得多。你可以这样做:

玩家A拿走他的牌并用钥匙Ka加密他们。他把他们送到B,他们将他们洗牌,用钥匙Kb加密。每次A想要打牌时,他都要求B对下一张卡进行(Kb)解密。 A解密这个以找到他画的卡。最后,A和B显示Ka和Kb,并将它们与游戏日志进行比较,以防止作弊。

更新:在反思中,这是一个更简单的解决方案:如上所述,玩家A加密他的牌并将其发送给B. B将他们洗牌。每当A想要一张牌时,他就告诉B他正在画哪张牌。 B从适当的堆中返回(加密)卡。

答案 3 :(得分:2)

也许球员们可以在比赛开始时交换他们的一堆灰烬。

然后当游戏完成时,玩家会在游戏开始时交换他们的桩的实际构图。现在,玩家的客户端可以检查它是否与之前获得的哈希匹配,然后检查所做的所有动作是否适用于这些套牌。

唯一的问题是甲板最初是如何洗牌的。你需要确保玩家不能按照他选择的任何顺序开始他的套牌。

也许让玩家通过从某个特定来源获得随机性来生成他们的初始套牌顺序..但是在某种程度上其他玩家无法计算出其他玩家的套牌订单直到游戏结束,但仍然可以检查玩家并没有摆弄他们的套牌。不知道你怎么能做到这一点。

修改

另一个想法。也许不是在游戏开始时生成随机套牌,而是可以在游戏进行时生成它们。

每次玩家需要从堆中取出新牌时,他们的对手会向他们发送一些随机种子,用于选择下一张牌的内容。

通过这种方式,用户无法知道卡片在其卡片中的顺序。

我不确定你是怎么阻止其他玩家能够分辨出他们将为对手挑选的牌。如果种子用于从某种随机排序的牌组中选择一张牌,对手有一个哈希值来验证......他们可以检查所有可能的牌组合,找出哪一张与哈希匹配,从而他们可以通过向他们发送一张会导致该卡被选中的种子,来决定他们想让其他玩家抽取哪张牌。

答案 4 :(得分:2)

虽然中央服务器可能是最简单的方法,但如果你想避免使用它,你可以使用分布式系统,其中每个玩游戏的人都是其他玩家甲板的存储主机(不是为了他自己或他的对手,而是其他人)。我相信Limewire和Bittorrent都是这样工作的,所以你可以通过研究这些来源获得一些想法。

答案 5 :(得分:0)

这是Acorns方法的改编:

设置:

每个玩家都有他们的牌组(完全有序的牌组)......这些牌组是公共的并且处于自然顺序

每个玩家需要一个不对称(签名)密钥对,交换公钥

现在对随机性问题:

由于玩家可能无法提前看到他们将会抽取哪些牌,因此对手将成为我们随机性的来源:

当我们需要一些随机值时,我们会询问我们的对手......随机值会与稍后检查的动作一起存储

由于我们的对手可能无法操纵我们的牌的顺序,我们接受随机值并用我们的私钥签名......该签名的价值将是我们的RNG种子(对手无法预测) ,之后对手可以根据他/她生成的随机数验证签名(所以我们也存储了签名,并在游戏后进行交换)

由于我们可以每轮进行这种随机数交换,因此预先不知道玩家的随机数 - >没有偷看堆栈的顺序

由于我们现在有一个种子RNG,我们可以得到从“共享”随机值派生的随机值... 通过这种方式,我们可以从我们的牌组中抽取“随机”(完全确定性,可重复的可验证结果)牌......牌组/桩不需要洗牌,因为我们可以从我们的RNG获得随机位置

由于我们已经交换了随机值,签名,初始套牌(按总顺序)和所有动作,我们可以在之后重播整个游戏并检查违规行为