Skip to content

Commit

Permalink
some (unoptimized) utility functions for polynomials in terms of powe…
Browse files Browse the repository at this point in the history
…rsoftau
  • Loading branch information
dtebbs committed Aug 21, 2019
1 parent 72e55ed commit 6cef625
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/snarks/groth16/evaluation_from_lagrange.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "include_libsnark.hpp"
#include <map>

/// Given a sequence of powers of x (with some factor) encoded in
/// GroupT, compute the values of various linear combination of
/// Lagrange polynomials at x.
///
/// TODO: Here, we assume that there may be more Lagrange polynomails
/// than variables in the original qap, so we use a map to avoid
/// evaluating those that are unused. This may not be the optimal approach.
template <typename ppT, typename GroupT>
class evaluation_from_lagrange
{
public:
evaluation_from_lagrange(
const std::vector<GroupT> &powers,
libfqfft::evaluation_domain<libff::Fr<ppT>> &domain);

GroupT evaluate_from_langrange_factors(
const std::map<size_t, libff::Fr<ppT>> lagrange_factors);

private:

const std::vector<GroupT> &powers;
libfqfft::evaluation_domain<libff::Fr<ppT>> &domain;
};


#include "evaluation_from_lagrange.tcc"
41 changes: 41 additions & 0 deletions src/snarks/groth16/evaluation_from_lagrange.tcc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include "evaluation_from_lagrange.hpp"
#include "multi_exp.hpp"


template<typename ppT, typename GroupT>
evaluation_from_lagrange<ppT, GroupT>::evaluation_from_lagrange(
const std::vector<GroupT> &powers,
libfqfft::evaluation_domain<libff::Fr<ppT>> &domain)
: powers(powers)
, domain(domain)
{
assert(powers.size() >= domain.m - 1);
}

template<typename ppT, typename GroupT>
GroupT evaluation_from_lagrange<ppT, GroupT>::evaluate_from_langrange_factors(
const std::map<size_t, libff::Fr<ppT>> lagrange_factors)
{
// libfqfft::evaluation_domain modifies an incoming vector of
// factors. Write the factors into the vector (it must be
// large enough to hold domain.m entries), and then run iFFT
// to transform to coefficients.

std::vector<libff::Fr<ppT>> coefficients(domain.m, libff::Fr<ppT>::zero());
for (auto it : lagrange_factors)
{
const size_t lagrange_idx = it.first;
const libff::Fr<ppT> &lagrange_factor = it.second;

assert(lagrange_idx < domain.m);
if (!lagrange_factor.is_zero())
{
coefficients[lagrange_idx] = lagrange_factor;
}
}

domain.iFFT(coefficients);
return multi_exp<ppT, GroupT>(powers, coefficients);
}
55 changes: 55 additions & 0 deletions src/snarks/groth16/multi_exp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

#include "include_libsnark.hpp"

///
template<typename ppT, typename GroupT> extern
GroupT multi_exp(
typename std::vector<libff::G1<ppT>>::const_iterator gs_start,
typename std::vector<libff::G1<ppT>>::const_iterator gs_end,
typename std::vector<libff::Fr<ppT>>::const_iterator fs_start,
typename std::vector<libff::Fr<ppT>>::const_iterator fs_end)
{
using Fr = libff::Fr<ppT>;
const libff::multi_exp_method Method = libff::multi_exp_method_BDLO12;
return
libff::multi_exp_with_mixed_addition<GroupT, Fr, Method>(
gs_start,
gs_end,
fs_start,
fs_end,
1);
}


///
template<typename ppT, typename GroupT> extern
GroupT multi_exp(
const std::vector<GroupT> &gs,
const libff::Fr_vector<ppT> &fs)
{
assert(gs.size() >= fs.size());
assert(gs.size() > 0);

#if 0

libff::G1<ppT> accum = fs[0] * gs[0];
for (size_t i = 1 ; i < gs.size() ; ++i)
{
accum = accum + fs[i] * gs[i];
}
return accum;

#else

using Fr = libff::Fr<ppT>;
const libff::multi_exp_method Method = libff::multi_exp_method_BDLO12;
return libff::multi_exp_with_mixed_addition<GroupT, Fr, Method>(
gs.begin(),
gs.begin() + fs.size(),
fs.begin(),
fs.end(),
1);

#endif
}

0 comments on commit 6cef625

Please sign in to comment.