Files
dragonx/src/snark/libsnark/algebra/evaluation_domain/evaluation_domain.tcc
2018-04-21 17:42:23 +02:00

119 lines
3.5 KiB
C++

/** @file
*****************************************************************************
Imeplementation of interfaces for evaluation domains.
See evaluation_domain.hpp .
We currently implement, and select among, three types of domains:
- "basic radix-2": the domain has size m = 2^k and consists of the m-th roots of unity
- "extended radix-2": the domain has size m = 2^{k+1} and consists of "the m-th roots of unity" union "a coset"
- "step radix-2": the domain has size m = 2^k + 2^r and consists of "the 2^k-th roots of unity" union "a coset of 2^r-th roots of unity"
*****************************************************************************
* @author This file is part of libsnark, developed by SCIPR Lab
* and contributors (see AUTHORS).
* @copyright MIT license (see LICENSE file)
*****************************************************************************/
#ifndef EVALUATION_DOMAIN_TCC_
#define EVALUATION_DOMAIN_TCC_
#include <cassert>
#include "algebra/fields/field_utils.hpp"
#include "algebra/evaluation_domain/domains/basic_radix2_domain.hpp"
#include "common/assert_except.hpp"
namespace libsnark {
template<typename FieldT>
std::shared_ptr<evaluation_domain<FieldT> > get_evaluation_domain(const size_t min_size)
{
assert_except(min_size > 1);
const size_t log_min_size = log2(min_size);
assert_except(log_min_size <= (FieldT::s+1));
std::shared_ptr<evaluation_domain<FieldT> > result;
if (min_size == (1u << log_min_size))
{
if (log_min_size == FieldT::s+1)
{
if (!inhibit_profiling_info)
{
print_indent(); printf("* Selected domain: extended_radix2\n");
}
assert_except(0);
}
else
{
if (!inhibit_profiling_info)
{
print_indent(); printf("* Selected domain: basic_radix2\n");
}
result.reset(new basic_radix2_domain<FieldT>(min_size));
}
}
else
{
const size_t big = UINT64_C(1)<<(log2(min_size)-1);
const size_t small = min_size - big;
const size_t rounded_small = (UINT64_C(1)<<log2(small));
if (big == rounded_small)
{
if (log2(big + rounded_small) < FieldT::s+1)
{
if (!inhibit_profiling_info)
{
print_indent(); printf("* Selected domain: basic_radix2\n");
}
result.reset(new basic_radix2_domain<FieldT>(big + rounded_small));
}
else
{
if (!inhibit_profiling_info)
{
print_indent(); printf("* Selected domain: extended_radix2\n");
}
assert_except(0);
}
}
else
{
if (!inhibit_profiling_info)
{
print_indent(); printf("* Selected domain: step_radix2\n");
}
assert_except(0);
}
}
return result;
}
template<typename FieldT>
FieldT lagrange_eval(const size_t m, const std::vector<FieldT> &domain, const FieldT &t, const size_t idx)
{
assert_except(m == domain.size());
assert_except(idx < m);
FieldT num = FieldT::one();
FieldT denom = FieldT::one();
for (size_t k = 0; k < m; ++k)
{
if (k == idx)
{
continue;
}
num *= t - domain[k];
denom *= domain[idx] - domain[k];
}
return num * denom.inverse();
}
} // libsnark
#endif // EVALUATION_DOMAIN_TCC_