Grin++兼莱特币开发人员 DavidBurkett 发文称,找到了实现 Mimblewimble 非交互式交易的方法。他表示,使用 MW 协议最大的困难在于发送和接收方需要进行通信,即要求收发方在进行转账时需要在线,而 DavidBurkett 的提案则能免去这一步骤。随后,他发表了一篇名为《Mimblewimble 中的链下交易(Offline Transactions in Mimblewimble)》一文,介绍了在 Mimblewimble 协议中实现非交互式交易的具体方案,以下为原文。__

Mimblewimble 是一种通过使用 pedersen 承诺、schnorr 签名及一种名为“cut-through”的新技术来改善比特币隐私性和可扩展性的区块链协议。但这些优势也伴随着高昂的代价。到目前为止,创建交易需要发送方和接收方之间进行交互,创建输出并共同对交易进行签名。因此本文旨在提出一种能够最小化对 mimblewimble 可扩展性和隐私性的影响,并实现单边交易的方法。

当前协议

**
**

与比特币相同,Grin 也使用 UTXO 模型。交易通过包含要花费的输入,创建价值相等或较低的新输出,以及签名和创建验证输入所有权的范围证明进行创建。

而与比特币的不同之处在于,Grin 使用的是机密交易,因此输入和输出都是 pedersen 承诺(rG + vH)。与将签名添加到输入不同,Grin 的每笔交易只有一个签名,它是交易内核的一部分。此签名验证了输入致盲因子(以及所有权)的知识,以及输出致盲因子的集体知识。

为使交易有效,必须满足以下条件(此处忽略交易费用及交易补偿):

· 输出承诺的总和减去输入承诺的总和必须等于内核承诺。即 (r_out1..nG +v_out1..nH) - (r_in1..nG +v_in1..nH) = r_kern*G

· 对某些已知消息基点 G 的内核过剩值 (rk = sum(ro1..n) - sum(ri1..n)) 进行签名。

· 范围证明验证无负输出值。

结合以上三点即可证明发送方是输入所有者,且交易中无创建新币。

此协议要求发送方(Alice)与接收方(Bob)进行交互,以构建交易,从而避免暴露彼此输入和输出的致盲因子。此过程分为三步:

1. Alice 用她的输入创建一笔未签名交易,更改输出和范围证明,一个包含输出和输入致盲因子差异的中间内核,并提交给 schnorr 签名的 nonce。

2. Bob 创建他的输出和范围证明,添加他在内核承诺中的份额,以生成实际交易内核,提交给 nonce,并提供交易内核的部分签名。

3. Alice 对她部分的内核签名进行签名,并聚合这两个签名。

尽管此协议运作正常,且 Alice 能够随意向 Bob 转移资金,但交互部分在安全性、可用性和隐私性方面也存在些许挑战。创建交易要么需要用户保持其密钥在线,要么需要某种形式的带外通信,而这就可能会导致隐私泄漏和 MITM 攻击。

创建非交互式交易

**
**

长久以来,大多数人始终都认为非交互式交易在 mimblewimble 中无法实现,因为输出致盲因子知识对于创建范围证明及构建 schnorr 签名必不可少。

因此我们必须先找到一种仅有发送方和接收方能够知道致盲因子,而不会透露给第三方的方法。而 Diffie-Hellman (密钥交换算法)就是此问题的完美解决方案。在此方案中,发送方只需生成一个密钥对,使用接收方公钥执行 ECDH,并生成一个可用作致盲因子的共享密钥。然后发送方可以生成接收方的输出、致盲因子和以及创建有效交易的签名。但此方案也存在两大问题。

第一个问题是,发送方仍需将其公钥和金额传达给接收方,因此我们需要在不影响隐私性的情况下将其作为输出的一部分。但数据提交仍无确切之法。我们不能将它作为内核的一部分,因为它会将内核链接到输出,从而缺乏隐私保护。

