另一个公平掷硬币 sCrypt 合约

上篇文章中,我们使用 XOR 在比特币网络上进行了公平的抛硬币。今天我们来介绍另一种使用 Blum 原始协议 [^1] 来实现这个游戏的方法。

它包括以下步骤:

  1. Alice 选择质数 pq。 他告诉 Bob 二者乘积 N = p * q。Alice 可以选择很大的 pq ,这样 Bob 就无法进行从 N 进行反推;
  2. Bob 在 0 到 N 之间选择 x [^2],并计算 b =x² mod N。他告诉Alice 数值 b。 此步骤类似于在掷硬币之前就选择一个结果并作出承诺;
  3. Alice 计算 b 取模 N 的四个方根,分别是 xyN-xN-y。 她选择 {x,N-x}{y,N-y} 对中的一个并告诉 Bob。 该步骤对应于硬币的物理翻转;
  4. 如果 Alice 选择 {x,N-x},则 Bob 获胜,并且他可以通过告诉 Alice x 轻松证明这一点。除非 Bob 在第2步中选择了 x,否则他无法计算出这个数,因为他不知道 pq
  5. 如果 Alice 选择 {y,N-y},则她获胜。 因为 Bob 无法计算出 y,所以他不能通过告诉 Alice 这个数来作弊。

合约示例代码如下:

// fair coin toss using Blum's protocol
// Coin Flipping by Telephone. by Manuel Blum CRYPTO 1981
contract CoinToss {
    PubKey alice;
    PubKey bob;
    // commitments
    Sha256 aliceHash;
    Sha256 bobHash;
    // N = p * q
    int N;

    public function toss(int aliceNonce, int bobNonce, Sig sig) {
        require(hash256(pack(aliceNonce)) == this.aliceHash);
        require(hash256(pack(bobNonce)) == this.bobHash);

        // Bob succeeds to guess Alice's toss
        bool head = aliceNonce == bobNonce || aliceNonce == this.N - bobNonce;

        // head -> Bob wins; tail -> Alice wins
        PubKey winner = head ? this.bob : this.alice;

        // winner takes all
        require(checkSig(sig, winner));
    }
}

[^1] Coin Flipping by Telephone: A Protocol for Solving Impossible Problems. Blum (CRYPTO 1981).
[^2] x 和 N 必须是互质的,以确保 4 个平方根

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sCrypt Web3应用开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值