libsnark是目前实现zk-SNARKs电路最重要的框架,在众多私密交易或隐私计算相关项目间广泛应用,其中最著名当然要数Zcash。Zcash在Sapling版本升级前一直使用libsnark来实现电路。毫不夸张地说,libsnark支撑并促进了zk-SNARKs技术的
首次大规模应用,填补了零知识证明技术从最新理论到工程实现间的空缺。
希望通过本系列文章,所有开发者都能亲自上手实践,在短时间内迅速入门libsnark,一步步了解libsnark的基本概念,学会如何开发zk-SNARKs电路,完成证明的生成和验证,最终将零知识证明应用到真实业务中去。
1、zk-SNARKs和libsnark背景简介
零知识证明,可能是目前最具应用前景和想象力的密码学黑科技。而zk-SNARKs正是一类零知识证明方案的简称,全称为Zero-KnowledgeSuccinctNon-interactiveArgumentsofKnowledge。这一名字几乎包含了其所有技术特征,即可以在不泄露任何其他信息的前提下证明一个命题的正确性,并且最终生成的证明具有简洁性,也就是说最终生成的证明足够小,并且与计算量大小无关,是一个常数。用白话说就是,你理论上可以在不暴露任何隐私的情况下向其他所有人证明某件事,并且生成的证明体积很小,校验成本很低,与需要证明的内容计算量无关。听起来简直太美好了!
zk-SNARKs能应用到很多场景,比如隐私保护、区块链扩容、可验证计算等。本文不介绍zk-SNARKS和零知识证明的理论细节,不熟悉或想深入了解的同学可阅读其他文章或论文。
如Vitalik写的关于zk-SNARKs著名的三篇博文。
https://medium.com/
第一步,我们需要将函数?C(x,out)?在libsnark中进行表达。此处先省略,后面介绍详细过程。
第二步,对应下面的Generator函数(
G),lambda?为随机产生,也就是常说的trustedsetup过程中产生的"toxicwaste"。人们喜欢称它为“有废物”,是因为它必须被妥善处理,否则会影响证明协议安全。
lambda<-random()
(pk,vk)=G(C,lambda)
最终生成provingkey(pk)和verificationkey(vk)。
第三步,对应使用Prove函数(
P)生成证明。这里想证明的是prover知道一个秘密值?x?和计算结果?out?可使等式满足。因此将?x、out?还有?pk?作为输入一起传给?
P,最终生成证明?proof。
proof=P(pk,out,x)
第四步,对应使用Verify函数(
V)验证证明,将?proof、out?还有?vk?传给?
G,即可在不暴露秘密的情况下证明存在一个秘密值可使等式满足。
2017银行年报:跨境和票据业务为上市银行实践区块链技术的主要领域:据报道,A股26家上市银行2017年业绩报告目前已披露完毕。报告显示,共有12家银行的年报显示在年内已上线运行区块链应用,其中包括三家国有大行、六家全国性股份制银行,以及三家城商行。上市银行实践应用区块链技术的领域主要为跨境业务和票据业务,也有部分银行创新性地将区块链应用于贷款征信、用户身份防伪和提升获客能力上。[2018/5/4]
V(vk,out,proof)?=true
而
开发者主要工作量就集中在第一步,需要按照libsnark的接口规则手写C++电路代码来描述命题,由代码构造R1CS约束。整个过程也即对应下图的Computation->ArithmeticCircuit->R1CS。
3、搭建zk-SNARKs应用开发环境
下面进入动手环节,快速上手libsnark,跑通例子。
先下载本文对应的libsnark最小可用例子代码库?libsnark_abc。
gitclonehttps://github.com/sec-bit/libsnark_abc.git
通过gitsubmodule拉取libsnark代码。
cdlibsnark_abc
gitsubmoduleupdate--init--recursive
参考libsnark?项目文档完成相关依赖安装。以Ubuntu16.04LTS为例,需安装以下组件:
sudoapt-getinstallbuild-essentialcmakegitlibgmp3-devlibprocps4-devpython-markdownlibboost-all-devlibssl-dev
初始化?build?文件夹。
mkdirbuild&&cdbuild&&cmake..
这步在macOS系统可能会遇到问题,参考这个issue?处理。或尝试使用以下命令:
mkdirbuild&&cdbuild&&CPPFLAGS=-I/usr/local/opt/openssl/includeLDFLAGS=-L/usr/local/opt/openssl/libPKG_CONFIG_PATH=/usr/local/opt/openssl/lib/pkgconfigcmake-DWITH_PROCPS=OFF-DWITH_SUPERCOP=OFF..
成功后,依旧在?build?目录进行编译。
Comcast Ventures高管:人们将真正看到区块链技术的潜力:比特币的价格正徘徊在今年最好的水平附近,Comcast Ventures董事总经理Gil Beyda表示,这是因为人们意识到比特币和区块链的真正价值。在2017年,投资者专注于快速致富,并将他们的钱翻倍,而泡沫现在已经不存在了。他说,“我认为,我们将会看到人们真正理解这项技术的潜力。”[2018/5/1]
make
编译成功后,在?build/src?目录中可看到3个二进制文件。
main
range
test
到这儿,你就以及完成示例项目的编译啦。尝试运行示例代码吧。
./src/main
最终出现如下日志,则说明一切正常。你已顺利拥有了zkSNARK应用开发环境,并成功跑了第一个zk-SNARKs的demo。
4、理解示例代码
下面我们一起来仔细瞅瞅代码。示例项目包含了3份代码。
不妨先看看?src/main.cpp。这个例子来自HowardWu的?libsnark_tutorial,他也是libsnark作者之一哦。本文?libsnark_abc?的项目结构就是依照他的?libsnark_tutorial?搭建,属于“官方推荐风格”,请放心食用。
只有区区几十行代码,其中?run_r1cs_gg_ppzksnark()?是主要部分。很容易发现,真正起作用的实质代码只有下面5行。
r1cs_gg_ppzksnark_keypair<ppT>keypair=r1cs_gg_ppzksnark_generator<ppT>(example.constraint_system);
r1cs_gg_ppzksnark_processed_verification_key<ppT>pvk=r1cs_gg_ppzksnark_verifier_process_vk<ppT>(keypair.vk);
r1cs_gg_ppzksnark_proof<ppT>proof=r1cs_gg_ppzksnark_prover<ppT>(keypair.pk,example.primary_input,example.auxiliary_input);
constboolans=r1cs_gg_ppzksnark_verifier_strong_IC<ppT>(keypair.vk,example.primary_input,proof);
constboolans2=r1cs_gg_ppzksnark_online_verifier_strong_IC<ppT>(pvk,example.primary_input,proof);
中国VC教父阎焱:区块链本身是好技术 但现阶段还存在很多弊端:据网易科技报道,赛富亚洲投资基金创始合伙人、有“中国VC教父”之称的阎焱表示,区块链技术本身是很好的技术,但现阶段还存在很多弊端,对其开发的能力不够。同时他认为,99%的人是不关注区块链。而中国虽然有扎扎实实发展的区块链公司,但数量很少,以以太坊为例,世界上有1000个,中国可能只有1、2家。[2018/3/25]
仅从“超长”的函数名就能看出来每步是在做什么,但是却看不到如何构造电路的细节。实际上这里仅仅是调用了自带的?r1cs_example,隐去了实现细节。
既然如此,那让我们通过一个更直观的例子来学习电路细节。研究?src/test.cpp,这个例子改编自ChristianLundkvist的?libsnark-tutorial(https://github.com/christianlundkvist/libsnark-tutorial)。
代码开头仅引用了三个头文件,分别是:
#include<libsnark/common/default_types/r1cs_gg_ppzksnark_pp.hpp>
#include<libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.hpp>
#include<libsnark/gadgetlib1/pb_variable.hpp>
前面提到?r1cs_gg_ppzksnark?对应的是Groth16方案。这里加了?gg?是为了区别?r1cs_ppzksnark,表示GenericGroupModel。Groth16安全性证明依赖GenericGroupModel,以更强的安全假设换得了更好的性能和更短的证明。
第一个头文件是为了引入?default_r1cs_gg_ppzksnark_pp?类型,第二个则为了引入证明相关的各个接口。pb_variable?则是用来定义电路相关的变量。
下面需要进行一些初始化,定义使用的有限域,并初始化曲线参数。这是相当于每次的准备工作。
typedeflibff::Fr<default_r1cs_gg_ppzksnark_pp>FieldT;
default_r1cs_gg_ppzksnark_pp::init_public_params();
接下来就需要明确「待证命题」是什么。这里不妨沿用之前的例子,证明秘密?x?满足等式?x^3+x+5==out。这实际也是Vitalik博文?"QuadraticArithmeticPrograms:fromZerotoHero"(https://medium.com/
template<typenameppT>
voidtest_r1cs_gg_ppzksnark(size_tnum_constraints,size_tinput_size)
伊利诺伊州计划将区块链技术用于政府运营:根据美国伊利诺伊州区块链专责小组1月31日提交的报告,州政府正着眼于区块链技术的使用,如管理州居民的身份信息以及公共部门的资产标记,以提高效率并减少欺诈。[2018/2/2]
{
??r1cs_example<libff::Fr<ppT>>example=generate_r1cs_example_with_binary_input<libff::Fr<ppT>>(num_constraints,input_size);
??constboolbit=run_r1cs_gg_ppzksnark<ppT>(example);
??assert(bit);
}
intmain(){
??default_r1cs_gg_ppzksnark_pp::init_public_params();
??test_r1cs_gg_ppzksnark<default_r1cs_gg_ppzksnark_pp>(1000,100);
??return0;
}
test.cpp
第二个例子?test.cpp。这个例子具体展示了如何利用libsnark构建一个最简单的电路。
#include<libsnark/common/default_types/r1cs_gg_ppzksnark_pp.hpp>
#include<libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.hpp>
#include<libsnark/gadgetlib1/pb_variable.hpp>
usingnamespacelibsnark;
usingnamespacestd;
intmain(){
??typedeflibff::Fr<default_r1cs_gg_ppzksnark_pp>FieldT;
??//Initializethecurveparameters
??default_r1cs_gg_ppzksnark_pp::init_public_params();
??//Createprotoboard
??protoboard<FieldT>pb;
??//Definevariables
??pb_variable<FieldT>x;
??pb_variable<FieldT>sym_1;
美团原联合创始人杨俊准备利用区块链技术改造现有电商平台:据网传,王兴的老搭档、美团网原联合创始人及副总裁杨俊最近正在组建团队希望用区块链技术改造现有电商平台。杨俊淡出美团之后,创办了惠每医疗和天际线创投,这次重新创业选择了区块链行业。[2018/2/2]
??pb_variable<FieldT>y;
??pb_variable<FieldT>sym_2;
??pb_variable<FieldT>out;
??//Allocatevariablestoprotoboard
??//Thestrings(like"x")areonlyfordebuggingpurposes??
??out.allocate(pb,"out");
??x.allocate(pb,"x");
??sym_1.allocate(pb,"sym_1");
??y.allocate(pb,"y");
??sym_2.allocate(pb,"sym_2");
??//Thissetsuptheprotoboardvariables
??//sothatthefirstone(out)representsthepublic
??//inputandtherestisprivateinput
??pb.set_input_sizes(1);
??//AddR1CSconstraintstoprotoboard
??//x*x=sym_1
??pb.add_r1cs_constraint(r1cs_constraint<FieldT>(x,x,sym_1));
??//sym_1*x=y
??pb.add_r1cs_constraint(r1cs_constraint<FieldT>(sym_1,x,y));
??//y+x=sym_2
??pb.add_r1cs_constraint(r1cs_constraint<FieldT>(y+x,1,sym_2));
??//sym_2+5=~out
??pb.add_r1cs_constraint(r1cs_constraint<FieldT>(sym_2+5,1,out));
??
??constr1cs_constraint_system<FieldT>constraint_system=pb.get_constraint_system();
??//generatekeypair
??constr1cs_gg_ppzksnark_keypair<default_r1cs_gg_ppzksnark_pp>keypair=r1cs_gg_ppzksnark_generator<default_r1cs_gg_ppzksnark_pp>(constraint_system);
??//Addpublicinputandwitnessvalues
??pb.val(out)=35;
??pb.val(x)=3;
??pb.val(sym_1)=9;
??pb.val(y)=27;
??pb.val(sym_2)=30;
??//generateproof
??constr1cs_gg_ppzksnark_proof<default_r1cs_gg_ppzksnark_pp>proof=r1cs_gg_ppzksnark_prover<default_r1cs_gg_ppzksnark_pp>(keypair.pk,pb.primary_input(),pb.auxiliary_input());
??//verify
??boolverified=r1cs_gg_ppzksnark_verifier_strong_IC<default_r1cs_gg_ppzksnark_pp>(keypair.vk,pb.primary_input(),proof);
??cout<<"NumberofR1CSconstraints:"<<constraint_system.num_constraints()<<endl;
??cout<<"Primary(public)input:"<<pb.primary_input()<<endl;
??cout<<"Auxiliary(private)input:"<<pb.auxiliary_input()<<endl;
??cout<<"Verificationstatus:"<<verified<<endl;
}
range.cpp
第三个例子?range.cpp。该例子利用了libsnark自带的?comparison_gadget?来实现取值范围证明。
#include<libsnark/common/default_types/r1cs_gg_ppzksnark_pp.hpp>
#include<libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.hpp>
#include<libsnark/gadgetlib1/pb_variable.hpp>
#include<libsnark/gadgetlib1/gadgets/basic_gadgets.hpp>
usingnamespacelibsnark;
usingnamespacestd;
intmain(){
??typedeflibff::Fr<default_r1cs_gg_ppzksnark_pp>FieldT;
??//Initializethecurveparameters
??default_r1cs_gg_ppzksnark_pp::init_public_params();
??//Createprotoboard
??protoboard<FieldT>pb;
??pb_variable<FieldT>x,max;
??pb_variable<FieldT>less,less_or_eq;
??x.allocate(pb,"x");
??max.allocate(pb,"max");
??
??pb.val(max)=60;
??comparison_gadget<FieldT>cmp(pb,10,x,max,less,less_or_eq,"cmp");
??cmp.generate_r1cs_constraints();
??pb.add_r1cs_constraint(r1cs_constraint<FieldT>(less,1,FieldT::one()));
??constr1cs_constraint_system<FieldT>constraint_system=pb.get_constraint_system();
??//generatekeypair
??constr1cs_gg_ppzksnark_keypair<default_r1cs_gg_ppzksnark_pp>keypair=r1cs_gg_ppzksnark_generator<default_r1cs_gg_ppzksnark_pp>(constraint_system);
??//Addwitnessvalues
??pb.val(x)=18;//secret
??cmp.generate_r1cs_witness();
??//generateproof
??constr1cs_gg_ppzksnark_proof<default_r1cs_gg_ppzksnark_pp>proof=r1cs_gg_ppzksnark_prover<default_r1cs_gg_ppzksnark_pp>(keypair.pk,pb.primary_input(),pb.auxiliary_input());
??//verify
??boolverified=r1cs_gg_ppzksnark_verifier_strong_IC<default_r1cs_gg_ppzksnark_pp>(keypair.vk,pb.primary_input(),proof);
??cout<<"NumberofR1CSconstraints:"<<constraint_system.num_constraints()<<endl;
??cout<<"Primary(public)input:"<<pb.primary_input()<<endl;
??cout<<"Auxiliary(private)input:"<<pb.auxiliary_input()<<endl;
??cout<<"Verificationstatus:"<<verified<<endl;
}
作者:?IgorMandrigin 翻译:?阿剑 来源:以太坊爱好者 什么是“无状态以太坊”?如果您已经了解什么是“无状态以太坊”以及“区块见证数据”,可以跳过这一段.
在刚刚过去的2019年中,尽管对大多数加密资产来说总体上看跌,但去中心化金融却在不断壮大。最近的研究发现,在过去的一年中,对DeFi的一小笔投资可能比比特币产生更多的收益.
随着区块链技术的发展,去中心化应用程序成为了新的潮流,而以太坊作为首屈一指的平台,为此类应用程序的扩展提供了基础.
编者注:原标题为《中国电信梁伟:解读区块链界最关心的4大问题》“如果说芯片我们被别人卡脖子,那么区块链这个领域我们和美国不分伯仲。”中国电信区块链业务研发负责人梁伟说道.
来源:52CBDC 今年6月以来,开发中央银行数字货币的竞赛正在加快。CBDC是一种新型的金融模式,它将扩大公众对中央银行帐户的数字访问权限,而中央银行帐户目前仅限于商业银行.
来源/LongHash 2020年伊始,最值得期待的明星项目当属波卡和Filecoin了,已经有至少10家交易所上线了DOT的IOU期货,随着IPFS测试网上线,矿工们也早已磨刀霍霍.