第二个问题是,Alice 和 Bob 最后都拿到了资金密钥,这就意味着 Bob 无法成为资金的独立所有者,且无法解决纠纷。我们还需要一种能够验证只有 Bob 可以花费输出的方法。

Grin 新提案

**
**

事实证明,在范围证明中可以加密近 32 个字节的数据。如果我们使用一个已知密钥,如 blake2b (output_commitment),我们就可以公开提交一些其他数据。而且,如果我们在范围证明中“加密”的数据是哈希,那么我们实际上就可以公开提交所需数据。这使得我们可以纳入一个新的数据块(output_data),其中包含:

· 发送方的临时公钥

· 接收方公钥

· 输出值(使用 ECDHE[发送方密钥,接收方密钥] 加密)

· 输出的致盲因子(使用 ECDHE[发送方密钥,接收方密钥] 加密)

然后,我们可以添加以下用于验证输出的共识规则:

· 每个使用 blake2b (output_commitment)的范围证明都必须是可重绕的

· 每个输出必须包含 output_data (其中包含 sender_pubkey,receiver_pubkey 和一些其他加密数据)

· ripemd160 (blake2b (output_data))必须与重绕范围证明数据的前 20 个字节相匹配

节点必须存储所有 UTXO 的 output_data,因此之后当它们被花费时,我们还可以要求一条新的共识规则来验证输入:

· 每个输入都必须包含一个有效签名:sig (receiver_pubkey,input_commitment)

输入和输出可以继续像往常一样被修剪,我们现在提供了一种向接收方发送资金的方法,且保证发送方无法重复花费。

安全性

**
**

因为发送方和接收方都知道输出的致盲因子,所以仅根据内核来验证当前的 UTXO 集是不够的。还必须验证所有最近输入的签名。因此我们建议由新节点来验证最近 X 块的所有输入签名(其中 X = Coinbase 成熟值),因为风险相似。

但这仍然会留下一个如今不可能实现的攻击点。攻击原理如下(假设过去一天的输入签名已验证):

1. Alice 创建一个包含 Bob 输出的交易。

2. Bob 将 Alice 已购买的商品寄给她。

    几天(甚至几年)过去了,Bob 还没有花掉他的资金。

4. Alice 强制对过去一天+1 个区块进行一次大重组。然后她可以将 Bob 的输出发回给自己,因为她知道致盲因子,且未对超过 1 天的区块交易进行签名验证。

虽然从理论上讲,这种攻击使你能够花费任意币龄的币,但它们必须是攻击者之前发送过的币,且未被接收方花费。但如今这种攻击提供的经济效益不太可能弥补得了进行重组带来的代价。不过,为谨慎起见,当你收到大量币时,只要花费掉就可以阻止这种攻击,且只需花费少量额外内核成本。

隐私性

**
**

只要密钥对没有被重复使用,以上方案就不会泄漏任何其他隐私。为确保这一点,我们建议对 output_data 进行一些小修改,以支持某种形式的隐匿地址(ISAP 或 DKSAP)。

支付证明

**
**

目前验证支付已十分简单。要证明一笔支付已完成包括原始输出、范围证明、output_data 以及显示范围证明 MMR 成员身份的默克尔证明。

多签钱包

**
**

目前要安全发送到多签名钱包发送方需要与所有接收方进行交互。而此新提案就消除了这种需求,但代价就是多签名钱包牺牲了隐私性。

其他改进

**
**

由于我们目前找到了能够将其他数据作为部分输出提交的方法,因此我们可以将费用以及其他数据从内核移至 output_data 结构中,这样就能够进行修剪,从而减小区块链的大小。

致谢

**
**

感谢 John Tromp 对重组攻击的详细解释,感谢 Jasper van der Maarel 提供的关于防弹和多签名钱包方面的建议,感谢 Phyro 提出的将内核细节移至 output_data 结构中的建议。同时,还要感谢 Daniel Lehnberg、Antioch Peverell、Pyro 和 Vladislav Gelfer 对此次新提案提供的宝贵反馈。