ChaumMian CoinJoin

Created on Oct 26, 2023
  • 目标:构建一笔 bitcoin mixer 交易, 打乱 Inputs Outputs 的关联. examples
  • 前置知识
  • 参与者:
    • 用户
    • coordinator: 一个无需信任的第三方
  • 为了简单起见,假设池子的单位为 1 btc,全部使用 P2PKH 的方式进行转账。参与者 alice 想要自己的 addr1 的 tx ouput(大于 1btc )当中转 1btc 到 bob 的地址 addr2 当中
  • 过程
    • alice 使用某个匿名的网络 id1 连上 coordiantor(tor etc)
    • alice 向 coordiator 证明自己可以解锁一个未使用的 ouput(大于 1btc )OP1
      • alice -> coordinator: 我拥有地址 addr1, 可以解锁 OP1 ( 使用 pk 就可以证明)
      • coordinator -> alice: 麻烦您签个名,我认证一下哈
      • alice -> coordinator: 签名消息
      • coordinator 验证成功
    • alice 向 coordiator 发送 bob 公钥的盲消息 M1 = < Blind(Hash(addr2.pk)) >
    • coordinator 对 M1 直接签名,并向 alice 返回 签名消息:M2 = Sign(Coordinator.sk, M1)
    • coordinator 向当前池子 tx 的临时 outputs 当中加上一条对 alice 的找零 output
      • OP_DUP OP_HASH160 <Hash(addr1.pk)> OP_EQUALVERIFY OP_CHECKSIG
    • alice 在 网络 id 1 下线,更换 id2 连上 coordinator(tor etc)
    • alice 对 M2 去盲得到 M3 =Sign(Coordinator.sk, Hash(addr2.pk)),并把 M2 和接收者的公钥哈希发送到 coordinator
    • coordinator 用自己的私钥验证,发现自己的确对这个接收者签了名
    • coordinator 向当前池子 tx 的临时 outputs 当中加上一条对 addr2 的 1btc 转账
      • OP_DUP OP_HASH160 <Hash(addr2.pk)> OP_EQUALVERIFY OP_CHECKSIG
    • 当 coordinator 发现池子足够大的时候把完整的 outputs 发给所有的该池子的用户,要求所有的参与者签名,锁住 outputs(此时 outputs 不会在添加了)
    • alice 从网络 id2 下线,更换 id3
    • alice 接收到了完成的 outputs, 作了个简单的算术,发现自己的两笔转账都在里面(一笔 1btc 给bob 的, 一笔找零给自己的)满意地签了名,把签名和自己的公钥(addr1.pk)发给 coordinator
    • coordinator 收集到了所有的签名,构建了所有的inputs ,把完整的 池子 tx 发送到 btc 网络上,完成交易
    • 待交易确认之后,bob 可以向正常使用 P2PKH 一样使用 alice 的转过来的 1btc
  • 匿名问题:有谁知道转移对?
    • alice:alice 作为发起人,当然知道
    • bob:如果bob 只知道链上的消息,bob不知道这笔钱是 alice 给转的。但是alice 和 bob 往往在链下有联系(要不然为什么要向bob 转账呢?除了投毒攻击,甚至往往可能是同一个人。
    • coordinator:coordinator 知道所有 input 对应的公钥. 由于 alice 使用两个不同的网络 id 发送 M1 M3. coordinator 无法将 M1M3 关联起来,除非 coordinator 关联了 id。
    • 混币池子里面其他的用户:无法知道其他的转移对,只知道完整的整个池子的转移
    • 其他人:更加无从得知转移对。
  • 破解匿名的方法:
    • 网络层面关联 id1 id2
    • coinjoin 常规攻击:在一个池子当中混入足够多的内鬼交易对(可以被攻击者知晓的交易对),可以暴露其他混币者的转移对。
  • 安全问题:
    • alice 怎样不会被 coordinator欺骗?
      • 在整个交易过程当中,alice 只签名了两次
        • 第一次签名用于证明了自己掌握了某个 output,过程与使用钱包 连接dapp的过程一致,签名消息都是明文。
        • 第二次是对整个池子 coinjoin 进行签名,alice只要验证钱是否有足够的钱转到 bob 和自己的,就可以签名了。
    • coordinator 怎样不被用户欺骗?
      • Coordinator 会对所有用户合格用户进行一个盲签。在我们举的例子当中,coordinator 会对所有 160 bit 的消息进行签名。
    • 混币池子里面其他的用户:无法知道其他的转移对,只知道完整的
    • 盲签的安全性:
      • 为了防止攻击者构造特殊的hash攻击让 coordinator 签名,盲签采用的签名方法应该与 btc 网络当中的签名方法完全不同,这样攻击者无法伪造 tx 签名。

参考链接