2 *****************************************************************************
3 * @author This file is part of libsnark, 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_PAIRING_BW6_761_BLS12_377_BLS12_377_MEMBERSHIP_CHECK_GADGETS_TCC_
10 #define LIBSNARK_GADGETLIB1_GADGETS_PAIRING_BW6_761_BLS12_377_BLS12_377_MEMBERSHIP_CHECK_GADGETS_TCC_
12 #include "libsnark/gadgetlib1/gadgets/pairing/bw6_761_bls12_377/bls12_377_membership_check_gadgets.hpp"
17 // bls12_377_G2_membership_check_gadget
19 template<typename wppT>
20 bls12_377_G1_membership_check_gadget<wppT>::
21 bls12_377_G1_membership_check_gadget(
22 protoboard<libff::Fr<wppT>> &pb,
23 const G1_variable<wppT> &P,
24 const std::string &annotation_prefix)
25 : gadget<libff::Fr<wppT>>(pb, annotation_prefix)
27 , _P_primed(pb, FMT(annotation_prefix, " P_primed"))
29 pb, _P_primed, FMT(annotation_prefix, " P_primed_checker"))
30 , _P_primed_mul_cofactor(
35 FMT(annotation_prefix, " mul_by_cofactor"))
39 template<typename wppT>
40 void bls12_377_G1_membership_check_gadget<wppT>::generate_r1cs_constraints()
42 _P_primed_checker.generate_r1cs_constraints();
43 _P_primed_mul_cofactor.generate_r1cs_constraints();
46 template<typename wppT>
47 void bls12_377_G1_membership_check_gadget<wppT>::generate_r1cs_witness()
49 // P has already been witnessed. Compute P'.
50 const libff::G1<nppT> P_val(
51 this->pb.lc_val(_P.X), this->pb.lc_val(_P.Y), libff::Fq<nppT>::one());
52 const libff::G1<nppT> P_primed_val = P_val.proof_of_safe_subgroup();
54 // Witness P_primed and the multiplication gadget. Re-witness the result P,
55 // ensuring that the result is as expected.
56 _P_primed.generate_r1cs_witness(P_primed_val);
57 _P_primed_checker.generate_r1cs_witness();
58 _P_primed_mul_cofactor.generate_r1cs_witness();
59 _P.generate_r1cs_witness(P_val);
62 template<typename wppT>
63 G2_variable<wppT> bls12_377_g2_untwist_frobenius_twist(
64 protoboard<libff::Fr<wppT>> &pb,
65 const G2_variable<wppT> &g2,
67 const std::string &annotation_prefix)
69 // Follows the libff implementation of
70 // bls12_377_G2::untwist_frobenius_twist(). See:
71 // libff/algebra/curves/bls12_377/bls12_377_g2.cpp.
73 using nppT = other_curve<wppT>;
74 using FqeT = libff::Fqe<nppT>;
75 using FqkT = libff::Fqk<nppT>;
76 using Fq6T = typename FqkT::my_Fp6;
80 // (x as Fp6) * bls12_377_g2_untwist_frobenius_twist_v.coeffs[0]
82 // (y as Fp12) * bls12_377_g2_untwist_frobenius_twist_w_3
83 Fp6_3over2_variable<Fq6T> x_as_Fp6(
87 pb, libff::Fqe<nppT>::zero(), FMT(annotation_prefix, " Fqe(0)")),
89 pb, libff::Fqe<nppT>::zero(), FMT(annotation_prefix, " Fqe(0)")),
90 FMT(annotation_prefix, " x_as_Fp6"));
91 Fp6_3over2_variable<Fq6T> y_as_Fp6(
94 Fp2_variable<FqeT>(pb, FqeT::zero(), FMT(annotation_prefix, " Fqe(0)")),
95 Fp2_variable<FqeT>(pb, FqeT::zero(), FMT(annotation_prefix, " Fqe(0)")),
96 FMT(annotation_prefix, " y_as_Fp6"));
97 Fp12_2over3over2_variable<FqkT> y_as_Fp12(
100 Fp6_3over2_variable<Fq6T>(
101 pb, Fq6T::zero(), FMT(annotation_prefix, " Fp6(0)")),
102 FMT(annotation_prefix, " y_as_Fp12"));
104 Fp6_3over2_variable<Fq6T> untwist_x =
105 x_as_Fp6 * libff::bls12_377_g2_untwist_frobenius_twist_v.coeffs[0];
106 Fp12_2over3over2_variable<FqkT> untwist_y =
107 y_as_Fp12 * libff::bls12_377_g2_untwist_frobenius_twist_w_3;
110 Fp6_3over2_variable<Fq6T> frob_untwist_x = untwist_x.frobenius_map(exp);
111 Fp12_2over3over2_variable<FqkT> frob_untwist_y =
112 untwist_y.frobenius_map(exp);
115 Fp6_3over2_variable<Fq6T> twist_frob_untwist_x =
117 libff::bls12_377_g2_untwist_frobenius_twist_v_inverse.coeffs[0];
118 Fp12_2over3over2_variable<FqkT> twist_frob_untwist_y =
120 libff::bls12_377_g2_untwist_frobenius_twist_w_3_inverse;
122 return G2_variable<wppT>(
124 twist_frob_untwist_x._c0,
125 twist_frob_untwist_y._c0._c0,
129 // bls12_377_G2_membership_check_gadget
131 template<typename wppT>
132 bls12_377_G2_membership_check_gadget<wppT>::
133 bls12_377_G2_membership_check_gadget(
134 protoboard<libff::Fr<wppT>> &pb,
135 G2_variable<wppT> &P,
136 const std::string &annotation_prefix)
137 : gadget<libff::Fr<wppT>>(pb, annotation_prefix)
138 , _P_checker(pb, P, FMT(annotation_prefix, " _P_checker"))
142 bls12_377_g2_untwist_frobenius_twist(
143 pb, P, 1, FMT(annotation_prefix, " psi(P)")),
145 G2_variable<wppT>(pb, FMT(annotation_prefix, "psi(P)-P")),
146 FMT(annotation_prefix, " _psi_P_minus_P"))
148 , _t_times_psi_P_minus_P(
150 libff::bls12_377_trace_of_frobenius,
151 _psi_P_minus_P.result,
152 G2_variable<wppT>(pb, FMT(annotation_prefix, " [t](psi(P)-P)")),
153 FMT(annotation_prefix, " _t_times_psi_P_minus_P"))
154 // P + [t](\psi(P) - P)
155 , _P_plus_t_times_psi_P_minus_P(
158 _t_times_psi_P_minus_P.result(),
159 G2_variable<wppT>(pb, FMT(annotation_prefix, " P-[t](psi(P)-P)")),
160 FMT(annotation_prefix, " _P_plus_t_times_psi_P_minus_P"))
161 // P + [t](\psi(P) - P) = \psi^2(P)
162 , _h1_r_P_equals_zero(
164 _P_plus_t_times_psi_P_minus_P.result,
165 bls12_377_g2_untwist_frobenius_twist(
166 pb, P, 2, FMT(annotation_prefix, " psi^2(P)")),
167 FMT(annotation_prefix, " _h1_r_P_is_zero"))
171 template<typename wppT>
172 void bls12_377_G2_membership_check_gadget<wppT>::generate_r1cs_constraints()
174 _P_checker.generate_r1cs_constraints();
175 _psi_P_minus_P.generate_r1cs_constraints();
176 _t_times_psi_P_minus_P.generate_r1cs_constraints();
177 _P_plus_t_times_psi_P_minus_P.generate_r1cs_constraints();
178 _h1_r_P_equals_zero.generate_r1cs_constraints();
181 template<typename wppT>
182 void bls12_377_G2_membership_check_gadget<wppT>::generate_r1cs_witness()
184 _P_checker.generate_r1cs_witness();
186 // Evaluate result of untwist_frobenius_twist and -P
187 _psi_P_minus_P.A.X->evaluate();
188 _psi_P_minus_P.A.Y->evaluate();
189 _psi_P_minus_P.B.X->evaluate();
190 _psi_P_minus_P.B.Y->evaluate();
191 _psi_P_minus_P.generate_r1cs_witness();
193 _t_times_psi_P_minus_P.generate_r1cs_witness();
195 _P_plus_t_times_psi_P_minus_P.generate_r1cs_witness();
197 // Evaluate result of untwist_frobenius_twist
198 _h1_r_P_equals_zero._A.X->evaluate();
199 _h1_r_P_equals_zero._A.Y->evaluate();
200 _h1_r_P_equals_zero.generate_r1cs_witness();
203 } // namespace libsnark
205 #endif // LIBSNARK_GADGETLIB1_GADGETS_PAIRING_BW6_761_BLS12_377_BLS12_377_MEMBERSHIP_CHECK_GADGETS_TCC_