libsnark庫使用gadgets將R1CS打包;
首先創建src/gadget.hpp
文件,開發人員設置共有變量out
和私有變量x
,gadget會自己處理中間變量y
、sym_1
和sym_2
;
然後創建一個派生自gadget
類的test_gadget
類,y
、sym_1
和sym_2
作爲其私有成員,x
和out
是公共類成員變量;
接下來介紹gadget
的功能及使用方法
構造函數:
sym_1.allocate(this->pb, "sym_1");
y.allocate(this->pb, "y");
sym_2.allocate(this->pb, "sym_2");
構造函數將中間變量分配給pb;
generate_r1cs_constraints()
該函數添加了與電路相對應的R1CS約束,與前面手動添加的函數相同,只是捆綁在這個函數中;
generate_r1cs_witness()
該函數假設我們已經設置了公共值out
和見證值x
,然後它計算中間值y
、sym_1
和sym_2
的見證值,因此gadget用戶無須擔心中間變量;
使用gadget:
protoboard<FieldT> pb;
pb_variable<FieldT> out;
pb_variable<FieldT> x;
out.allocate(pb, "out");
x.allocate(pb, "x");
初始化pb,聲明out
和x
;
pb.set_input_sizes(1);
test_gadget<FieldT> g(pb, out, x);
指定哪些變量是公共的,哪些變量是私有的,然後創建新的test_gadget
;
g.generate_r1cs_constraints();
調用函數生成R1CS約束;
pb.val(out) = 35;
pb.val(x) = 3;
g.generate_r1cs_witness();
添加公共值35
和見證值3
,其餘中間變量的值在gadget
中自動計算;