代表数字货币的不同架构和交易验证方式。
基于账户的数字货币模型。
主要特点
Unspent Transaction Output,基于未花费的交易输出模型,比特币就是采用的这种模型。
主要关注的是资金的来源和去向,每笔交易都有若干交易输入(也就是资金来源),同时也都有若干笔交易输出(也就是资金去向)。一般来说,每一笔交易都要花费(spend)一笔输入,产生一笔输出,而其所产生的还没有被下一笔交易花费的 Output ,就是“未花费过的交易输出”,也就是 UTXO。
主要特点
比特币作为第一个电子现金系统,其使用的最核心的隐私保护措施就是交易假名和地址不可关联,但这是存在一些问题的。
公开账本信息泄露
我们知道,比特币使用的是UTXO,用户的钱包会管理很多地址,这些地址与用户本身没有任何关联,故能实现隐私。但是,由于比特币网络上的账本是公开可查询的,导致交易金额以及交易的历史是可查的。而交易的地址和金额都是明文的,如果不做一些安全措施的话,是可以通过对交易之间的关系以及交易时间的进行分析,是有可能分析出哪些地址是属于哪个用户的。比如,一笔交易中多个输入来自不同的地址但在统一交易中被用于创建输出,那么显然这多个地址就会属于某个单一用户。另外一些交易也会泄露额外的信息,比如交易留言,金额等等。
当然,最核心的问题是,比特币做不到深层次的隐私,由于现在很多时候都涉及到了实名制的问题,一旦某个地址与用户身份进行了绑定,那么等于隐私被暴露了,想再次进行隐私是很困难的,一旦最初的这个地址暴露以后,即使我们更换一个新的地址,把暴露地址中的币转入新地址,新地址和老地址之间关联性就非常明显。即便是自己做的防护措施挺好,但一旦与自己交易的那个地址暴露了,那么就可以从那个地址的持有者里拿到自己的信息。
通讯协议未加密
比特币的通讯协议是没有加密的,因此节点在进行消息传播的时候,是有概率泄露源IP和地址的对应关系的,同样也可以在网络中部署节点监听进行信息收集。
轻量级节点信息泄露
因为不是所有节点都有能力存储完整的账本,还有很多设备客户端是受限制的,比如手机,平板等等,上面使用的是轻量级密码算法和协议,在支付的时候是采用了简化的支付验证(SPV),这种方式不存储完整的区块链,也不验证系统种的所有交易,也可以让支付完成。它只默认连接随机的几个节点,而且只请求给定高度的区块,或者相关交易的过滤区块。这就产生了隐私问题,因为只读取特定交易区块而选择性的进行交易验证。
**假名机制,**比特币这种机制是伪匿名的,叫做假名机制,即用户可以独立生成任意数量的地址,无需注册或者认证,同一用户之间的地址是无相关联的,那么仅仅凭借地址是没法找到用户的。但是就像前面提到的,可以通过对交易历史的分析是可以有很大概率找到联系的。就像网名和实名之间的联系。
这种链条状的交易历史可查会导致如果其中一个节点的信息暴露出来,那么整条交易链上的信息就会暴露出来。
匿名机制,也就是用户什么相关信息都不透露,类似学校表白墙上发了信息,但是要求墙墙“狠狠的”,它发了信息,但是你不知道任何有关它的信息。
之前的交易中,由于交易是可见的,也是交易双方一一对应的,同一区块会存放多个交易,那么可以通过把输入和输出的地址进行打乱混淆,切断交易双方的联系,让别人无法分辨谁和谁是对应的交易双方,从而提升隐私性。
这就是混币,也就是地址混淆。这是不需要修改协议就能一定程度上提高匿名性的有效手段,有效抵抗交易图分析攻击。
但是这也不是完美的,因为如果要混合交易,那么双方的交易量必须得相似,不然还是很容易能找出联系。
也就是找一个可信机构来进行混淆,需要保证该机构不保存任何账本记录,也不认证用户的信息,这样数据外泄的时候就不会减少用户信息泄露。
但是也同样存在一定问题,如,
一些解决方案
解决外部隐私问题,最容易想到的就是随机化,将一些固定的东西进行随机化,如,一定范围内的随机化交易时间,随机化交易手续费,在多个混币机构之间多混几次。这能起到一定程度的保护作用。
这是用来解决机构和用户之间的信任问题,防止资金盗取的。也就是服务机构用自己的电子签名去做承诺,即约定好输入输出地址、混淆资产金额、约定时间等信息,并用混币服务商的长期公钥 对应私钥进行签名。出现问题时,用户就可以打开承诺向其他用户说明情况,进行证明。
接下来是内部地址的不可链接性问题,需要服务提供商在不知道用户输入输出地址对应关系的情况下进行输入和输出阶段。这就用到了盲签名,它可以同时隐藏消息内容和签名请求者的隐私,满足
盲签名的一般做法是,用户随机选择一个随机因子,然后与待签名的消息进行计算,让其与原消息没有关联,从而达到盲化。然后签名者对盲化的消息进行签名,从而不知道签名消息的内容。后续就是解盲签名和公布去盲化签名以及原始消息进行验证了。
也就是无需第三方混币服务商。
用户在网络中找到其他需要混币的用户,通过多方参与者运行协议的方式构造一致的混币交易,确认后进行签名使得交易生效即可。
一般方式
分为协商、混淆、确认、结束四个阶段
同样去中心化混币也存在着一些不足,如寻找其他混币用户困难、容易让外部攻击者混入监听、DOS攻击、女巫攻击等等。
混淆地址很麻烦,那么如果不隐藏地址而是把金额隐藏了呢?这就是私密交易CT,是站在密码学角度的。在CT中,每笔交易的金额会被加密成一个隐藏的数学证明,该证明可以保证交易的输入等于输出,以保持账户平衡,但不揭示金额。
隐藏可以通过加密来实现,但是又要满足可以进行一定的计算,那么自然而然能够想到 HE ,也就是同态加密。另外还需要注意到两个问题,
密码学方法除了可以隐藏金额以外,还可以隐藏交易双方的地址。
隐藏地址:主要思想是,每次发送者要发起一笔交易时,先利用接收者的公钥信息计算出一次性临时中间地址,然后将币发送到这个中间地址,,接收方再利用自己的公私钥信息找到那笔交易,从而进行花费,主要基于 DH 密钥交换。
**密码累加器:**这个是用来判定一个数据是否在某一集合的。主要概念是,将整个集合组合到一个较小的累加器数据中,达到以固定大小的证据证明某元素在累加器中的效果。
也就是零币。
该方案,把比特币换成一个 Zerocoin 币,使用承诺隐藏交易细节,再从另一个比特币地址中换回 Zerocoin 币,割裂输入地址和输出地址的关系。Zerocoin 通过创建两种新的交易类型来扩展比特币:铸币交易 (mint) 和花费交易 (spend)。
主要思想:
用户可以独自进行混币操作,通过铸币交易将资产加入密码累加器,生成私密资产,达到和所有使用 ZeroCoin 的用户共同混币的效果。当用户需要使用之前加入累加器的资产时,根据参数生成凭证,证明自己拥有累加器资产集合中的某一未曾花费过的资产,花费该资产生成等额比特币 。
基本流程如下
允许用户交换一定数量的比特币以制造新的 Zerocoin 币。每个 Zerocoin 币是使用随机数 r r r对序列号 s n sn sn 的币承诺 c m cm cm。即
c m = C O M M r ( s n ) = g s n h r cm = COMM_r(sn) = g^{sn}h^r cm=COMMr(sn)=gsnhr
具体流程大致是
用户可以发出包括接收地址、序列号、和 spend 交易的 proof(证明自己知道秘密承诺 c m cm cm和随机数 r r r),其中 c m cm cm是过去经过铸币的,也就是存在于区块链上,可以通过承诺随机数 r r r打开 c m cm cm以得到币的序列号 s n sn sn。
具体流程大致为
Zerocoin 会构建相应的零知识证明,通过密码累加器累积所有的铸币承诺集合,然后证明该集合中相应的承诺随机数和集合中元素。 但在 Zerocoin 中, 计算累加器的见证 (witness) 需要访问目前为止的所有承诺。
零知识证明并不将花费交易与任何特定的铸币交易 (迄今为止所有铸币交易之间) 相联系。如果验证正确, 并且序列号以前没有被花费, 则将相应量的比特币发送到目的地址
同时缺陷也很多,如无法拆分金额,无法隐藏交易金额和接收方的地址,零知识证明的开销,验证时间大,然后每个节点需要存储的容量也大。
和 Zerocoin 同源的,是针对其缺陷的改进方案。主要使用了zk-SNARKs协议来保证交易之间的不可链接性,同时也对交易金额和输入地址保密。
主要思想:
Zcash是在比特币上增加一套匿名支付机制(DAP, Decentralized Anonymous Payment)得到的货币协议。
DAP 也可以搭建在其他底层货币上,是相互独立的,底层的货币称为 basecoin, 在其之上也增加了 shielded coin 和 transparent coin (unspent basecoin)的概念。相比于 basecoin(BC),shielded coin(SC)的所有权和金额都是隐藏的,暴露在外面的只有一个陷门承诺,其中包含了面值 v v v和暗地址 a p k a_{pk} apk。
同样zcash 也提供了两种交易铸币(Mint)和花费(Pour),铸币负责把BC 转换为 SC,花费则是负责 SC 的支付,同时它可以实现两种货币的转换。
部分细节如下
zcash地址对 ( a p k , a s k ) (a_{pk},a_{sk}) (apk,ask),其中 a p k a_{pk} apk就是所谓的暗地址,假设要铸币值为 v v v的,用户首先随机选取 ρ \rho ρ,设置币的序列号 s n = P R F ( a s k s n ( ρ ) ) sn = PRF(^{sn}_{a_{sk}}(\rho)) sn=PRF(asksn(ρ))(显然序列号不能除拥有者之外的人知道,所以生成的时候是需要用到拥有者的私钥的)。
为了让验证者验证 SC 面值的正确性,需要对此做两次承诺。
铸币的结果则是铸币承诺 c = ( a p k , v , ρ , r , s , c m ) c=(a_{pk},v,\rho,r,s,cm) c=(apk,v,ρ,r,s,cm)和铸币交易 t x m i n t = ( v , k , s , c m ) tx_{mint}=(v,k,s,cm) txmint=(v,k,s,cm)
两步承诺的目的主要是验证 SC 的合法性的时候只需要公开 k , s , v k,s,v k,s,v,即铸币交易,任何人都可以验证,无需展示地址、序列号等信息,达到隐藏的效果。
花费交易 t x p o u r = ( s n 1 o l d , s n 2 o l d , c m 1 n e w , c m 2 n e w , v p u b , π P O U R , ∗ ) tx_{pour} = (sn_1^{old},sn_2^{old},cm_1^{new},cm_2^{new},v_{pub},\pi_{POUR},*) txpour=(sn1old,sn2old,cm1new,cm2new,vpub,πPOUR,∗)
∗ * ∗中包含了新旧SC,输入两个旧的 SC( c 1 o l d , c 2 o l d c_1^{old},c_2^{old} c1old,c2old) ,输出两个新的 SC( c 1 n e w , c 2 n e w c_1^{new},c_2^{new} c1new,c2new),以及一个面值为 v p u b v_{pub} vpub的 BC(大小可能为0)。
可以看到交易中还提供了旧 SC 的序列号,用于防止重复花费,当SC被花掉的时候必须要公布出来。
π P O U R \pi_{POUR} πPOURproof 能证明, s n 1 o l d , s n 2 o l d sn_1^{old},sn_2^{old} sn1old,sn2old是两个合法的序列号,也就是它们对应的承诺 c m 1 o l d , c m 2 o l d cm_1^{old},cm_2^{old} cm1old,cm2old存在于账本上,且可以打开;新的承诺 c m 1 n e w , c m 2 n e w cm_1^{new},cm_2^{new} cm1new,cm2new也是可以打开的;输入和输出是平衡的,即 v 1 o l d + v 2 o l d = v 1 n e w + v 2 n e w + v p u b v_1^{old}+v_2^{old} = v_1^{new}+v_2^{new}+v_{pub} v1old+v2old=v1new+v2new+vpub;对于旧SC c i o l d c_i^{old} ciold中承诺的 a p k i o l d a^{old}_{pk_i} apkiold,存在对应的 a s k i o l d a^{old}_{sk_i} askiold。
UTXO模型
浅谈零知识证明:背景与起源
[1]李旭东,牛玉坤,魏凌波等.比特币隐私保护综述[J].密码学报,2019,6(02):133-149.DOI:10.13868/j.cnki.jcr.000290.
[1]张云聪. 高效可扩展的区块链隐私保护技术研究[D].上海交通大学,2019.DOI:10.27307/d.cnki.gsjtu.2019.003618.
[1]张奥,白晓颖.区块链隐私保护研究与实践综述[J].软件学报,2020,31(05):1406-1434.DOI:10.13328/j.cnki.jos.005967.