详细讲解:零知识证明 之 ZCash 完整的匿名交易流程
作者:林冠宏 / 指尖下的幽灵
博客:http://www.cnblogs.com/linguanh/
掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8
GitHub : https://github.com/af913337456/
注:发现掘金的图片屏蔽了博客园获取,导致我的一些文章在博客园这里的图片显示不了,因为现在我的文章是我首发在掘金的
目录
- 前序
- 交易体的结构 note
- commitment 和 nullifier
- ZCash 1.0 的公私钥机制
- 转账人发出交易 note
- 收款人如何获取 note 的使用权
- 零知识自证
- 后记
前序
在这篇文章中,我将承接上一篇文章 详细讲解:零知识证明 之 zk-SNARK 开篇 (开篇中介绍了什么是零知识证明及其它术语) 来从一个完整的交易流程
讲解 ZCash
是如何利用零知识证明
的zk-SNARK
实现匿名交易的。
其中第六
部分 收款人如何获取 note 的使用权
是目前国内网上所有的介绍 ZCash
的文章都没有谈及的,造成了读者只知道交易的发出
,而不知道交易是凭借什么机制让收款人有权限使用的
。
此外,"现在关于 ZCash 的文章和回答,很多都不准确,甚至是有误导性的!"
此话---引自 woodstock
文章不从源码分析的角度去展开,那样的写作和阅读成本太高。
交易体的结构 note
首先 ZCash
在交易的整体模式上,参考了 BTC
的 UTXO
模型,拥有交易输入和交易输出的概念,对于 UTXO
的讲解,可以自行网上搜索文章进行阅读,目前介绍 UTXO
的优秀文章还是很多的。
UTXO
是一种模型,模型是可以被以不同的形式展现出的。在 ZCash
中,交易原始的输入输出结构体被形象成了代码中的 note
结构体。
一个完整的 note
包含有如下的变量:
- 持有者的公钥: a_pk,又称收款人地址
- 面额: value,又被简称为 v,代表这笔 note 的代币数值
- 随机数: rho, 是每一条 note 的唯一标识,当一条 note 被消费了之后,这个值会被放置到
nullifier
表中,代表这条 note 已经被消费了,再次进行消费同一条 note的时候,会触发双花
错误,即交易双花防护机制。 - 随机数: r
用向量组代表上面的 note,可以表示为:note = <a_pk , v , r , rho>
commitment 和 nullifier
在 ZCash
中,存在两种表格,分别是:commitment
和 nullifier
,下图取自于 ZCash
的官方文档 How Transactions Between Shielded Addresses Work 中,提示
:该文章内部并没有指出 note 的收款人是如何对一笔 note 有使用权限的,看完也会有很多疑问。
图中显示出了 commitment
和 nullifier
表格的大致结构:
左边的 hashed notes
就是 commitment
列表,右边的 nullifier set
就是 nullifier
列表。
commitment
列表存储的是所有的,注意!是所有。存储所有 note 经过不可逆 hash 函数后生成的 hash 值 Hx
x∈ (1,2,3,4,5,6...N)
nullifier
列表存储的是已经被消费
的 note 中的随机数 r
生成的 hash 值 nfx
。r 就是 note 结构中的 r。nullifier
中文意思:作废
,nullifier set
作废集合。
注意一点
:对于两个不同的 note,他们的 commitment hash 值一定不相同,从 hash 值又无法推测出其背后的 note.。
如上图所示,在右边我们可以看到 r2 对应的 note2 的 nf1 已经被记录到了 nullifier
列表中,这个 nf1 就是结构体中的 rho。被记录到了这里,代表着 note2 不再是 UTXO
,不再是没被花费的输出,它已经被消费了。
一条被花费的输出 output
会导致一条新产生的交易输入 input
。继续以上图为例子,note2 作为被消费了的输出,据表可以, note3 应该是它所产生的交易的输入,此时 note3 还没被消费,因为它的 nf3 还没被记录到 nullifier
列表。note2 相对于 note3 来说,note2 是 note3 的输入。note3 作为一条新的交易输入,还没输出给其它的 note。
ZCash 1.0 的公私钥机制
在认识交易被发出前的操作,我们现来认识下 ZCash 1.0
的公私钥机制,下图取自于官方文档:
下面我将讲解下这图的主要要表达的意思,上面我列举的 note ,是一个整体的讲解,在实际的 ZCash
源码中,note 其实还分为两种,分别是:SproutNote
和 SaplingNote
。目前 ZCash
使用的是第一种,本文所谈的也是 SproutNote
。ZCash
的发展将会慢慢向第二种 SaplingNote
迁移。
因为 note 结构中有一个 a_pk 字段,在SproutNote
和 SaplingNote
中,内部的字段组成是不同的,源码的定义如下图所示:
SaplingNote
中,明显 a_pk 不见了,多了其它的。回到下图,我们主要看左边的 Sprout
,其中:
- 双竖线表示相同
- 箭头表示生成关系,如果 A 指向B, 那么表示A可以生成B。
下图的Sprout
中 a_sk 代表的是私钥,由 a_sk 可以生成第一个公钥 a_pk
和 私钥 sk_enc
,由 sk_enc 可以生成第二个公钥pk_enc
。意味着:
在ZCash 1.0 中,一个钱包地址里面包含由两个公钥:a_pk , pk_enc
转账人发出交易 note
现在进行到转账人发出交易 note,假设转账人是A,收款人是B,A 要转 5 个币个B。
那么 A 组装 note 的过程如下:
- 首先 A 找到自己的一条或多条没消费的 note,即是
UTXO
输出,每条 note 中有对应的 value,我们假设一条就足够转出,多条的情况是如果一条 note 无法满足目标转出 value,才会凑多条 note 作为输出。 - A 找出了 note 1 ,使用自己的
私钥 sk_enc
解密 note 1,获取 note 1 中的 value 和其它数据,假设 value 是8,此时8 > 5
。 - A 先新建两条 note,分别是 note4 和 note5,note4 内部的 value 设置为 5,代表是要给 B 的。note 5 的 value 是 (8-5=3),代表给自己找零,不找零将会损失掉这3个币,相关的
找零
解析见UTXO
模型介绍。 - A 为 note 4 和 note 5 分别生成随机数 r4 和 r5
- A 将 B 的 a_pk 公钥设置到 note 4 里面去, 代表收款人是 B。再将自己的 a_pk 公钥设置到 note 5 里面去,代表收款人是自己。
- 使用 hash 函数生成 note 4 和 note 5 的 rho。
PS: ( rho = nf = HASH (r) )
- 此时 note 4 和 note 5 分别是:
note4 = <B的a_pk ,v=5,r4,rho4>
note5 = <A的a_pk ,v=3,r5,rho5>
- 与此同时,A 还要将 note 1 的 nf2 (
nf2=HASH (r1)
) 发往公链的节点网络,即 note 1 的 rho,此时节点在收到 nf2 后会判断是否已经在nullifier
列表存在 nf2 了,是的话,那么判断 note 1 被双花了。否则,就将 note 1 的 nf2 记录下来了。 - A 此时使用 B 的 pk_enc 签名 note 4,和自己的 pk_nec 签名 note 5。这里 B 的 pk_enc 是公开的,注意!ZCash 1.0 中,一个地址的 a_pk 和 pk_enc 都是公开的。
- A 将 note 4 通过秘密通道发给 B,自己的 note 5 便自己保存,同时将 note 4 和 note 5 的 hash 值 h4、h5 发给所有链上的节点。
- 以上便是一个
发起交易
的流程。
对上述流程可以提出下面细节。
- 节点能够知道的只有 note1 的 nf2 和 note4 的 h4 和 note5 的 h5。他们对收款人地址,金额是多少都一无所知。
- 此时链上节点们维护的
commitment
和nullifier
表变成了如下的样子。
note hashs(commitments) | nullifier set |
---|---|
h1=HASH (note1) | nf1 = HASH (r2) |
h2=HASH (note2) | nf2 = HASH (r1) |
h3=HASH (note3) | |
h4=HASH (note4) | |
h5=HASH (note5) |
- A 发给 B note4 的秘密通道。这里我们不展开说,它的方式有很多,可以在用加密的电子邮件传送,或者可以面对面传递小纸条。具体见官方完整的文档:完整文档
- B 手上有经过了自己的 sk_enc 签名了的 note4
收款人如何获取 note 的使用权
其实在上面小节中,读者应该能理会到 B 是可以使用自己的原始私钥 a_sk 对自己获取到的 note4 数据进行解密的,进而获取到里面的 <a_pk,v,r,rho>,到了这一步,B 保存好 note4 的 rho,那么他就能够向 nullifier
表发送 note4 的 rho ,达到消费 note4 的目的。
至此,ZCash 的匿名交易流程形成了闭环
。
那么为什么 a_sk
能对 sk_enc
签名的数据,进行解密呢?因为在 ZCash 1.0 中,由地址的公私钥生成规则,可知原始私钥 a_sk 可以导出 sk_enc。在ZCash 1.0 的公私钥机制
小节中也做了说明。
零知识自证
- 节点在校验完了一个 note 的 rho 后,如何判断发送者是真正对 note 拥有使用权的?
答:对于 note 的所有权拥有者A 来说,好像除了公布 note 里面的内容外,好像没其它手段来自我证明?这个时候零知识证明
就排上用场了,note 的拥有者在发布使用该 note 的时候还要向节点出示称为 Π
的零知识证明凭据,根据 Π ,节点们作为验证者,能够验证 note 的使用权的确属于A。ZCash 在这里应用到了零知识证明
,它的代码是根据zk-SNARK
理论完成的,同时也参考了 Zerocash
。
- PS:如何统计一个地址的余额?
答:不在本文的讨论范围内,详细可以见官方完整的文档:完整文档 的第4章
,关于 Balance 的描述。
后记
为了理清 ZCash 的匿名交易的最后一部分,也即是收款人是如何获得 note 的所有权的,使整个流程形成闭环
。
我查阅了很多文章都、文档和咨询了一位网友已经查看了部分源码。目前网上的其它文章都没有讲到 收款人如何获取 note 的使用权
这一部分。稍微较好的是对官方文档 在隐藏地址之间如何进行交易的直接做了翻译,但是由于官方的这篇文章是个简版,也没有对 收款人如何获取 note 的使用权
做出解析,所以,几乎所有的翻译文章都是没答案的,而且大部分文章,本身还有一些错误,可能作者自己也一知半解。
感谢下面的人和文给予了我有用的信息引导:
人:woodstock
文:
- https://z.cash/zh/blog/zcash-private-transactions/
- https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
- https://zhuanlan.zhihu.com/p/25168970
- https://zhuanlan.zhihu.com/p/58006716
- https://blog.csdn.net/lvbin2012/article/details/87339907
转载于:https://www.cnblogs.com/linguanh/p/10911822.html
详细讲解:零知识证明 之 ZCash 完整的匿名交易流程相关推荐
- 一篇文章讲清什么是零知识证明
作用 抽象领域 零知识证明是打通链上数据与链下计算的关键技术,也是实现链上数据隐私保护的重要途径. 零知识证明技术可以解决数据的信任问题,计算的信任问题! 具体领域 数据的隐私保护:在一个数据表格中, ...
- 不是程序员也能看懂的ZCash零知识证明
交易过程完全匿名是数字货币ZCash最大的亮点,正是这一点使得ZCash自提出以来便备受关注.ZCash匿名交易的实现依赖于一种叫做"零知识证明"的密码学手段.本文将通过打比方的手 ...
- ZCash零知识证明
交易过程完全匿名是数字货币ZCash最大的亮点,正是这一点使得ZCash自提出以来便备受关注.ZCash匿名交易的实现依赖于一种叫做"零知识证明"的密码学手段.本文将通过打比方的手 ...
- ZCash的零知识证明
交易过程完全匿名是数字货币ZCash最大的亮点,正是这一点使得ZCash自提出以来便备受关注.ZCash匿名交易的实现依赖于一种叫做"零知识证明"的密码学手段.本文将通过打比方的手 ...
- 零知识证明学习资源汇总
本文将继续会持续进行更新,更新后的版本将在 Github 和知乎上发布,欢迎关注. Github 地址:https://github.com/sec-bit/learning-zkp/blob/mas ...
- 【区块链基础知识系列】 第8课 区块链之零知识证明
所谓零知识证明,指的是示证者在证明自己身份时不泄露任何信息,验证者得不到示证者的任何私有信息,但又能有效证明对方身份的一种方法. 从本质上讲,零知识证明是一种协议.所谓协议(Protocol),就是两 ...
- 零知识证明实践教程,第一部分
本文和其他博客文章的区别: 现今存在很多讲解零知识证明的文章,但是它们都是只涉及到很浅层的概念理解和直观感受上面,没有深入到零知识证明的细节,导致读者只知道什么是零知识证明,而不清楚怎么构造一个零知识 ...
- 区块链交易隐私如何保证?华为零知识证明技术实战解析
摘要:本文通过介绍华为如何在同态加密及零知识证明框架的集成介绍来介绍了一些对金融领域交易隐私保护的思路,通过代码结和应用场景描述了zksnark如何集成到现有联盟链体系保护交易隐私. 本文分享自华为云 ...
- 零知识证明 - zkSNARK入门
网络上讲解零知识证明的文章就不多,这些文章要不太浅显,要不太深入,很少有能给入门者整体框架上的认识. 比如,阿里巴巴零知识证明就是一个非常好的通俗理解零知识证明的例子: 阿里巴巴被强盗抓住,为了保命, ...
最新文章
- ansible笔记(11):初识ansible playbook(二)
- html底部导航_松鼠导航 | 优质资源网站荟萃
- java递归深度克隆_递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝。...
- 配置FTP服务-要点总结
- sqlserver 集群_云数据库最优成本方案,阿里云数据库新形态专属集群
- C++语言基础 —— STL —— 容器与迭代器 —— list 与 deque
- Copy++ 复制 PDF、CAJ 内容时,自动删除空格、空行,以及自动翻译[Win]
- Sentinel热点Key降级上_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0042
- TCPIP header
- [黑金原创教程] FPGA那些事儿《设计篇 I》- 图像处理前夕
- python gif压缩_压缩gif的正确姿势
- 实验二 译码器及其应用
- wex5 checkbox
- Android之Realm详解(非原创)
- 模电_数电_微机接口_微机应用实验装置,QY-MS535F
- 系统上公有云安全需要考虑什么?
- Generative Adversarial Registration for Improved Conditional Deformable Templates 论文
- MySQL主外键设置
- 解决CSR 8510 A10蓝牙适配器驱动安装不正常问题
- 什么文案才算得上好文案