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.
This commit is contained in:
330
src/snark/libsnark/gadgetlib1/pb_variable.tcc
Normal file
330
src/snark/libsnark/gadgetlib1/pb_variable.tcc
Normal file
@@ -0,0 +1,330 @@
|
||||
/** @file
|
||||
*****************************************************************************
|
||||
* @author This file is part of libsnark, developed by SCIPR Lab
|
||||
* and contributors (see AUTHORS).
|
||||
* @copyright MIT license (see LICENSE file)
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef PB_VARIABLE_TCC_
|
||||
#define PB_VARIABLE_TCC_
|
||||
#include <cassert>
|
||||
#include "gadgetlib1/protoboard.hpp"
|
||||
#include "common/utils.hpp"
|
||||
|
||||
namespace libsnark {
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_variable<FieldT>::allocate(protoboard<FieldT> &pb, const std::string &annotation)
|
||||
{
|
||||
this->index = pb.allocate_var_index(annotation);
|
||||
}
|
||||
|
||||
/* allocates pb_variable<FieldT> array in MSB->LSB order */
|
||||
template<typename FieldT>
|
||||
void pb_variable_array<FieldT>::allocate(protoboard<FieldT> &pb, const size_t n, const std::string &annotation_prefix)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(annotation_prefix != "");
|
||||
#endif
|
||||
(*this).resize(n);
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
(*this)[i].allocate(pb, FMT(annotation_prefix, "_%zu", i));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_variable_array<FieldT>::fill_with_field_elements(protoboard<FieldT> &pb, const std::vector<FieldT>& vals) const
|
||||
{
|
||||
assert(this->size() == vals.size());
|
||||
for (size_t i = 0; i < vals.size(); ++i)
|
||||
{
|
||||
pb.val((*this)[i]) = vals[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_variable_array<FieldT>::fill_with_bits(protoboard<FieldT> &pb, const bit_vector& bits) const
|
||||
{
|
||||
assert(this->size() == bits.size());
|
||||
for (size_t i = 0; i < bits.size(); ++i)
|
||||
{
|
||||
pb.val((*this)[i]) = (bits[i] ? FieldT::one() : FieldT::zero());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_variable_array<FieldT>::fill_with_bits_of_field_element(protoboard<FieldT> &pb, const FieldT &r) const
|
||||
{
|
||||
const bigint<FieldT::num_limbs> rint = r.as_bigint();
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
pb.val((*this)[i]) = rint.test_bit(i) ? FieldT::one() : FieldT::zero();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_variable_array<FieldT>::fill_with_bits_of_ulong(protoboard<FieldT> &pb, const unsigned long i) const
|
||||
{
|
||||
this->fill_with_bits_of_field_element(pb, FieldT(i, true));
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
std::vector<FieldT> pb_variable_array<FieldT>::get_vals(const protoboard<FieldT> &pb) const
|
||||
{
|
||||
std::vector<FieldT> result(this->size());
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
result[i] = pb.val((*this)[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
bit_vector pb_variable_array<FieldT>::get_bits(const protoboard<FieldT> &pb) const
|
||||
{
|
||||
bit_vector result;
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
const FieldT v = pb.val((*this)[i]);
|
||||
assert(v == FieldT::zero() || v == FieldT::one());
|
||||
result.push_back(v == FieldT::one());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
FieldT pb_variable_array<FieldT>::get_field_element_from_bits(const protoboard<FieldT> &pb) const
|
||||
{
|
||||
FieldT result = FieldT::zero();
|
||||
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
/* push in the new bit */
|
||||
const FieldT v = pb.val((*this)[this->size()-1-i]);
|
||||
assert(v == FieldT::zero() || v == FieldT::one());
|
||||
result += result + v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
pb_linear_combination<FieldT>::pb_linear_combination()
|
||||
{
|
||||
this->is_variable = false;
|
||||
this->index = 0;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
pb_linear_combination<FieldT>::pb_linear_combination(const pb_variable<FieldT> &var)
|
||||
{
|
||||
this->is_variable = true;
|
||||
this->index = var.index;
|
||||
this->terms.emplace_back(linear_term<FieldT>(var));
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination<FieldT>::assign(protoboard<FieldT> &pb, const linear_combination<FieldT> &lc)
|
||||
{
|
||||
assert(this->is_variable == false);
|
||||
this->index = pb.allocate_lc_index();
|
||||
this->terms = lc.terms;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination<FieldT>::evaluate(protoboard<FieldT> &pb) const
|
||||
{
|
||||
if (this->is_variable)
|
||||
{
|
||||
return; // do nothing
|
||||
}
|
||||
|
||||
FieldT sum = 0;
|
||||
for (auto term : this->terms)
|
||||
{
|
||||
sum += term.coeff * pb.val(pb_variable<FieldT>(term.index));
|
||||
}
|
||||
|
||||
pb.lc_val(*this) = sum;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
bool pb_linear_combination<FieldT>::is_constant() const
|
||||
{
|
||||
if (is_variable)
|
||||
{
|
||||
return (index == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto term : this->terms)
|
||||
{
|
||||
if (term.index != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
FieldT pb_linear_combination<FieldT>::constant_term() const
|
||||
{
|
||||
if (is_variable)
|
||||
{
|
||||
return (index == 0 ? FieldT::one() : FieldT::zero());
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldT result = FieldT::zero();
|
||||
for (auto term : this->terms)
|
||||
{
|
||||
if (term.index == 0)
|
||||
{
|
||||
result += term.coeff;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination_array<FieldT>::evaluate(protoboard<FieldT> &pb) const
|
||||
{
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
(*this)[i].evaluate(pb);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination_array<FieldT>::fill_with_field_elements(protoboard<FieldT> &pb, const std::vector<FieldT>& vals) const
|
||||
{
|
||||
assert(this->size() == vals.size());
|
||||
for (size_t i = 0; i < vals.size(); ++i)
|
||||
{
|
||||
pb.lc_val((*this)[i]) = vals[i];
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination_array<FieldT>::fill_with_bits(protoboard<FieldT> &pb, const bit_vector& bits) const
|
||||
{
|
||||
assert(this->size() == bits.size());
|
||||
for (size_t i = 0; i < bits.size(); ++i)
|
||||
{
|
||||
pb.lc_val((*this)[i]) = (bits[i] ? FieldT::one() : FieldT::zero());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination_array<FieldT>::fill_with_bits_of_field_element(protoboard<FieldT> &pb, const FieldT &r) const
|
||||
{
|
||||
const bigint<FieldT::num_limbs> rint = r.as_bigint();
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
pb.lc_val((*this)[i]) = rint.test_bit(i) ? FieldT::one() : FieldT::zero();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void pb_linear_combination_array<FieldT>::fill_with_bits_of_ulong(protoboard<FieldT> &pb, const unsigned long i) const
|
||||
{
|
||||
this->fill_with_bits_of_field_element(pb, FieldT(i));
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
std::vector<FieldT> pb_linear_combination_array<FieldT>::get_vals(const protoboard<FieldT> &pb) const
|
||||
{
|
||||
std::vector<FieldT> result(this->size());
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
result[i] = pb.lc_val((*this)[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
bit_vector pb_linear_combination_array<FieldT>::get_bits(const protoboard<FieldT> &pb) const
|
||||
{
|
||||
bit_vector result;
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
const FieldT v = pb.lc_val((*this)[i]);
|
||||
assert(v == FieldT::zero() || v == FieldT::one());
|
||||
result.push_back(v == FieldT::one());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
FieldT pb_linear_combination_array<FieldT>::get_field_element_from_bits(const protoboard<FieldT> &pb) const
|
||||
{
|
||||
FieldT result = FieldT::zero();
|
||||
|
||||
for (size_t i = 0; i < this->size(); ++i)
|
||||
{
|
||||
/* push in the new bit */
|
||||
const FieldT v = pb.lc_val((*this)[this->size()-1-i]);
|
||||
assert(v == FieldT::zero() || v == FieldT::one());
|
||||
result += result + v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
linear_combination<FieldT> pb_sum(const pb_linear_combination_array<FieldT> &v)
|
||||
{
|
||||
linear_combination<FieldT> result;
|
||||
for (auto &term : v)
|
||||
{
|
||||
result = result + term;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
linear_combination<FieldT> pb_packing_sum(const pb_linear_combination_array<FieldT> &v)
|
||||
{
|
||||
FieldT twoi = FieldT::one(); // will hold 2^i entering each iteration
|
||||
std::vector<linear_term<FieldT> > all_terms;
|
||||
for (auto &lc : v)
|
||||
{
|
||||
for (auto &term : lc.terms)
|
||||
{
|
||||
all_terms.emplace_back(twoi * term);
|
||||
}
|
||||
twoi += twoi;
|
||||
}
|
||||
|
||||
return linear_combination<FieldT>(all_terms);
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
linear_combination<FieldT> pb_coeff_sum(const pb_linear_combination_array<FieldT> &v, const std::vector<FieldT> &coeffs)
|
||||
{
|
||||
assert(v.size() == coeffs.size());
|
||||
std::vector<linear_term<FieldT> > all_terms;
|
||||
|
||||
auto coeff_it = coeffs.begin();
|
||||
for (auto &lc : v)
|
||||
{
|
||||
for (auto &term : lc.terms)
|
||||
{
|
||||
all_terms.emplace_back((*coeff_it) * term);
|
||||
}
|
||||
++coeff_it;
|
||||
}
|
||||
|
||||
return linear_combination<FieldT>(all_terms);
|
||||
}
|
||||
|
||||
|
||||
} // libsnark
|
||||
#endif // PB_VARIABLE_TCC
|
||||
Reference in New Issue
Block a user