http://www.7klian.com

零常识证明 电路及证昭示例(libsnark)

  sample::MerkleCircuit<FieldT, HashT> mc(pb, tree_depth);
typedef libff::Fr<ppzksnark_ppT> FieldT;
4.4 验证
在编译之前,同步该项目依赖的libsnark库:
4.2 可信配置(trusted setup)
实现一个电路,主要实现两个接口函数:
  protoboard<FieldT> pb;
./merkle verify [root]
  protoboard<FieldT> pb;
4.1 编译
3.2 prove
3.3 verify
零常识证明 – libsnark源代码阐明
3.1 setup
./merkle setup
typedef sha256_two_to_one_hash_gadget<FieldT> HashT;
为了利便入门者编写本身的电路,同事写了个基于libsnark结构电路,并生成并验证电路的实例:
4 编译和运行
mkdir build; cd build; cmake ..
  return r1cs_gg_ppzksnark_generator<ppzksnark_ppT>(cs);
./merkle prove [data1] [data2] [data3] [data4] [data5] [data6] [data7] [data8] [index]

libsnark库代码条理很是清晰。libsnark也给出了SNARK相关算法的全貌,各类Relation,Language,Proof System。为了更好的生成R1CS电路,libsnark抽象出protoboard和gadget,利便开拓者快速搭建电路。在阅读该示例代码前,请仔细阅读libsnark的源代码阐明:
  return r1cs_gg_ppzksnark_prover<ppzksnark_ppT>(proving_key, pb.primary_input(), pb.auxiliary_input());
https://github.com/StarLI-Trapdoor/libsnark_sample
独一有点遗憾的,libsnark没有给个完整的电路结构实例,入门者想搭建本身的电路,刚开始有点摸不着脑子。
在main函数中界说了merkle树计较需要的一些范例:
  mc.generate_r1cs_constraints();
prove逻辑,首先从输入参数结构一个完整的merkle树,并按照输入选定了默克尔路径。通过generate_read_proof函数生成
证明。该函数逻辑也较量清晰:
3 生成和验证证明
2 电路实现
确定了电路的实现,看看main函数,如何生成和验证证明。
  sample::MerkleCircuit<FieldT, HashT> mc(pb, tree_depth);
  mc.generate_r1cs_witness(pb, leaf, root, path, address, address_bits);
  mc.generate_r1cs_constraints();
prove呼吁,需要提供原始的3层merkle树的8个叶子节点,并指定需要证明的第几个叶子节点对应的路径(index指明)。
1 代码布局
  r1cs_constraint_system<FieldT> cs = pb.get_constraint_system();
generate_r1cs_witness – 给所有的变量举办赋值。该电路,需要赋值的变量有root,leaf(叶子节点),和叶子节点配套的默克尔路径,以及默克尔路径对应的地点信息(也就是每一层的节点的位置,左边照旧右边)。
pb.set_input_sizes(root_digest->digest_size);
在获知vk,证明以及果真信息(root)的基本上,挪用r1cs_gg_ppzksnark_verifier_strong_IC的接口完成验证。这也就是verify_read_proof函数的逻辑。
pk存放在merkle_pk.raw文件中,vk存放在merkle_vk.raw中。
git submodule update –init –recursive
个中,root信息是在prove中生成进程中打印出来的root信息(也是果真信息)。假如验证通过,就说明存在一条能生成root的merkle路径,固然没有果真路径的详细信息。
4.3 生成证明
也就是说,该电路的果真变量为root的bit个数。
总结:
typedef libff::default_ec_pp ppzksnark_ppT;
generate_r1cs_constraints – 生成R1CS,该电路较量简朴,只要让依赖的两个gadget,生成R1CS即可。
结构MerkleCircuit,在生成R1CS后,配置各个变量的值。接着通过r1cs_gg_ppzksnark_prover生成证明。
实现了generate_read_keypair函数,生成pk/vk。仔细看一下generate_read_keypair函数,逻辑简朴清晰:结构MerkleCircuit,在生成R1CS后,挪用r1cs_gg_ppzksnark_generator生成pk/vk。
FieldT默认是bn256椭圆曲线的的Fr,默克尔树计较回收是sha256算法。
编译完成,merkle目次下会生成merkle的可执行文件。
整个电路最巨大的就是电路的结构函数,申请变量,建设gadget。个中重点讲一讲,set_input_sizes函数。libsnark的框架中,利用简朴的区分public和private变量的模子。通过set_input_sizes函数,配置前几个变量为public变量。
入门者,,可以基于这个示例开拓本身的电路。选择默克尔树作为电路的示例,因为在零常识证明的应用中,大量的利用默克尔树数据布局。
libsnark库代码条理很是清晰,并抽象出protoboard和gadget,利便开拓者快速搭建电路。本文给出了一个基于libsnark库开拓的完整电路示例。示例实现了3层默克尔树的一条默克尔路径的验证。个中默克尔树回收sha256的散列函数。

电路名为MerkleCircuit,主要依赖两个gadget:merkle_authentication_path_variable和merkle_tree_check_read_gadget。merkle_authentication_path_variable提供了merkle树的一条路径。merkle_tree_check_read_gadget查抄给定一个叶子节点,是否能计较出正确的root。
该示例结构了一条merkle路径的验证电路,生成并验证证明。merkle树的深度为3,而且merkle树的计较回收sha256散列函数。代码布局较量清晰,merkle目次中的main.cpp是主函数。circuit目次下的merklecircuit.h是电路的实现。整个项目用cmake举办编译。

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。