MIMBLEWIMBLE:一种改进比特币交易隐私的办法
MIMBLEWIMBLE(无声无息之咒——一种改进比特币交易隐私的办法)
(译者注:Mimblewimble是《哈利波特》中的一种诅咒)
原文作者:Tom Elvis Jedusor
(译者注:这个名字也是哈利波特里伏地魔的法语名,所以推测是一个假名)
2016年7月19日
译者:黄世亮
2016年8月19日
介绍
比特币是第一个被广泛使用的财务系统,任何人都可以拿到并验证系统状态的全部必要数据。它利用一个叫“区块链”的公共数据库保存所有的交易数据以完 成这一壮举,然而真正想要检查系统状态的人必须下载所有数据,并且追溯每一笔交易。同时,大多数这些交易并不影响它的最终实际状态(它们每创建一项输出, 就会销毁一项之前的交易)。
在写这篇文章时,在区块链里包含了近1亿5000万笔交易,其中包含了仅仅4百万笔未花费输出,这些未花费输出被重复记录。
如果审计员只需要检查输出数据本身会更好,但这是不可能的,因为当且仅当输出是一连串“前输出”的最后一笔时才有效,每个输出都连在前一个输出后面。换言之,整个区块链必须通过完整历遍验证才可以确认最终状态。
另外,这些交易是“cryptographically atomic”(加密原子),进入每一项交易的输出是什么、又发生了什么它都会很清楚。“transaction graph(交易图)”会泄露大量信息,并且有许多专业的分析交易的公司,这些公司的商业模式是监管和控制着市场这些交易层。这使得交易非常非私人化,甚 至对用户造成危险。
现在已经提出一些解决方案。Greg Maxwell发现加密交易金额可使交易匿名化,但仍允许其他人确认金额是否正确[1]。Maxwell博士也创造了CoinJoin,一个比特币用户可以混合多笔交易,使得交易关系混淆不清的系统。Nicolas van Saberhagen开发了一个可以蒙蔽交易输入的系统,进一步混淆交易关系(同时不必进行混币)[3]。之后,Noether结合这两种方法得到了“Maxwell的‘机密交易(Confidential transactions)’和van Saberhagen的暗箱操作”[4]。
这些解决办法很好,它们会使比特币使用起来非常安全。但问题在于大量数据因此而变得更糟。机密交易(Confidential transactions)的每一个输出需要多字节的证明, van Saberhagen签名要求保存每次输出,因此其不可能明确交易到底是什么时候完成的。
Maxwell博士的CoinJoin已经出现需要互动(译者注:CoinJoin需要多个用户参与混币以参建机密交易)的问题。Yuan Horas Mouton博士通过制造可自由合并交易解决了这一问题[5],但是他需要使用基于配对的密码,这些密码潜在地延缓了交易,这更难置信。他称这为“单向聚合签名”(OWAS)。
单向聚合签名是一个很好的办法用于混合区块里的交易。想象一下,我们可以通过跨区块来进行混合交易(也有可能是粘合数据),所以当输出产生和销毁 时,这和它从未出现是一样的。然后,为了验证整个链条,用户只需知道钱什么时候进入系统(每个区块的区块奖励产生的新币,或者是Monero,或者是用于 侧链楔入锚定的比特币[6]) 以及最终什么时候成为未花费输出,剩余可能被转移、遗忘。然后,我们可通过机密交易隐藏金额和单向聚合签名,进而模糊交易图,并使用更少空间(与现在的比 特币区块链相比)让用户充分验证区块链。进行再次想象,我们不需要基于配对密码或新猜想,仅使用类似比特币的普通散列数签名。这里是我的建议。
因为它被用来防止区块链泄露所有用户的信息,我称我的发明为Mimblewimble[7]。
机密交易和单向聚合签名(OWAS)
我们首先要做的是移除比特币脚本。这听起来很悲伤,但它太强大了,因此使用通用脚本混合交易是不可能的。我们将证明Maxwell博士的机密交易 (经过一些小的修改之后)足于构建花费,甚至无需交互就可混合交易。单向聚合签名(OWAS)也同样如此,它允许中继节点收取一些交易费或让接收人改变交 易费用。我们可以免费实现比特币无法实现的这些额外功能。
我们首先向读者解释机密交易是如何工作的。首先,通过以下方程将金额编码:
C = r*G + v*H
其中,C是一个Pedersen commitment(译者注:从上下文章意思来翻译C是一个通过ECDSA算法加密后的交易金额),G和H是与椭圆曲线加密函数(ECDSA)生成的无 关的固定值,v 是金额,而r 是一个秘密的random blinding key(随机盲密匙)。(译者注:这个公式是将交易金额进行加密。比如真实的交易金额是1BTC,那v=1BTC。C是经过ECDSA算法加密后得到的一个金额,以隐藏真实金额。G和H两个参数也是ECDSA算法生成的两个值,r类似于密码,G、H和r三者齐聚时才有可能从C推导出v。)
和输出相联系的是一个rangeproof(译者注:暂时不清楚这单词该怎么译。非译不可推荐使用“范围值”),v的取值范围是[0, 2^64], 所以用户不能利用暴力计算来破解。
为了验证一笔交易,验证者将会加上所有输出,加上f*H(f是明确给出的交易费用),再减去所有输入费用。其结果一定是0,意味着整体交易未产生或破坏。
我们注意到,要创建该交易,用户必须知道所有“commitments entries” (译者注:暂时不清楚这单词该怎么译,commitments这一词在本文多次出现,后面我一律保持原文。)的r值总和。因此,r值(及其总和)就可以充当密匙的功能。如果我们可以使r输出值仅对收款人可知,我们有一个认证系统!不幸的是如果我们遵守规则,所有“commits” (译者注:暂时不清楚这单词该怎么译)加起来等于0是不可能的,因为打款人知道其r值总和,因此也会知道收款人r 值加起来是负数。因此,我们允许交易总和为一个非零值K * G,并需要一个空字符串签名,以其为密匙,进而证明其金额部分为零。
我们让交易拥有其所希望的尽可能多的K * G值,每个值都附有签名,并在验证过程中将它们加起来。
创建交易时,交易的打款人和收款人应当遵循以下规则:
打款人与收款人就交易金额达成一致。这称为b。
打款人使用所有输入创建交易,并且改变输出,并且将“total blinding factor”(译者注:暂译成“全盲因子”)(r值的变化减去r值的输入)随着这次交易一起发送给收款人。所以,“commitments”总值为 r*G – b*H。
收款人随机选择r值作为其输出,所有值加起来等于b减去交易手续费,然后将其全部加入到交易中(包括取值范围)。现在投入总和为k*G – fee*H,仅收款人才知道k。
收款人将使用k来签名加入到交易中,并且给出明确的手续费。这样整个交易就完成了。
现在,以这种方式创建的交易已经支持单向聚合签名(OWAS)。为了进行演示,假设我们有两笔交易,有剩余(译者注:原文的“have a surplus”我译为“有剩余”,这是我能找到的阅读最为通畅的译文)的k1*G和k2*G,这些都附上签名。然后,可以将两笔交易的输入和输出混合起来,将k1*G和k2*G 相互混合,这样再次成为一笔有效的交易。这笔混合后的交易中的输入值和输出值不可能找到对应的原始交易中的输入和输出
正因为如此,我们将我们比特币区块格式改为以下信息:
数量明确的新货币(区块奖励或者用于侧链楔入锚定的比特币)和其他需要的数据。如果是一个侧链锚定就涉及到一笔交易,这笔交易提交了一个特定的 k*G值吗?(译者注:原文这里确实是一个疑问句,可能作者也对此保持有拿不准的成分。)
所有交易的输入。
所有交易的输出。
所有交易中的k*G值 。
因为其原始交易边界是什么并不重要,这些都是混合在一起的。此外,清单2、3、4中的值应该按字母表的顺序依次排列,因为它可以快速检查并且防止区块的创建者泄露任何原始交易信息。
请注意,我们可以通过输出值的哈希散列值来识别出它们,而不是在交易中的位置,因此这很容易被改变。所以,为避免混淆,应该禁止相同的两项未花费输出同时进行。
跨区块混合交易
现在我们已经使用Maxwell博士的机密交易去创建一个非交互式版本(译者注:这里的非交互式noninteractive version从上下文来理解应该是指不需要多人合作来混币)的Maxwell博士的CoinJoin,但是我们并未看到最后的奇迹。他说,我们需要其他主意,即,交易裁减(译者注:原文为:transaction cut-through)[8]。再次,我们创建一个非交互式版本,并展示它是如何和几个区块一起使用。
我们现在可以将每一个区块都想象成一个大的交易。为了验证这一点,我们把所有输出commitments看作为一个整体,然后减去所有输入的 commitments、K*G值、所有明确的输入量次数H。我们发现,可以由两个区块混合成新的交易,当我们把单个区块内的交易混合起来时,结果又会是 一项有效交易。除此之外,当把第一个区块中的输出放到第二个区块中时,一些输出commitments完全等于它们的输入commitments。我们去 掉这两个commitments时,仍会得到一笔有效交易。事实上,不必检查被删除输出的rangeproof。
将这个设想拓展到从创世块延伸到最新的区块,我们可以看到每一个非显性的输入连同和它相关的输出都被删除了。剩下的将只有未花费的输出,显性的输入 总额和每一个K*G值。将所有这些数据都好像可以作为一笔交易:将所有的未花费输出commitments,减去K*G值,验证显性的输入总金额(如果这 里有任何东西需要验证的话),然后减去它们的次数H。如果总和为0,则可判断整个区块链是正确的。
这是什么意思呢?当一个用户启动和下载整个区块链时,需要依据每一个区块下面的数据:
数量明确的新币(区块奖励或侧链锚定币)和其他需要的数据。
所有交易的未花费输出,连同每个输出的merkle proof 都将出现在原始区块中。
所有交易的k*G值。
比特币现在大约有423000个区块,占80GB的硬盘空间,这些数据可以对所有交易进行验证。这些数据是一亿五千万的笔交易和500
万未花费的非保密输出值。如果相同的交易量在Mimblewinmble链上,来估算下需要占用多少空间。每笔未花费的输出需要3Kb空间来存储
rangeproof 和Merkle
proof,每笔交易也需要占用100字节来存储:一个K*G值和一个签名。区块头和显性的总金额可以忽略不计。所有这些加起来一共需要30GB——包括
所有的机密交易和桂花糕的交易图!
问题和直觉
最近几周以来,我做梦会梦见一些问题,醒来总是一身冷汗。
事实上情况还好。
问题:如果你删除了交易的输出,用户不能验证rangeproof,因此可能产生一个负金额。
回答:这没有问题。验证过所有交易后可证实所有负金额会被抵消的。正是因为过去没有发生非法的通胀,用户才可以安全地使用SPV,用户知道现在也不会有通胀。
问题:如果你删除了输入,就会发生双花。
回答:事实上,这就意味着:可能会有一些人声称在有未花费的输出在之前被支付过。但这是不可能的,否则混合交易的总金额就不可能是零。
存在一种例外情况,当输出总金额为零时,有可能是两笔输出正好正负相反,则这一对数据就可以被再次使用。所以,为了防止一致性问题,应该禁止输出总额为0的交易。仅仅需要在每个输出上加H,这样所有金额至少是1。
未来研究
下面是一些在此次写作时我无法回答的问题。
哪种脚本支持有这种应用?我们需要将脚本运作转化为某种形式的离散值信息。
我们需要用户去检查所有的k*G值,事实上他们所需要的所有数据都来自于k*G。不使用签名,是否存在可被混合的其他离散值证明?
当用户下载区块链时会有一个拒绝服务选项,攻击者会给出字节数据并且提供错误的未花费输出。用户将会看到,最后相加后的结果不等0,但却找不到问题在哪。
现在用户可能仅是从Torrent或者从其他用户共享的数据下载区块链,这种情况应该是可以获得正确的数据。
(译者注:译文docx和pdf版本可在百度网盘下载链接: http://pan.baidu.com/s/1o8dEf7G 密码: 7jes)
[[2]] https://bitcointalk.org/index.php?topic=279249.0[[2]]
注释 (↵ returns to text)
https://people.xiph.org/~greg/confidential_values.txt↵
https://cryptonote.org/whitepaper.pdf↵
https://eprint.iacr.org/2015/1098.pdf↵
https://download.wpsoftware.net/bitcoin/wizardry/horasyuanmouton-owas.pdf↵
http://blockstream.com/sidechains.pdf↵
http://fr.harrypotter.wikia.com/wiki/Sortilège_de_Langue_de_Plomb↵
https://bitcointalk.org/index.php?topic=281848.0↵
声明:此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。本网站所提供的信息,只供参考之用。
-
被币圈收割的VC们...
2024-12-26 -
2025年:以太坊将如何迎接 AI 智能体与重大升级的突破?
2024-12-26 -
Blockworks:2025年加密领域将有哪五大变化?
2024-12-26 -
揭秘加密 ETF 未来趋势
2024-12-26 -
Outlier:以太坊六大L2激励效果研究 为何新L2空投后留不住用户
2024-12-24