2 *****************************************************************************
3 * @author This file is part of libff, developed by Clearmatics Ltd
4 * (originally developed by SCIPR Lab) and contributors
6 * @copyright MIT license (see LICENSE file)
7 *****************************************************************************/
9 #ifndef LIBSNARK_GADGETLIB1_GADGETS_VERIFIERS_KZG10_VERIFIER_GADGET_TCC_
10 #define LIBSNARK_GADGETLIB1_GADGETS_VERIFIERS_KZG10_VERIFIER_GADGET_TCC_
12 #include "libsnark/gadgetlib1/gadgets/verifiers/kzg10_verifier_gadget.hpp"
17 template<typename ppT>
18 kzg10_srs_variable<ppT>::kzg10_srs_variable(
19 protoboard<libff::Fr<ppT>> &pb,
20 const size_t max_degree,
21 const std::string &annotation_prefix)
22 : alpha_g2(pb, FMT(annotation_prefix, " alpha_g2"))
25 alpha_powers_g1.reserve(max_degree + 1);
26 for (size_t i = 0; i < max_degree + 1; ++i) {
27 alpha_powers_g1.emplace_back(
28 pb, FMT(annotation_prefix, " alpha_powers_g1[%zu]", i));
32 template<typename ppT>
33 void kzg10_srs_variable<ppT>::generate_r1cs_witness(
34 const typename kzg10<npp>::srs &srs)
36 assert(srs.alpha_powers_g1.size() == alpha_powers_g1.size());
38 for (size_t i = 0; i < srs.alpha_powers_g1.size(); ++i) {
39 alpha_powers_g1[i].generate_r1cs_witness(srs.alpha_powers_g1[i]);
41 alpha_g2.generate_r1cs_witness(srs.alpha_g2);
44 template<typename ppT>
45 kzg10_verifier_gadget<ppT>::kzg10_verifier_gadget(
46 protoboard<libff::Fr<ppT>> &pb,
47 const kzg10_srs_variable<ppT> &srs,
48 const kzg10_commitment_variable<ppT> &commitment,
49 pb_linear_combination<libff::Fr<ppT>> i,
50 pb_linear_combination<libff::Fr<ppT>> poly_eval,
51 const kzg10_witness_variable<ppT> &witness,
52 pb_variable<libff::Fr<ppT>> result,
53 const std::string &annotation_prefix)
54 : gadget<libff::Fr<ppT>>(pb, annotation_prefix)
56 , i_in_G2(pb, FMT(annotation_prefix, " i_in_G2"))
62 libff::G2<other_curve<ppT>>::one(),
63 FMT(annotation_prefix, " one_G2")),
65 FMT(annotation_prefix, " compute_i_in_G2"))
67 , B(pb, FMT(annotation_prefix, " B"))
73 FMT(annotation_prefix, " compute_B"))
75 , poly_eval_in_G1(pb, FMT(annotation_prefix, " poly_eval_in_G1"))
76 , compute_poly_eval_in_G1(
81 libff::G1<other_curve<ppT>>::one(),
82 FMT(annotation_prefix, " one_G1")),
84 FMT(annotation_prefix, " compute_poly_eval_in_G1"))
86 , C(pb, FMT(annotation_prefix, " C"))
90 -poly_eval_in_G1.value,
92 FMT(annotation_prefix, " compute_C"))
96 pb, witness, A_precomp, FMT(annotation_prefix, " compute_A_precomp"))
99 pb, B, B_precomp, FMT(annotation_prefix, " compute_B_precomp"))
102 pb, C, C_precomp, FMT(annotation_prefix, " compute_C_precomp"))
105 libff::G2<other_curve<ppT>>::one(),
106 FMT(annotation_prefix, " D_precomp"))
108 , check_result(pb_variable_allocate<FieldT>(
109 pb, FMT(annotation_prefix, " check_result")))
110 , check_pairing_equality(
117 FMT(annotation_prefix, " check_pairing_equality"))
119 , group_elements_non_zero(pb_variable_allocate<FieldT>(
120 pb, FMT(annotation_prefix, " group_elements_non_zero")))
125 template<typename ppT>
126 void kzg10_verifier_gadget<ppT>::generate_r1cs_constraints()
128 compute_i_in_G2.generate_r1cs_constraints();
129 compute_B.generate_r1cs_constraints();
130 compute_poly_eval_in_G1.generate_r1cs_constraints();
131 compute_C.generate_r1cs_constraints();
132 compute_A_precomp.generate_r1cs_constraints();
133 compute_B_precomp.generate_r1cs_constraints();
134 compute_C_precomp.generate_r1cs_constraints();
135 check_pairing_equality.generate_r1cs_constraints();
137 // group_elements_non_zero =
138 // (1 - i_in_G2.is_identity) * (1 - poly_eval_in_G1.is_identity)
139 this->pb.add_r1cs_constraint(
140 r1cs_constraint<FieldT>(
141 FieldT::one() - i_in_G2.is_identity,
142 FieldT::one() - poly_eval_in_G1.is_identity,
143 group_elements_non_zero),
144 FMT(this->annotation_prefix, " compute_group_elements_non_zero"));
146 // result = group_elements_non_zero * check_result
147 this->pb.add_r1cs_constraint(
148 r1cs_constraint<FieldT>(group_elements_non_zero, check_result, result),
149 FMT(this->annotation_prefix, " compute_result"));
152 template<typename ppT> void kzg10_verifier_gadget<ppT>::generate_r1cs_witness()
154 compute_i_in_G2.generate_r1cs_witness();
155 // compute_B.B = -i_in_G2.value. Evaluate the result of the negation.
156 compute_B.B.Y->evaluate();
157 compute_B.generate_r1cs_witness();
158 compute_poly_eval_in_G1.generate_r1cs_witness();
159 // compute_C.B = -poly_eval_in_G1.value. Evaluate the result of negation.
160 compute_C.B.Y.evaluate(this->pb);
161 compute_C.generate_r1cs_witness();
162 compute_A_precomp.generate_r1cs_witness();
163 compute_B_precomp.generate_r1cs_witness();
164 compute_C_precomp.generate_r1cs_witness();
165 check_pairing_equality.generate_r1cs_witness();
167 const FieldT group_elements_non_zero_val =
168 (FieldT::one() - this->pb.lc_val(i_in_G2.is_identity)) *
169 (FieldT::one() - this->pb.lc_val(poly_eval_in_G1.is_identity));
170 const FieldT result_val =
171 group_elements_non_zero_val * this->pb.val(check_result);
173 this->pb.val(group_elements_non_zero) = group_elements_non_zero_val;
174 this->pb.val(result) = result_val;
177 } // namespace libsnark
179 #endif // LIBSNARK_GADGETLIB1_GADGETS_VERIFIERS_KZG10_VERIFIER_GADGET_TCC_