Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
bls12_377_membership_check_gadgets.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3  * @author This file is part of libsnark, developed by Clearmatics Ltd
4  * (originally developed by SCIPR Lab) and contributors
5  * (see AUTHORS).
6  * @copyright MIT license (see LICENSE file)
7  *****************************************************************************/
8 
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_
11 
12 #include "libsnark/gadgetlib1/gadgets/pairing/bw6_761_bls12_377/bls12_377_membership_check_gadgets.hpp"
13 
14 namespace libsnark
15 {
16 
17 // bls12_377_G2_membership_check_gadget
18 
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)
26  , _P(P)
27  , _P_primed(pb, FMT(annotation_prefix, " P_primed"))
28  , _P_primed_checker(
29  pb, _P_primed, FMT(annotation_prefix, " P_primed_checker"))
30  , _P_primed_mul_cofactor(
31  pb,
32  libff::G1<nppT>::h,
33  _P_primed,
34  P,
35  FMT(annotation_prefix, " mul_by_cofactor"))
36 {
37 }
38 
39 template<typename wppT>
40 void bls12_377_G1_membership_check_gadget<wppT>::generate_r1cs_constraints()
41 {
42  _P_primed_checker.generate_r1cs_constraints();
43  _P_primed_mul_cofactor.generate_r1cs_constraints();
44 }
45 
46 template<typename wppT>
47 void bls12_377_G1_membership_check_gadget<wppT>::generate_r1cs_witness()
48 {
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();
53 
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);
60 }
61 
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,
66  size_t exp,
67  const std::string &annotation_prefix)
68 {
69  // Follows the libff implementation of
70  // bls12_377_G2::untwist_frobenius_twist(). See:
71  // libff/algebra/curves/bls12_377/bls12_377_g2.cpp.
72 
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;
77 
78  // Untwist:
79  // untwist_x =
80  // (x as Fp6) * bls12_377_g2_untwist_frobenius_twist_v.coeffs[0]
81  // untwist_y =
82  // (y as Fp12) * bls12_377_g2_untwist_frobenius_twist_w_3
83  Fp6_3over2_variable<Fq6T> x_as_Fp6(
84  pb,
85  *g2.X,
86  Fp2_variable<FqeT>(
87  pb, libff::Fqe<nppT>::zero(), FMT(annotation_prefix, " Fqe(0)")),
88  Fp2_variable<FqeT>(
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(
92  pb,
93  *g2.Y,
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(
98  pb,
99  y_as_Fp6,
100  Fp6_3over2_variable<Fq6T>(
101  pb, Fq6T::zero(), FMT(annotation_prefix, " Fp6(0)")),
102  FMT(annotation_prefix, " y_as_Fp12"));
103 
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;
108 
109  // Frobenius:
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);
113 
114  // Twist:
115  Fp6_3over2_variable<Fq6T> twist_frob_untwist_x =
116  frob_untwist_x *
117  libff::bls12_377_g2_untwist_frobenius_twist_v_inverse.coeffs[0];
118  Fp12_2over3over2_variable<FqkT> twist_frob_untwist_y =
119  frob_untwist_y *
120  libff::bls12_377_g2_untwist_frobenius_twist_w_3_inverse;
121 
122  return G2_variable<wppT>(
123  pb,
124  twist_frob_untwist_x._c0,
125  twist_frob_untwist_y._c0._c0,
126  annotation_prefix);
127 }
128 
129 // bls12_377_G2_membership_check_gadget
130 
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"))
139  // \psi(P) - P
140  , _psi_P_minus_P(
141  pb,
142  bls12_377_g2_untwist_frobenius_twist(
143  pb, P, 1, FMT(annotation_prefix, " psi(P)")),
144  -P,
145  G2_variable<wppT>(pb, FMT(annotation_prefix, "psi(P)-P")),
146  FMT(annotation_prefix, " _psi_P_minus_P"))
147  // [t](\psi(P) - P)
148  , _t_times_psi_P_minus_P(
149  pb,
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(
156  pb,
157  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(
163  pb,
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"))
168 {
169 }
170 
171 template<typename wppT>
172 void bls12_377_G2_membership_check_gadget<wppT>::generate_r1cs_constraints()
173 {
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();
179 }
180 
181 template<typename wppT>
182 void bls12_377_G2_membership_check_gadget<wppT>::generate_r1cs_witness()
183 {
184  _P_checker.generate_r1cs_witness();
185 
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();
192 
193  _t_times_psi_P_minus_P.generate_r1cs_witness();
194 
195  _P_plus_t_times_psi_P_minus_P.generate_r1cs_witness();
196 
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();
201 }
202 
203 } // namespace libsnark
204 
205 #endif // LIBSNARK_GADGETLIB1_GADGETS_PAIRING_BW6_761_BLS12_377_BLS12_377_MEMBERSHIP_CHECK_GADGETS_TCC_