2 *****************************************************************************
4 Implementation of interfaces for a gadget that can be created from an R1CS
7 See gadget_from_r1cs.hpp .
9 *****************************************************************************
10 * @author This file is part of libsnark, developed by SCIPR Lab
11 * and contributors (see AUTHORS).
12 * @copyright MIT license (see LICENSE file)
13 *****************************************************************************/
15 #ifndef GADGET_FROM_R1CS_TCC_
16 #define GADGET_FROM_R1CS_TCC_
21 template<typename FieldT>
22 gadget_from_r1cs<FieldT>::gadget_from_r1cs(
23 protoboard<FieldT> &pb,
24 const std::vector<pb_variable_array<FieldT>> &vars,
25 const r1cs_constraint_system<FieldT> &cs,
26 const std::string &annotation_prefix)
27 : gadget<FieldT>(pb, annotation_prefix), vars(vars), cs(cs)
29 cs_to_vars[0] = 0; /* constant term maps to constant term */
31 size_t cs_var_idx = 1;
32 for (auto va : vars) {
35 "gadget_from_r1cs: translating a block of variables with length "
40 cs_to_vars[cs_var_idx] = v.index;
44 // handle annotations, except for re-annotating constant term
45 const std::map<size_t, std::string>::const_iterator it =
46 cs.variable_annotations.find(cs_var_idx);
48 std::string annotation =
49 FMT(annotation_prefix, " variable_%zu", cs_var_idx);
50 if (it != cs.variable_annotations.end()) {
51 annotation = annotation_prefix + " " + it->second;
54 pb.augment_variable_annotation(v, annotation);
62 printf("gadget_from_r1cs: sum of all block lengths: %zu\n", cs_var_idx - 1);
63 printf("gadget_from_r1cs: cs.num_variables(): %zu\n", cs.num_variables());
66 assert(cs_var_idx - 1 == cs.num_variables());
69 template<typename FieldT>
70 void gadget_from_r1cs<FieldT>::generate_r1cs_constraints()
72 for (size_t i = 0; i < cs.num_constraints(); ++i) {
73 const r1cs_constraint<FieldT> &constr = cs.constraints[i];
74 r1cs_constraint<FieldT> translated_constr;
76 for (const linear_term<FieldT> &t : constr.a.terms) {
77 translated_constr.a.terms.emplace_back(linear_term<FieldT>(
78 pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
81 for (const linear_term<FieldT> &t : constr.b.terms) {
82 translated_constr.b.terms.emplace_back(linear_term<FieldT>(
83 pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
86 for (const linear_term<FieldT> &t : constr.c.terms) {
87 translated_constr.c.terms.emplace_back(linear_term<FieldT>(
88 pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
91 std::string annotation =
92 FMT(this->annotation_prefix, " constraint_%zu", i);
95 auto it = cs.constraint_annotations.find(i);
96 if (it != cs.constraint_annotations.end()) {
97 annotation = this->annotation_prefix + " " + it->second;
100 this->pb.add_r1cs_constraint(translated_constr, annotation);
104 template<typename FieldT>
105 void gadget_from_r1cs<FieldT>::generate_r1cs_witness(
106 const r1cs_primary_input<FieldT> &primary_input,
107 const r1cs_auxiliary_input<FieldT> &auxiliary_input)
109 assert(cs.num_inputs() == primary_input.size());
110 assert(cs.num_variables() == primary_input.size() + auxiliary_input.size());
112 for (size_t i = 0; i < primary_input.size(); ++i) {
113 this->pb.val(pb_variable<FieldT>(cs_to_vars[i + 1])) = primary_input[i];
116 for (size_t i = 0; i < auxiliary_input.size(); ++i) {
117 this->pb.val(pb_variable<FieldT>(
118 cs_to_vars[primary_input.size() + i + 1])) = auxiliary_input[i];
122 } // namespace libsnark
124 #endif // GADGET_FROM_R1CS_TCC_