Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
scalar_multiplication.hpp
Go to the documentation of this file.
1 
9 #ifndef LIBSNARK_GADGETLIB1_GADGETS_CURVE_SCALAR_MULTIPLICATION_HPP_
10 #define LIBSNARK_GADGETLIB1_GADGETS_CURVE_SCALAR_MULTIPLICATION_HPP_
11 
15 
16 #include <libff/algebra/curves/public_params.hpp>
17 #include <memory>
18 
19 namespace libsnark
20 {
21 
34 template<typename ppT, typename groupT, typename groupVariableT>
35 class variable_or_identity : public gadget<libff::Fr<ppT>>
36 {
37 public:
38  using FieldT = libff::Fr<ppT>;
39 
40  groupVariableT value;
42 
43  // Internally allocates the variable and flag, to be set later via the
44  // generate_r1cs_witness calls.
46  protoboard<FieldT> &pb, const std::string &annotation_prefix);
47 
48  // Initialize the variable and flag with constants. Do not try to call
49  // generate_r1cs_witness().
52  const groupT &P,
53  const std::string &annotation_prefix);
54 
58 
61  void generate_r1cs_witness(const groupT &elt);
62 
66 
67  groupT get_element() const;
68 
69 protected:
70  // Only allocated if necessary, in which case it should be set using
71  // generate_r1cs_witness().
73 };
74 
76 template<
77  typename ppT,
78  typename groupT,
79  typename variableT,
80  typename variableSelectorT>
81 class variable_or_identity_selector : public gadget<libff::Fr<ppT>>
82 {
83 public:
84  using FieldT = libff::Fr<ppT>;
86 
87  // result.value = variableSelectorT(
88  // selector, zero_case.value, one_case.value)
89  variableSelectorT value_selector;
90 
91  // result.is_identity = (1 - selector) * zero_case + selector * one_case
92  // = selector * (one_case - zero_case) + zero_case
93  // <=> result.is_identity - zero_case = selector * (one_case - zero_case)
97 
100  const pb_linear_combination<FieldT> &selector,
101  const variableOrIdentity &zero_case,
102  const variableOrIdentity &one_case,
103  const variableOrIdentity &result,
104  const std::string &annotation_prefix);
105 
107  void generate_r1cs_witness();
108 };
109 
111 template<
112  typename ppT,
113  typename groupT,
114  typename variableT,
115  typename variableSelectorT>
117 {
118 public:
119  using FieldT = libff::Fr<ppT>;
121 
122  // result.value = select(selector, zero_case.value, one_case)
123  variableSelectorT value_selector;
124 
125  // result.is_identity = (1 - selector) * zero_case
129 
132  const pb_linear_combination<FieldT> &selector,
133  const variableOrIdentity &zero_case,
134  const variableT &one_case,
135  const variableOrIdentity &result,
136  const std::string &annotation_prefix);
137 
139  void generate_r1cs_witness();
140 };
141 
145 template<
146  typename ppT,
147  typename groupT,
148  typename variableT,
149  typename variableSelectorT,
150  typename addGadgetT>
151 class add_variable_or_identity : public gadget<libff::Fr<ppT>>
152 {
153 public:
154  using FieldT = libff::Fr<ppT>;
156 
157  // Recall the form of the variable selector gadget parameters:
158  // variableSelectorT(<flag>, <zero_case>, <one_case>)
159  //
160  // The `is_identity` flags of A, B and result are known to be boolean by
161  // the constraints in variable_or_identity.
162  //
163  // The output from this gadget should therefore be:
164  //
165  // result.is_identity = A.is_identity * B.is_identity
166  //
167  // result.value = variableSelectorT( // selector_A
168  // A.is_identity,
169  // variableSelectorT( // selector_A_not_identity
170  // B.is_identity,
171  // add_result, // A != 0 && B != 0
172  // A.value), // A != 0 && B == 0
173  // variableSelectorT( // selector_A_is_identity
174  // B.is_identity,
175  // B.value, // A == 0 && B != 0
176  // groupT::one()) // A == 0 && B == 0
177  //
178  // Note, this can be reduced to:
179  //
180  // result.is_identity = A.is_identity * B.is_identity
181  //
182  // result.value = variableSelectorT( // selector_A
183  // A.is_identity,
184  // variableSelectorT( // selector_A_not_identity
185  // B.is_identity,
186  // add_result, // A != 0 && B != 0
187  // A.value), // A != 0 && B == 0
188  // B.value)
189 
190  variableT add_result;
191  addGadgetT add;
192 
193  // A_not_identity_result = variableSelectorT(
194  // B.is_identity, add_result, A.value)
196  variableSelectorT selector_A_not_identity;
197 
198  // result = variableSelectorT(
199  // A.is_identity, A_not_identity_result, B.value)
200  variableSelectorT selector_A;
201 
203 
206  const variableOrIdentity &A,
207  const variableOrIdentity &B,
208  const variableOrIdentity &result,
209  const std::string &annotation_prefix);
210 
212 
213  void generate_r1cs_witness();
214 };
215 
218 template<
219  typename ppT,
220  typename groupT,
221  typename variableT,
222  typename variableSelectorT,
223  typename addGadgetT>
224 class add_variable_and_variable_or_identity : public gadget<libff::Fr<ppT>>
225 {
226 public:
227  using FieldT = libff::Fr<ppT>;
229 
230  // Recall the form of the variable selector gadget parameters:
231  // variableSelectorT(<flag>, <zero_case>, <one_case>)
232  //
233  // The `is_identity` flag of A is known to be boolean by the constraints in
234  // variable_or_identity.
235  //
236  // The output from this gadget should therefore be:
237  //
238  // add_result = add(A.value, B)
239  //
240  // result.value = variableSelectorT(
241  // A.is_identity,
242  // B, // A == 0 case
243  // add_result) // A != 0 case
244 
245  variableT result;
246  variableT add_result;
247  addGadgetT add;
248  variableSelectorT selector_A;
249 
252  const variableOrIdentity &A,
253  const variableT &B,
254  const variableT &result,
255  const std::string &annotation_prefix);
256 
258 
259  void generate_r1cs_witness();
260 };
261 
264 template<
265  typename ppT,
266  typename groupT,
267  typename groupVariableT,
268  typename dblGadgetT>
269 class dbl_variable_or_identity : public gadget<libff::Fr<ppT>>
270 {
271 public:
272  using FieldT = libff::Fr<ppT>;
273  using variableOrIdentity =
275 
276  // The goal is:
277  //
278  // result = select(A.is_identity, 0, double(A))
279  //
280  // which is achieved via:
281  //
282  // result.value = double(A)
283  // result.is_identity = A.is_identity
284  //
285  // Note: result.is_identity does not need to be allocated, but the current
286  // variable_or_identity interface always allocates. Ideally it would simply
287  // be set to pb_linear_combination(A.is_identity), which costs nothing
288 
291  dblGadgetT double_gadget;
292 
295  const variableOrIdentity &A,
296  const variableOrIdentity &result,
297  const std::string &annotation_prefix);
299  void generate_r1cs_witness();
300 };
301 
304 template<
305  typename groupT,
306  typename groupVariableT,
307  typename add_gadget,
308  typename dbl_gadget,
309  typename scalarT>
311  : public gadget<typename groupT::base_field>
312 {
313 public:
314  using FieldT = typename groupT::base_field;
315 
316  const scalarT _scalar;
317  const groupVariableT _result;
318  std::vector<std::shared_ptr<add_gadget>> _add_gadgets;
319  std::vector<std::shared_ptr<dbl_gadget>> _dbl_gadgets;
320 
323  const scalarT &scalar,
324  const groupVariableT &P,
325  const groupVariableT &result,
326  const std::string &annotation_prefix);
327 
329  void generate_r1cs_witness();
330  const groupVariableT &result() const;
331 };
332 
335 template<
336  typename ppT,
337  typename groupT,
338  typename groupVarT,
339  typename selectorGadgetT,
340  typename addGadgetT,
341  typename dblGadgetT>
342 class point_mul_by_scalar_gadget : public gadget<typename groupT::base_field>
343 {
344 public:
345  using Field = libff::Fr<ppT>;
346  using nFr = libff::Fr<other_curve<ppT>>;
350  ppT,
351  groupT,
352  groupVarT,
353  selectorGadgetT>;
355  ppT,
356  groupT,
357  groupVarT,
358  selectorGadgetT,
359  addGadgetT>;
360  using dblVarOrIdentityGadget =
362 
364  std::vector<dblVarOrIdentityGadget> dbl_gadgets;
365  std::vector<addVarAndVarOrIdentityGadget> add_gadgets;
366  std::vector<selectVarOrVarIdentityGadget> selector_gadgets;
367 
368  // Use to avoid adding P + -P in the final loop.
369  //
370  // For scalar = -1, the final loop can result in a call to addGadgetT(P,
371  // -P), which is not supported (results in a division by zero since the X
372  // coordinates of P and -P are the same). This is because: after the final
373  // double, scalar * P = -P has been computed, and the final (lowest order)
374  // bit of scalar is 0 (i.e. no further addition is required). However,
375  // since the constraints must hold for all scalar values, the final
376  // addition is always performed (but filtered out).
377  //
378  // To handle this edge case, we "select" either the correct intermediate
379  // values (if the 0-th bit is 1), or some hard-coded values which are known
380  // to work with addGadgetT (if 0-th bit is 0). This situation should not
381  // arise in other cases, since all intermediate multiple of P are
382  // necessarily multiples strictly smaller than the (prime) order of the
383  // group - 1.
384 
385  std::shared_ptr<selectVarOrVarIdentityGadget> final_add_input_left;
386  std::shared_ptr<selectorGadgetT> final_add_input_right;
387 
390  const pb_linear_combination<Field> &scalar,
391  const groupVarT &P,
392  const groupVarOrIdentity &result,
393  const std::string &annotation_prefix);
394 
396  void generate_r1cs_witness();
397  const groupVarOrIdentity &result() const;
398 
399 protected:
401  protoboard<Field> &pb, const std::string &annotation_prefix);
402 };
403 
404 } // namespace libsnark
405 
407 
408 #endif // LIBSNARK_GADGETLIB1_GADGETS_CURVE_SCALAR_MULTIPLICATION_HPP_
libsnark::dbl_variable_or_identity::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::variable_or_identity::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::add_variable_or_identity::selector_A_not_identity
variableSelectorT selector_A_not_identity
Definition: scalar_multiplication.hpp:196
libsnark::dbl_variable_or_identity::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::point_mul_by_const_scalar_gadget::_result
const groupVariableT _result
Definition: scalar_multiplication.hpp:317
libsnark::point_mul_by_scalar_gadget< ppT >::Field
libff::Fr< ppT > Field
Definition: scalar_multiplication.hpp:345
libsnark::gadget< libff::Fr< ppT > >::annotation_prefix
const std::string annotation_prefix
Definition: gadget.hpp:20
libsnark::point_mul_by_const_scalar_gadget::_add_gadgets
std::vector< std::shared_ptr< add_gadget > > _add_gadgets
Definition: scalar_multiplication.hpp:318
libsnark
Definition: accumulation_vector.hpp:18
libsnark::variable_and_variable_or_identity_selector::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::point_mul_by_const_scalar_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::add_variable_or_identity::add_variable_or_identity
add_variable_or_identity(protoboard< FieldT > &pb, const variableOrIdentity &A, const variableOrIdentity &B, const variableOrIdentity &result, const std::string &annotation_prefix)
libsnark::add_variable_or_identity::add
addGadgetT add
Definition: scalar_multiplication.hpp:191
libsnark::variable_or_identity_selector::result_is_identity
pb_linear_combination< FieldT > result_is_identity
Definition: scalar_multiplication.hpp:96
libsnark::dbl_variable_or_identity::double_gadget
dblGadgetT double_gadget
Definition: scalar_multiplication.hpp:291
libsnark::variable_or_identity_selector::one_case_is_identity
pb_linear_combination< FieldT > one_case_is_identity
Definition: scalar_multiplication.hpp:95
libsnark::variable_or_identity_selector::FieldT
libff::Fr< ppT > FieldT
Definition: scalar_multiplication.hpp:84
libsnark::add_variable_or_identity::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::variable_or_identity< ppT >::FieldT
libff::Fr< ppT > FieldT
Definition: scalar_multiplication.hpp:38
libsnark::add_variable_and_variable_or_identity::selector_A
variableSelectorT selector_A
Definition: scalar_multiplication.hpp:248
libsnark::variable_or_identity::is_identity
pb_linear_combination< FieldT > is_identity
Definition: scalar_multiplication.hpp:41
libsnark::gadget< libff::Fr< ppT > >::pb
protoboard< libff::Fr< ppT > > & pb
Definition: gadget.hpp:19
libsnark::variable_or_identity_selector::value_selector
variableSelectorT value_selector
Definition: scalar_multiplication.hpp:89
libsnark::add_variable_and_variable_or_identity::FieldT
libff::Fr< ppT > FieldT
Definition: scalar_multiplication.hpp:227
libsnark::variable_and_variable_or_identity_selector::one_case_is_identity
pb_linear_combination< FieldT > one_case_is_identity
Definition: scalar_multiplication.hpp:127
libsnark::variable_or_identity::get_element
groupT get_element() const
libsnark::add_variable_or_identity::A_not_identity_result
variableT A_not_identity_result
Definition: scalar_multiplication.hpp:195
libsnark::variable_or_identity::variable_or_identity
variable_or_identity(protoboard< FieldT > &pb, const std::string &annotation_prefix)
libsnark::variable_and_variable_or_identity_selector::value_selector
variableSelectorT value_selector
Definition: scalar_multiplication.hpp:123
gadget.hpp
libsnark::point_mul_by_scalar_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::point_mul_by_const_scalar_gadget::result
const groupVariableT & result() const
libsnark::point_mul_by_const_scalar_gadget< wppT, libff::bls12_377_r_limbs >::FieldT
typename wppT ::base_field FieldT
Definition: scalar_multiplication.hpp:314
libsnark::variable_or_identity::generate_r1cs_witness
void generate_r1cs_witness(const groupT &elt)
libsnark::variable_and_variable_or_identity_selector::variable_and_variable_or_identity_selector
variable_and_variable_or_identity_selector(protoboard< FieldT > &pb, const pb_linear_combination< FieldT > &selector, const variableOrIdentity &zero_case, const variableT &one_case, const variableOrIdentity &result, const std::string &annotation_prefix)
libsnark::dbl_variable_or_identity
Definition: scalar_multiplication.hpp:269
libsnark::variable_and_variable_or_identity_selector::FieldT
libff::Fr< ppT > FieldT
Definition: scalar_multiplication.hpp:119
libsnark::point_mul_by_scalar_gadget::final_add_input_left
std::shared_ptr< selectVarOrVarIdentityGadget > final_add_input_left
Definition: scalar_multiplication.hpp:385
libsnark::dbl_variable_or_identity::dbl_variable_or_identity
dbl_variable_or_identity(protoboard< FieldT > &pb, const variableOrIdentity &A, const variableOrIdentity &result, const std::string &annotation_prefix)
libsnark::gadget
Definition: gadget.hpp:16
libsnark::add_variable_or_identity
Definition: scalar_multiplication.hpp:151
libsnark::add_variable_and_variable_or_identity::add
addGadgetT add
Definition: scalar_multiplication.hpp:247
libsnark::point_mul_by_scalar_gadget::selector_gadgets
std::vector< selectVarOrVarIdentityGadget > selector_gadgets
Definition: scalar_multiplication.hpp:366
libsnark::add_variable_or_identity::FieldT
libff::Fr< ppT > FieldT
Definition: scalar_multiplication.hpp:154
libsnark::point_mul_by_const_scalar_gadget::point_mul_by_const_scalar_gadget
point_mul_by_const_scalar_gadget(protoboard< FieldT > &pb, const scalarT &scalar, const groupVariableT &P, const groupVariableT &result, const std::string &annotation_prefix)
libsnark::point_mul_by_scalar_gadget< ppT >::nFr
libff::Fr< other_curve< ppT > > nFr
Definition: scalar_multiplication.hpp:346
libsnark::point_mul_by_scalar_gadget::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::variable_and_variable_or_identity_selector::zero_case_is_identity
pb_linear_combination< FieldT > zero_case_is_identity
Definition: scalar_multiplication.hpp:126
libsnark::add_variable_and_variable_or_identity::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::add_variable_or_identity::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::add_variable_and_variable_or_identity::add_result
variableT add_result
Definition: scalar_multiplication.hpp:246
libsnark::point_mul_by_scalar_gadget::result
const groupVarOrIdentity & result() const
libsnark::variable_or_identity_selector::generate_r1cs_witness
void generate_r1cs_witness()
pairing_params.hpp
libsnark::add_variable_or_identity::add_result
variableT add_result
Definition: scalar_multiplication.hpp:190
libsnark::variable_or_identity::is_identity_var
pb_variable< FieldT > is_identity_var
Definition: scalar_multiplication.hpp:72
libsnark::pb_linear_combination
Definition: pb_variable.hpp:101
libsnark::variable_or_identity_selector
Selector gadget for variable_or_identity.
Definition: scalar_multiplication.hpp:81
scalar_multiplication.tcc
libsnark::variable_or_identity
Definition: scalar_multiplication.hpp:35
libsnark::dbl_variable_or_identity::result
variableOrIdentity result
Definition: scalar_multiplication.hpp:290
libsnark::variable_and_variable_or_identity_selector::result
variableOrIdentity result
Definition: scalar_multiplication.hpp:128
libsnark::pb_variable
Definition: pb_variable.hpp:24
libsnark::packing_gadget< Field >
basic_gadgets.hpp
libsnark::variable_or_identity_selector::variable_or_identity_selector
variable_or_identity_selector(protoboard< FieldT > &pb, const pb_linear_combination< FieldT > &selector, const variableOrIdentity &zero_case, const variableOrIdentity &one_case, const variableOrIdentity &result, const std::string &annotation_prefix)
libsnark::point_mul_by_scalar_gadget::point_mul_by_scalar_gadget
point_mul_by_scalar_gadget(protoboard< Field > &pb, const pb_linear_combination< Field > &scalar, const groupVarT &P, const groupVarOrIdentity &result, const std::string &annotation_prefix)
libsnark::pb_variable_array
Definition: pb_variable.hpp:44
libsnark::variable_or_identity_selector::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::point_mul_by_const_scalar_gadget::generate_r1cs_constraints
void generate_r1cs_constraints()
libsnark::dbl_variable_or_identity::FieldT
libff::Fr< ppT > FieldT
Definition: scalar_multiplication.hpp:272
libsnark::add_variable_and_variable_or_identity::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::add_variable_and_variable_or_identity::add_variable_and_variable_or_identity
add_variable_and_variable_or_identity(protoboard< FieldT > &pb, const variableOrIdentity &A, const variableT &B, const variableT &result, const std::string &annotation_prefix)
libsnark::point_mul_by_const_scalar_gadget::_scalar
const scalarT _scalar
Definition: scalar_multiplication.hpp:316
libsnark::point_mul_by_scalar_gadget::dbl_gadgets
std::vector< dblVarOrIdentityGadget > dbl_gadgets
Definition: scalar_multiplication.hpp:364
libsnark::add_variable_or_identity::result
variableOrIdentity result
Definition: scalar_multiplication.hpp:202
libsnark::point_mul_by_scalar_gadget::add_gadgets
std::vector< addVarAndVarOrIdentityGadget > add_gadgets
Definition: scalar_multiplication.hpp:365
libsnark::point_mul_by_scalar_gadget::scalar_unpacked
packing_gadget< Field > scalar_unpacked
Definition: scalar_multiplication.hpp:363
libsnark::variable_and_variable_or_identity_selector::generate_r1cs_witness
void generate_r1cs_witness()
libsnark::point_mul_by_const_scalar_gadget::_dbl_gadgets
std::vector< std::shared_ptr< dbl_gadget > > _dbl_gadgets
Definition: scalar_multiplication.hpp:319
libsnark::point_mul_by_scalar_gadget::final_add_input_right
std::shared_ptr< selectorGadgetT > final_add_input_right
Definition: scalar_multiplication.hpp:386
libsnark::dbl_variable_or_identity::A_is_identity
pb_linear_combination< FieldT > A_is_identity
Definition: scalar_multiplication.hpp:289
libsnark::add_variable_and_variable_or_identity::result
variableT result
Definition: scalar_multiplication.hpp:245
libsnark::variable_or_identity_selector::zero_case_is_identity
pb_linear_combination< FieldT > zero_case_is_identity
Definition: scalar_multiplication.hpp:94
libsnark::add_variable_and_variable_or_identity
Definition: scalar_multiplication.hpp:224
libsnark::point_mul_by_scalar_gadget
Definition: scalar_multiplication.hpp:342
libsnark::point_mul_by_scalar_gadget::create_variable_array_for_bits
static pb_variable_array< Field > create_variable_array_for_bits(protoboard< Field > &pb, const std::string &annotation_prefix)
libsnark::add_variable_or_identity::selector_A
variableSelectorT selector_A
Definition: scalar_multiplication.hpp:200
libsnark::variable_or_identity::value
groupVariableT value
Definition: scalar_multiplication.hpp:40
libsnark::point_mul_by_const_scalar_gadget
Definition: scalar_multiplication.hpp:310
libsnark::variable_and_variable_or_identity_selector
Selector gadget for a variable_or_identity, and a variable.
Definition: scalar_multiplication.hpp:116
libsnark::protoboard
Definition: pb_variable.hpp:22