Pay-to-Contract and Sign-to-Contract Commitment

Table of Contents

1. 背景简介

怎么在 BTC 区块链上提交一个 Commitment 呢?一个可行的办法是在 Tx 的 Output 中使用 OP_RETURN 提交。不过,这种方式会增加 Tx 的大小,增加手续费。

本文介绍其它两种往 BTC 区块链上提交 Commitment 的办法。

2. Pay-to-Contract

假如 Bob 要给 Alice 转一些 BTC,同时 Bob 还想把某个 Commitment 值(如某个文档的哈希值 s)也提交到链上去。

假设 Bob 知道了 Alice 的公钥 A:

A = a * G                   // a 是 Alice 的私钥,A 是相应公钥,Alice 地址由公钥 A 推导出来

Bob 不直接把 BTC 转给 Alice 的地址,而是 把 BTC 转到下面公钥(Q)对应的地址:

Q = A + h(A || s) * G       // A 是 Alice 的公钥, || 表示concatenate

这个公钥 Q 对应的私钥为:

q = a + h(A || s)
    ^          ^
    |          |
    |      Bob 掌握
    |
 Alice 掌握

当 Bob 把 s 值告诉 Alice 后,Alice 就完全掌握了公钥 Q 对应的私钥 q。

这样,Bob 给 Alice 转 BTC 的同时往链上提交了一个 Commitment s。一旦 s 背后的原始文档被 Bob 公开,所有人都可以验证 Bob 确实在这笔转账之前就已经掌握了 s 背后的原始文档(注:如果这个文档记录着某个未公开的研究成果,则 Bob 可以验证他在这笔转账前就掌握了这个研究成果)。

Pay-to-Contract 有个不足: 如果 Alice 暂时不想使用 Bob 给她转的 BTC,则她需要对 s 进行备份(因为计算私钥 q 时需要 s),如果没有备份 s,可能导致资产损失。

2.1. Pay-to-Contract 原始论文

Pay-to-Contract 由 Ilja Gerhardt 和 Timo Hanke 于 2012 年在论文 Homomorphic Payment Addresses and the Pay-to-Contract Protocol 中提出。

论文中描述了 Customer 浏览 Merchant 网站购买东西的场景。图 1 是一种传统的方案,用户提交订单后,Merchant 网站后台生成一个付款地址后返回给用户。这种方式不是很安全,论文作者提出了图 2 所示的 Pay-to-Contract 方案,付款地址由 Customer 端根据合约(前面介绍中的 s )推导出来。

bitcoin_p2c_paper0.jpg

Figure 1: 传统的方案

bitcoin_p2c_paper1.jpg

Figure 2: Pay-to-Contract 方案

3. Sign-to-Contract

前面提到,Pay-to-Contract 有个不足:暂时不花费 UTXO 的话,需要小心备份 Commitment。Sign-to-Contract 可以避免 Pay-to-Contract 的这个缺点。

Sign-to-Contract 的思路是 把 Commitment 嵌入到 Tx Input 中的签名数据中。

回顾一下 ECDSA 签名:

def ECDSAsign(x,m):
    k = deterministic_nonce(x,m)
    R = k*G
    r = R.x mod n
    s = k^(-1) * (m + r*x) mod n
    return (r,s)

签名数据是 (r,s)

签名过程中,有个 R 值,它一般需要随机产生;在 Deterministic ECDSA 中,它是由私钥 x 和待签名消息 m 确定产生的。

对于 Sign-to-Contract,关键步骤就是使用下面值 Q 来替换 R:

Q = R + h(R||s) * G                // Sign-to-Contract 所使用的新 R 值

具体来说,过程如下:

def ECDSAsign2contract(x,m,s):
    k = deterministic_nonce(x,m)
    R = k*G
    e = k + h(R||s)
    Q = R + h(R||s) * G            // Q = e*G,相关于 ECDSAsign 中的 R
    q = Q.x mod n
    z = e^(-1) * (m + q*x) mod n
    return (q,z), R

新的签名数据是 (q,z)

揭秘 Commitment 时,公开 s 背后的原始文档和 ECDSAsign2contract 中的 R 值,这样别人就都可以验证 Commitment 了。

4. 参考

Author: cig01

Created: <2021-11-05 Fri>

Last updated: <2022-01-14 Fri>

Creator: Emacs 27.1 (Org mode 9.4)