Files
dragonx/src/snark/libsnark/gadgetlib1/gadgets/gadget_from_r1cs.tcc
syd a55c186a74 Fix libsnark dependency build.
This changes libsnark to build in-place, instead of copying first to
a build directory. Previously, modifications made to the original
sources wouldn't get rebuilt without a 'make clean' because users
would be pointing to the copies.

This closes #2689.
2017-12-16 15:52:08 -05:00

124 lines
4.1 KiB
C++

/** @file
*****************************************************************************
Implementation of interfaces for a gadget that can be created from an R1CS constraint system.
See gadget_from_r1cs.hpp .
*****************************************************************************
* @author This file is part of libsnark, developed by SCIPR Lab
* and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#ifndef GADGET_FROM_R1CS_TCC_
#define GADGET_FROM_R1CS_TCC_
namespace libsnark {
template<typename FieldT>
gadget_from_r1cs<FieldT>::gadget_from_r1cs(protoboard<FieldT> &pb,
const std::vector<pb_variable_array<FieldT> > &vars,
const r1cs_constraint_system<FieldT> &cs,
const std::string &annotation_prefix) :
gadget<FieldT>(pb, annotation_prefix),
vars(vars),
cs(cs)
{
cs_to_vars[0] = 0; /* constant term maps to constant term */
size_t cs_var_idx = 1;
for (auto va : vars)
{
#ifdef DEBUG
printf("gadget_from_r1cs: translating a block of variables with length %zu\n", va.size());
#endif
for (auto v : va)
{
cs_to_vars[cs_var_idx] = v.index;
#ifdef DEBUG
if (v.index != 0)
{
// handle annotations, except for re-annotating constant term
const std::map<size_t, std::string>::const_iterator it = cs.variable_annotations.find(cs_var_idx);
std::string annotation = FMT(annotation_prefix, " variable_%zu", cs_var_idx);
if (it != cs.variable_annotations.end())
{
annotation = annotation_prefix + " " + it->second;
}
pb.augment_variable_annotation(v, annotation);
}
#endif
++cs_var_idx;
}
}
#ifdef DEBUG
printf("gadget_from_r1cs: sum of all block lengths: %zu\n", cs_var_idx-1);
printf("gadget_from_r1cs: cs.num_variables(): %zu\n", cs.num_variables());
#endif
assert(cs_var_idx - 1 == cs.num_variables());
}
template<typename FieldT>
void gadget_from_r1cs<FieldT>::generate_r1cs_constraints()
{
for (size_t i = 0; i < cs.num_constraints(); ++i)
{
const r1cs_constraint<FieldT> &constr = cs.constraints[i];
r1cs_constraint<FieldT> translated_constr;
for (const linear_term<FieldT> &t: constr.a.terms)
{
translated_constr.a.terms.emplace_back(linear_term<FieldT>(pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
}
for (const linear_term<FieldT> &t: constr.b.terms)
{
translated_constr.b.terms.emplace_back(linear_term<FieldT>(pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
}
for (const linear_term<FieldT> &t: constr.c.terms)
{
translated_constr.c.terms.emplace_back(linear_term<FieldT>(pb_variable<FieldT>(cs_to_vars[t.index]), t.coeff));
}
std::string annotation = FMT(this->annotation_prefix, " constraint_%zu", i);
#ifdef DEBUG
auto it = cs.constraint_annotations.find(i);
if (it != cs.constraint_annotations.end())
{
annotation = this->annotation_prefix + " " + it->second;
}
#endif
this->pb.add_r1cs_constraint(translated_constr, annotation);
}
}
template<typename FieldT>
void gadget_from_r1cs<FieldT>::generate_r1cs_witness(const r1cs_primary_input<FieldT> &primary_input,
const r1cs_auxiliary_input<FieldT> &auxiliary_input)
{
assert(cs.num_inputs() == primary_input.size());
assert(cs.num_variables() == primary_input.size() + auxiliary_input.size());
for (size_t i = 0; i < primary_input.size(); ++i)
{
this->pb.val(pb_variable<FieldT>(cs_to_vars[i+1])) = primary_input[i];
}
for (size_t i = 0; i < auxiliary_input.size(); ++i)
{
this->pb.val(pb_variable<FieldT>(cs_to_vars[primary_input.size()+i+1])) = auxiliary_input[i];
}
}
} // libsnark
#endif // GADGET_FROM_R1CS_TCC_