wade12138 的Zcash-sapling分享

前序

有疑问,欢迎留言;由错误,欢迎指正;都没有?不存在的,错误!一个都不能少。
														    -----代号韦德

缘起

在一次关于zk-snark的组内分享小会上,俺把个人理解的zk-snark数学原理一点一点讲了一遍,虽然有些知识点被一笔带过(自己还没闹明白,寄希望于各位读者指教一二,先谢为敬!),但还好大家都表示听明白了,大概懂了有3、4成吧,甚感欣慰。
中间,大家也提出了zk-snark在zcash上应用的一些疑问,我都没成功答疑(我有什么办法,我也不知道呀)。但是,也不能”不会、不学、不练“不是,于是带着以下几个疑问,开始了149页的协议学习研究征程。
1. Zcash是如何隐藏发送方的?
2. Zcash是如何隐藏接收方的?
3. Zcash是如何隐藏交易金额的?

附上协议说明书链接:[zcash protocol Specification](https://github.com/zcash/zips/blob/master/protocol/protocol.pdf)
**note:**阅读本文前,您需要事先了解:
1.  zcash的交易的基本单元note;
2. 零知识证明的基本概念;

您好,Zcash!

经初期了解发现,迄今为止,Zcash总共经历了三个版本的迭代,第四次版本升级时间预计在10.28.2019,据官方介绍,此次更新主要是缩短了出块的时间。各版本升级的相关信息如下图所示,更详细内容可见链接[zcash upgrade information](https://z.cash/upgrade/)。

Sapling

为何先从Sapling讲起?因为Sprout的总结还需完善。不过这并不影响各位对此次分享内容的理解。无论是Sapling版本,还是Sprout版本,交易的整体流程都可以简要概括为以下四个步骤:
1. 交易者发起交易;
2. 交易者生成zk-proof,和signature;
3. 验证者验证zk-proof,和signature;
4. 接收者接受交易;
接下来,我们将尽量仔细挖掘每一个步骤,把第二小节的灵魂三问,带到Sapling协议中去,去探索一下,它是做到这三点的。	

交易者发起交易

在这里,我们不详细介绍交易发起者是如何发起一起交易的,我们直接介绍Sapling中的交易结构,如图所示:	

在这里插入图片描述

实际上,Sapling的交易结构内容不止这些,在这只是罗列出Sapling特有的一些字段及相应的解释,完整的交易结构在协议说明书的7.1章节有详细介绍。
在Sapling中,交易由Spend Transfer和Output Transfer组成,分别对应隐匿的输入和隐匿的输出,而spendDescription和output Description是用来分别描述Spend Transfer和Output Transfer的数据字段,它们被各自编码表示成vShieldSpend和vShieldOutput字段储存在交易结构中。接下来,重点介绍vShieldSpend、vShieldOutput、valueBlance、bindingSig四个字段表示的内容。
1. vShieldSpend
	一个vShiledSpend对应着一个SpendDescription,一个可靠的SpendDescription表示一个note的有效花费,它包含的内容如下图所示:
	cv:对Inpunote 的value的承诺,所谓承诺,其实就是对v值的一种隐藏,这种隐藏是单向的,不可逆的,也不可伪造;
	anchor:cm默克尔树的根,用于验证inputnote的存在性及有效性;
	nullifier:note的唯一性标识,用来防止同一note被重复花费;
	rk:用于验证消费授权签名;
	zkproof:零知识证据,在不透露相应隐私的情况下,证明note的有效性、花费note的权力、隐私地址的有效性
	spendAuthSig:用私钥对spendDescription签名,对note的花费进行授权

在这里插入图片描述

2. vShieldOutput
	同理,一个vShiledOutput对应一个OutputDescription,一个可靠的OutputDescription表示产生的新note的有效性,它包含的内容如下图所示:	
	cv:对outputnote 的 value的承诺,亦满足单向性,不可伪造性;
	cmu:对outputnote的承诺,承诺的数学形式是曲线上的一个点(u,v),cmu为点的u坐标;
	ephemeralKey:临时公钥,用于计算解密密钥
	encCiphertext:noteplaint的密文,noteplaint是note的具体内容;
	outCiphertext:用来计算共享密钥的信息密文,可用来恢复noteplaint信息
	zkproof:零知识证据,在不透露任何隐私的情况下,证明新生成Note的有效性

在这里插入图片描述

3. valueBlance
	valueBalance表示此transparent value pool的变化量,由Spend Transfer的v总和减去Output Transferd的v的总和得出。当valueBalance 为正数时,表示从Sapling value pool转移valueBalance至transparent value pool,如果为负数,则执行相反的操作。  
	valueBalance将在bindingSig中,用于验证交易的balance 属性。
4. bindingSig
	在Sapling中,bingingSig发挥两个作用。第一,保证了交易的balance属性;第二,利用计算输入和输出note cv的随机数rcv,来生成签名私钥,防止outputDescription被攻击者进行重放攻击(spendDescription的防重放攻击由spendAuthSig来保证)

交易者生成zk-proof,和signature

在Sapling中,交易者总共要生成两个zkproof(spend zkproof & output zkproof)和两个签名(spendAuthSig & bindingSig)。下面逐个介绍。
1. spend zkproof
	spend zkproof 主要是实现了在不暴露任何隐私信息的场景下,去证明txsender有权力去花费一些note,并且这些note都是有效的。输入分为两个部分,一个是primary input, 一个是Auxiliary input。primary input是公开的输入信息,Auxiliary input是隐私的输入信息,只有txsender知道。具体内容如下图所示:

在这里插入图片描述

根据上图可知,spend zkproof总共证明了以下几点:
	Note commitment integrity:inputnode的承诺的完整性,证明cm确实根据v,rcm,gd,pkd计算出来的;
	Merkle path validity:默克尔树验证路径有效性,证明cm是存在默克尔树上的,是一个有效的cm;
	Value commitment integruty:inputnote v的承诺完整性,证明cv确实根据rcv,v计算出来的;
	Small order checks:证明私有参数,gd和ak是合法的;
	Nullifier integrity:Note的唯一标识,证明nf确实根据nsk,cm,pos计算出来的;
	Spend authority:Note的花费权力,证明拥有花费note所需的私有参数;
	Diversified address integrity:	一次性地址的计算完整性。
若以上等式均能满足,则说明txsender有权力花费对应的Note,因为等式4,6,7成立;其花费的note是有效性,因1,2,3,5成立。
2. output zkproof
	output zkproof 主要是实现了在不暴露任何隐私信息的情况下,去使得validator相信txsender所产生的新note是有效的。输入仍分为两个部分,一个是primary input, 一个是Auxiliary input。primary input是公开的输入信息,Auxiliary input是隐私的输入信息,只有txsender知道。具体内容如下图所示:

在这里插入图片描述

根据上图可以看出,output zkproof总共证明了一下几点:
	Note commitment integrity:outputnode的承诺的完整性,证明cm确实根据v,rcm,gd,pkd计算出来的;
	Value commitment integruty:inputnote v的承诺完整性,证明cv确实根据rcv,v计算出来的;
	Small order checks:证明私有参数,gd是合法的;
	Ephemeral public key integrity:临时公钥的计算完整性。
若以上等式均满足,则说txsender产生的新note是有效的,因为等式1,2,3均成立;等式4成立则可以保证txreceiver可以根据自己的ivk密钥和epk去解析加密后的np,并保存到本地的集合当中。
3. spendAuthSig 
	关于spendAuthSig 的意义,可在两种场景下,进行描述。
	第一:txsender自己产生zkproof,然后对spendDescription进行签名。这时,如果存在一个攻击者,想对spendDescription进行重放攻击,则其需要重新签名,则rk会被替换,那么验证者在验证spend zkproof时,就会验证失败;如果攻击者不替换rk,那么spendAuthSig的验签就会失败,因此spendAuthSig的存在,有效规避spendDescription的重放攻击;
	第二:txsender调用第三方产生zkproof,然后自己对spendDescription进行签名,这是Sapling版本允许的,为了让内存和计算能力受限的一些钱包也能支持隐私交易,即使这样损失了隐私性,因为需要把auxiliary input全部发送给第三方。因此,在这种情况下,为了不让第三方恶意产生有效的zkproof,txsender需要对spendDescription进行签名,需要注意的是,txsender签名用的是ask,zkproof中spend Authority的证明用的是ak(ak可由ask计算得出),因此第三方无法产生有效的签名,有效规避spendDescription的重放攻击。
	spendAuthSig的签名流程如下图所示:

在这里插入图片描述

4. bindingSig
	如前面所说,bindingSig主要实现了两个功能。
	第一:在不暴露spend Transfer 和 output Transfer的v值的情况下,保证了transaction balance;
	第二:防止了outputDescription被攻击者重放,主要是利用spendDescription 和 outputDescription对应的用于计算cv的随机数rcv来产生签名私钥bsk,这使得攻击者无法作恶,因此签名验证公钥是利用spendDescription 和 outputDescription对应的cv来生成的,攻击者无法改变cv,否则zkproof会验证失败。
	bindingSig的签名验签流程如下图所示:

在这里插入图片描述

验证者验证zk-proof,和signature

对于zk-proof的验证和签名的验签,本篇不做详细的分享。zk-proof的验证过程,将会在本人的其他文章中涉及;两种签名的验签流程第二部分也有涉及,读者如有疑问,可留言交流^_^.

接收者接受交易

txReceiver接收交易的一般步骤为:
接收者遍历每笔交易的outputDes,用自己的ivk和outputDes里的epk尝试解密每一个Cenc ,如果返回成功,则将接收到的note添加至本地的receiveSets。
那么什么是Cenc呢?用ivk和epk如何去解密Cenc?
1. 什么是Cenc?
	Cenc是encCiphertext,是noteplaint经过对称密钥加密后的密文信息,noteplaint是指交易新生成的note的内容,这些内容都是私密的。np的组成及Cenc的加密过程如下图所示:

在这里插入图片描述

  相关字段解释如下
  	DiverfiedHash:一次性参数生成器,输入d,输出gd,每次调用都不一样;
 	esk、epk:一次性私钥、公钥,满足epk = esk * gd;
  	pkd:一次性传输地址;
  	np:noteplaint{memo、rcm、v、d}  => note信息{特殊字段,由交易发送者和接收者协商一致使用、生成cm的随机数、note的面额、			diversifier};
  	KA.DerivePublic:计算公钥;
  	KA.Agree:计算共享密钥;
  	KDF:密钥获取函数,得到最终的加密密钥Kenc;
  	Sym.Encrypt:一次性对称加密函数;
  其中Kenc为一次性对称加密密钥,Penc为编码后的Cenc。从交易结构里可以看出,Kenc并没有直接的当作明文进行传输,那么,交易接收者是如何获取Kenc,对Cenc进行加密的呢?
  2. 用ivk和epk如何去解密Cenc?
  	首先,让我们关注两个等式:
  	pkd = ivk * gd
  	esk * gd = epk
  	在加密的过程中,KA.Agree的输入参数为pkd和esk,由pkd * esk = ivk * gd * esk = ivk * epk,因此在解密的过程中,如果能输入ivk和epk,那么由KA.Agree(pkd,esk) == KA.Agree(ivk,epk)。理解了这一点,下面具体看一下Cenc的解密过程,如下图所示:	      

在这里插入图片描述

相关字段解释如下:
	NoteCommit:cm计算函数,原始输入为np的数据;
	cm:note的承诺;
	Extractor:抽取器,返回cm的u坐标,cm形式(u,v);
若返回的cmu与outputDes里的一致,则说明证明者有计算cm的私有数据;

总结

可能阅读到这里,大部分人还是不太明白,以下几点到底是如何实现的?
	1. Sapling是如何实在隐藏交易发送方的?
	2. Sapling是如何实现隐藏交易接收方的?
	3. Sapling是如何隐藏交易发送金额的?
答案就在下面的图中:

在这里插入图片描述
希望各位读者给予指导。。多谢_.

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值