概述
在研究区块链系统的工作原理时,我们需要了解各种各样密码学知识,比如secp256k1,它是一种曲线和非对称签名算法,在比特币和以太坊系统中用于签名和验证账号。比如sha256,它是一种哈希算法,用于把变长信息压缩成定长编码。比如base58,它可以把信息编码转换成可打印字符表示的字符串。比如ECDH,它是一种Diffie-Hellman密钥交换算法,用于在P2P节点间安全交换通讯密钥。
零知识证明也是一种密码学算法,简称为ZKP或者ZK,它的特点是可以在不泄露任何其他信息的前提下证明一个命题的正确性。
ZKP最早在1985年就已经被提出,然而长期以来一直没有找到大规模应用的场景,所以技术的发展也十分缓慢。一直到2009年比特币诞生后,人们发现它非常适合用于解决区块链中的隐私和扩展性问题,至此大量的资本和人才投入到了这项技术的开发和工程应用中。ZKP有很多实现,例如:Groth16、PlonK、STARK等,至今还没出现真正的行业标准,本文将为大家盘点各种ZKP实现的技术特点,希望能给大家的学习研究和工程开发带来帮助。
ZKP应用领域
1.隐私证明
Zcash可能是ZKP的第一个被广泛使用的应用,它在比特币源代码的基础上,将ZKP应用于代币的转移,使得交易的信息完全保密,但同时能被区块链上的节点验证。
TornadoCash是在以太坊运行的混币器,它使用ZKP证明Merkle-Tree上的节点,用户可以将固定金额的代币存入资金池,然后使用ZKP生成的Proof证明自己曾经存入过资金,但不需要暴露自己存入时的交易信息。
2.?计算外包
在区块链中,每个节点的计算能力有限,但借助ZKP技术,节点可以将大量的计算外包给链下节点,这时只需要验证外包提交的计算结果和计算证明就可以知道计算是否正确。
zksync1.0就是一个很好的例子,它在链下进行以太坊代币转账和交易,然后将结果提交给节点,节点通过验证ZKP证明就可以知道它是否按照它声明的方法进行计算。
3.?数据压缩
慢雾:上周Web3安全事件中总损失约1996.3万美元:金色财经报道,据慢雾区块链被黑档案库统计,2023年8月14日至8月20日,共发生安全事件10起,总损失约1996.3万美元。具体事件:
8月14日,Hexagate发推表示,过去几天单个MEV Bot被利用了约20万美元。以太坊上Zunami Protocol协议遭遇价格操纵攻击,损失1,179个ETH(约220万美元)。
8月15日,以太坊扩容解决方案Metis官方推特账号被盗。Sei Network官方Discord服务器遭入侵。Base生态项目RocketSwap遭遇攻击,攻击者窃取了RCKT代币,将其转换为价值约86.8万美元的ETH并跨链到以太坊。
8月16日,借贷协议SwirlLend团队从Base盗取了约290万美元的加密货币,从Linea盗取了价值170万美元的加密货币。BAYC推出的链上许可申请平台Made by Apes的SaaSy Labs APl存在一个问题,允许访问MBA申请的个人详细信息。
8月18日,DeFi借贷协议Exactly Protocol遭受攻击,损失超7,160枚ETH(约1204万美元)。
8月19日,Cosmos生态跨链稳定币协议Harbor Protocol被利用,损失42,261枚LUNA、1,533枚CMDX、1,571枚stOSMO和18,600万亿枚WMATIC。
8月20日,衍生品市场Thales发布公告称,一名核心贡献者的个人电脑/Metamask遭到黑客攻击,一些充当临时部署者(2.5万美元)或管理员机器人(1万美元)的热钱包已被攻破。[2023/8/21 18:13:42]
Filecoin运用ZKP构造了时空证明系统,能证明用户在本地存储了特定文件,目前已经证明存储的文件已经达到18EiB。
Mina是另一个例子,在很多高速区块链系统中,交易的数据十分庞大,系统需要保留所有的区块以备共识协议的验证,所以系统对硬件的要求极高,永久保存意味着区块链节点将需要不断增大磁盘空间和数据索引能力。这时候可以借助ZKP,将验证数据压缩,Mina通过递归零知识证明,将账本压缩到11KB,但依旧可以验证区块的正确性。
慢雾:发现BNB Chain上一恶意合约地址,建议用户快速验证并撤销异常授权:8月20日消息,慢雾在推特发文提醒:请用户检查是否已将资产授权到BNB Chain上的一恶意合约地址:0x75117c9158f53998ce8689B64509EFf4FA10AD80。
该恶意合约尚未通过开源进行验证,但反编译显示其存在针对授权资产的任意转账后门。这种类型的后门让用户钱包在很长一段时间内保持正常使用,但当某天转移一笔金额稍大的资产时,它会突然被盗,而链上不会显示任何最近的异常授权。
用户可使用Revoke.cash和Rabby Wallet进行快速验证并撤销异常授权。以下是与上述合约相关的恶意地址:0xE2A178C2C5C4920C1b2B947A35edDb4f8EcBb7dD、0xB88457b62491CBcEc42203672cFcb4269d64c7e。请用户保持警惕。[2023/8/20 18:11:40]
ZKP证明系统
证明系统是ZKP的底层算法实现,可分为交互式和非交互式两种:
1.?交互式证明系统
交互证明系统由两方参与,分别称为证明者和验证者,其中P知道某一秘密,P希望使V相信自己的确掌握这一秘密。交互证明由若干轮组成,在每一轮,P和V可能需根据从对方收到的消息和自己计算的某个结果向对方发送消息。比较典型的方式是在每轮V都向P发出一个询问,P向V做出一个应答。所有轮执行完后,V根据P是否在每一轮对自己发出的询问都能正确应答,决定是否接受P的证明。
2.?非交互式证明系统
在上述交互式证明系统中,P和V不进行交互,证明由P产生后直接给V,V对证明直接进行验证,这种证明系统称为非交互式证明系统。
我们在区块链中使用的证明系统一般都是NIZK,区块链中的节点就是验证者V,终端用户或者二层网络就是证明者P。
文末参考链接?描述了近十年来公开发表的NIZK方案及特点。
在实际工程应用中我们主要关注的是性能和通用性,因此我们对一些常见证明系统进行更细致的分类对比,见文末参考链接:
慢雾:pGALA合约黑客已获利430万美元:11月4日消息,安全团队慢雾在推特上表示,pGALA合约黑客已将大部分GALA兑换成13,000枚BNB,获利超430万美元,该地址仍有450亿枚Gala,但不太可能兑现,因为资金池基本已耗尽。此外,黑客的初始资金来自几个币安账户。
今日早些时候消息,一个BNB Chain上地址在BNB Chain上地址凭空铸造了超10亿美元的pGALA代币,并通过在PancakeSwap上售出获利。pNetwork表示此为跨链桥配置错误所致,GALA跨链桥已暂停,请用户不要在BNB Chain上DEX中交易pGALA。[2022/11/4 12:16:04]
Bulletproofs
特点:简洁证明大小,无需可信设置,但证明生成和验证耗时相比较长。
代表项目:Bulletproofs,Halo,Halo2。
SNARKs(SuccinctNon-interactiveARgumentsofKnowledge)
特点:简洁证明大小,证明验证耗时相比较短,但需要对每一个电路进行可信设置。
代表项目:Groth16。
SNORKs(SuccinctNon-interactiveOecumenical(Universal)aRgumentsofKnowledge)
特点:简洁证明大小,只需要进行一次可信设置即可用于所有电路。
代表项目:Sonic,PlonK,Marlin,Plonky2。
STARKs(Succinct(Scalable)TransparentARgumentsofKnowledge)
特点:证明十分庞大,不需要进行可信设置,具有良好的可扩展性。
代表项目:STARK。
以上分类也不是绝对的,比如Halo/Halo2项目,它们在设计时也借鉴了很多Plonk的思路,另外,SNORKs通常会被归入到SNARKs,因为它们都需要可信设置。
3.性能对比
慢雾:Equalizer Finance被黑主要在于FlashLoanProvider合约与Vault合约不兼容:据慢雾区消息,6 月 7 日,Equalizer Finance 遭受闪电贷攻击。慢雾安全团队以简讯形式将攻击原理分享如下:
1. Equalizer Finance 存在 FlashLoanProvider 与 Vault 合约,FlashLoanProvider 合约提供闪电贷服务,用户通过调用 flashLoan 函数即可通过 FlashLoanProvider 合约从 Vault 合约中借取资金,Vault 合约的资金来源于用户提供的流动性。
2. 用户可以通过 Vault 合约的 provideLiquidity/removeLiquidity 函数进行流动性提供/移除,流动性提供获得的凭证与流动性移除获得的资金都受 Vault 合约中的流动性余额与流动性凭证总供应量的比值影响。
3. 以 WBNB Vault 为例攻击者首先从 PancekeSwap 闪电贷借出 WBNB
4. 通过 FlashLoanProvider 合约进行二次 WBNB 闪电贷操作,FlashLoanProvider 会先将 WBNB Vault 合约中 WBNB 流动性转给攻击者,随后进行闪电贷回调。
5. 攻击者在二次闪电贷回调中,向 WBNB Vault 提供流动性,由于此时 WBNB Vault 中的流动性已经借出一部分给攻击者,因此流动性余额少于预期,则攻击者所能获取的流动性凭证将多于预期。
6. 攻击者先归还二次闪电贷,然后从 WBNB Vault 中移除流动性,此时由于 WBNB Vault 中的流动性已恢复正常,因此攻击者使用添加流动性获得凭证所取出的流动性数量将多于预期。
7. 攻击者通过以上方式攻击了在各个链上的 Vault 合约,耗尽了 Equalizer Finance 的流动性。
此次攻击的主要原因在于 Equalizer Finance 协议的 FlashLoanProvider 合约与 Vault 合约不兼容。慢雾安全团队建议协议在进行实际实现时应充分考虑各个模块间的兼容性。[2022/6/8 4:09:22]
电路编程
慢雾:Polkatrain 薅羊毛事故简析:据慢雾区消息,波卡生态IDO平台Polkatrain于今早发生事故,慢雾安全团队第一时间介入分析,并定位到了具体问题。本次出现问题的合约为Polkatrain项目的POLT_LBP合约,该合约有一个swap函数,并存在一个返佣机制,当用户通过swap函数购买PLOT代币的时候获得一定量的返佣,该笔返佣会通过合约里的_update函数调用transferFrom的形式转发送给用户。由于_update函数没有设置一个池子的最多的返佣数量,也未在返佣的时候判断总返佣金是否用完了,导致恶意的套利者可通过不断调用swap函数进行代币兑换来薅取合约的返佣奖励。慢雾安全团队提醒DApp项目方在设计AMM兑换机制的时候需充分考虑项目的业务场景及其经济模型,防止意外情况发生。[2021/4/5 19:46:39]
电路是ZKP系统的业务逻辑实现,开发ZKP应用需要进行电路编程,为什么ZKP逻辑代码被称为“电路”?主要有以下几个原因:
ZKP证明的代码会被转换成一系列简单约束条件的表达式R1CS,然后使用拉格朗日插值法,转换为一个巨大的多项式QAP,最终以门电路的形式被约束。
与硬件电路类似,所有分支的代码将被一起执行。
与硬件电路类似,ZKP证明电路中没有递归和复杂的循环,循环的数量只能是恒定的。
我们不需要从头去用密码学实现ZKP应用,有很多开发库已经实现了这些底层证明系统,我们只需要关注业务逻辑的实现。当然每一种库都有不同的抽象程度,有的需要去学习描述电路的表达式,有的只需要按流程定义好代码就可以轻松实现。
1.常用开发库
libsnark
用C++语言实现了通用证明系统、基础电路库和应用示例。
证明系统:BBFR15、BCCT12、BCCT13、BCGTV13、BCIOP13、BCTV14a、BCTV14b、CTV15、DFGK14、Groth16、GM17、GGPR13、PGHR13。
链接:https://github.com/scipr-lab/libsnark。
gnark
用Go语言实现的证明系统,提供高级API来设计电路。
证明系统:Groth16、PlonK。
链接:https://github.com/consensys/gnark。
bellman
Rust实现的证明系统,它提供电路接口、基础结构以及一些基本电路实现,例如布尔和数值抽象。
证明系统:Groth16。
链接:https://github.com/zkcrypto/bellman。
snarkjs
Javascript和WASM实现的证明系统,可用于可信设置、生成证明并验证证明。snarkjs使用iden3自己的circom编译器对DSL定义的电路进行编译。
证明系统:Groth16、PlonK。
链接:https://github.com/iden3/snarkjs。
ethsnarks
使用Python实现,可以在用户浏览器生成证明,使用以太坊智能合约做为验证者。目前项目开发不活跃,相同的场景下使用Circom可能是更好的选择。
证明系统:Groth16。
链接:https://github.com/HarryR/ethsnarks。
bulletproofs
使用Rust实现的证明系统,具有单一和聚合范围证明、强类型多方计算,正在开发中用于证明任意语句的可编程约束系统API。
证明系统:bulletproofs。
链接:https://github.com/dalek-cryptography/bulletproofs。
halo2
一个基于Rust的实现的证明系统,由ZCash团队维护。Halo2特定于PLONKish,可以非常直接地控制电路在算术运算中的表示方式,非常适合编写高度优化的电路。
证明系统:Halo2。
链接:https://github.com/zcash/halo2。
2.开发流程
以gnark为例,一个典型的工作流程如下图:
1)用代码描述需要解决的问题。
2)编译成R1CS约束系统。
3)对R1CS进行可信设置,得到Provingkey和Verifykey。
4)证明者使用R1CS和Provingkey计算私密数据,生成证明Proof。
5)验证者使用Verifykey验证Proof。
电路编程专用语言
1.?基于以太坊平台
Cairo
Cairo是一种用于编写可证明程序的编程语言,其中一方可以向另一方证明某个计算已正确执行。Cairo和类似的证明系统可用于为区块链提供可扩展性。StarkNet将Cairo编程语言用于其基础设施和编写StarkNet合约。
证明系统:STARK。
链接:https://www.cairo-lang.org/docs/。
Zokrates
ZoKrates采用DSL描述电路,提供了一些常用的电路库,它可以帮助你在DApp中使用可验证的计算,从用高级语言规范您的程序到生成计算证明,再到在Solidity中验证这些证明。
证明系统:GM17、Groth16、Marlin。
链接:https://zokrates.github.io/。
Circom
Circom语言采用DSL描述电路,可以配合snarkjs在用户浏览器生成证明,使用以太坊智能合约做为验证者。
证明系统:Groth16、PlonK。
链接:https://iden3.io/circom。
Noir
Aztec基于Rust的隐私编程语言,采用DSL描述电路,允许安全、无缝地构建隐私保护零知识电路。
证明系统:PlonK。
链接:https://noir-lang.org/index.html。
zkEVM
与EVM一样,zkEVM是一个虚拟机,它作为程序操作的结果在状态之间转换,但是zkEVM通过生成证明来证明计算的每个部分的正确性。本质上,zkEVM使用一种机制来证明执行步骤遵循规则。
目前有zkSync、Polygon、Scroll、Starkware等团队正致力于zkEVM的实现,已取得重大进展。
2.?基于公链平台
zkApp(Mina)
zkApps是MinaProtocol的智能合约,由零知识证明提供支持。zkApps可以在链下执行任意复杂的计算,同时只收取固定费用以将生成的零知识证明发送到链以验证此计算,这与其他在链上运行计算并使用基于可变gas费用的区块链相反模型。zkApps使用Typescript编写。
证明系统:PlonK。
链接:https://docs.minaprotocol.com/zkapps。
LEO(Aleo)
Leo是一种函数式静态类型编程语言,专为编写私有应用程序而构建。它专为开发人员设计,可以直观地在Aleo区块链上构建,为私有的、去中心化的生态系统提供基础。
证明系统:Marlin。
链接:https://leo-lang.org/。
ZKP常见安全问题
在过去几年,慢雾安全团队已为多个知名ZKP产品进行了电路及应用安全审计,包括ZKSwap、Zkdex、Zksafe等,发现了多个中高危漏洞,对基于Circom、libsnark等流行框架开发的应用有较为深入的理解。慢雾安全团队在ZKP应用审计中发现常见的安全问题有:
信任参数风险
为了使用zk-SNARKs,需要一组公共参数,称为公共参考字符串。但是这些参数的创建也会产生一些私有参数,如果某一方获得这些私有参数,他们就可以伪造证明。另外,生成CRS的流程需要经过审计,确保不会有随机数后门,或者私有参数不会被蓄意保留。使用zk-SNORKs时也需要确保结构化参考字符串是可信的。
可信配置阶段的安全隐患问题可以使用安全多方计算来解决,MPC的特点是只要任何一个参与者能诚实参与,那么通过这套多方计算系统最终得到的计算结果就是可信的。
静态代码安全
这部分主要是由于编码不规范造成的安全问题,例如:参数未校验、返回值未处理、数值溢出、边界未检查等,如果编写电路的语言是C/C++,那么还会存在内存溢出风险。
供应链攻击风险
供应链的风险主要来自使用了存在漏洞的代码库,例如:旧版本的仓库。通常ZKP应用还需要配合客户端或者Web前端使用,而这部分也很容易遭受多种方式黑客攻击。
逻辑错误
逻辑错误是电路实现中最容易出现的错误,需要结合需求文档检查电路的设计是否符合需求。
双花攻击
错误的设计可能导致双花攻击,例如:某些ZKP库存在延展性风险,攻击者可利用已知的Proof生成不同Proof,如果设计不当会导致双花攻击。
证明伪造
有效的证明是ZKP首要解决的问题,确保满足完备性和可靠性,即“假的真不了,真的假不了”,所以如果一个电路可以创建假证明,通常是由于底层库出现漏洞,通常我们会建议项目方使用公开的经过审计的ZKP库,并使用稳定的发行版。
侧信道攻击
如果电路设计不当,不同的隐私信息可能存在不同的计算特征,攻击者可能通过公开的输入或者证明猜解出私有输入数据。
电路约束失效
不恰当的电路表达式可能导致变量未被约束。
特殊值攻击
一些特殊的输入值可能绕过系统的验证逻辑,例如:0、null等。
隐私输入猜解
对于TornadoCash等应用,如果输入的信息可以被猜解,那么会导致严重的隐私泄露问题,这时需要对输入数据进行严格审计,确保不能被猜解。
RugPull风险
一些项目可能存在特殊的管理员权限,一旦权限被非法使用会导致项目资金和用户资产被窃取。
智能合约风险
一些ZKP证明使用智能合约进行验证,例如:Circom、ZoKrates等。智能合约可能出现重入、重放、逻辑错误等风险,详情可查看慢雾安全团队的智能合约安全审计服务。
针对上面列举的ZKP安全问题,慢雾安全团队在攻防实战中总结出了一套安全解决方案,结合黑盒/灰盒/白盒多种测试手段,推出了面向区块链行业的ZKP电路审计服务。
总结
零知识证明是解决区块链隐私性、计算扩展和数据压缩问题的有效方法,目前有很多的实现方案,这些实现方案具有不同的性能参数指标和安全基准。开发者在开发零知识证明电路时需要注意根据需求选择合适的框架,并确保在项目上线前对应用的安全性进行过全面安全审计。
最后,感谢领先的一站式数字资产自托管服务商Safeheron提供的专业技术建议。
参考链接:
.https://en.wikipedia.org/wiki/Zero-knowledge_proof
.https://github.com/matter-labs/awesome-zero-knowledge-proofs
.https://docs.google.com/presentation/d/1gfB6WZMvM9mmDKofFibIgsyYShdf0RV_Y8TLz3k1Ls0/edit
郑重声明: 本文版权归原作者所有, 转载文章仅为传播更多信息之目的, 如作者信息标记有误, 请第一时间联系我们修改或删除, 多谢。