/** @file ***************************************************************************** Declaration of interfaces for evaluation domains. Roughly, given a desired size m for the domain, the constructor selects a choice of domain S with size ~m that has been selected so to optimize - computations of Lagrange polynomials, and - FFT/iFFT computations. An evaluation domain also provides other other functions, e.g., accessing individual elements in S or evaluating its vanishing polynomial. The descriptions below make use of the definition of a *Lagrange polynomial*, which we recall. Given a field F, a subset S=(a_i)_i of F, and an index idx in {0,...,|S-1|}, the idx-th Lagrange polynomial (wrt to subset S) is defined to be \f[ L_{idx,S}(z) := prod_{k \neq idx} (z - a_k) / prod_{k \neq idx} (a_{idx} - a_k) \f] Note that, by construction: \f[ \forall j \neq idx: L_{idx,S}(a_{idx}) = 1 \text{ and } L_{idx,S}(a_j) = 0 \f] ***************************************************************************** * @author This file is part of libsnark, developed by SCIPR Lab * and contributors (see AUTHORS). * @copyright MIT license (see LICENSE file) *****************************************************************************/ #ifndef EVALUATION_DOMAIN_HPP_ #define EVALUATION_DOMAIN_HPP_ #include namespace libsnark { /** * An evaluation domain. */ template class evaluation_domain { public: const size_t m; /** * Construct an evaluation domain S of size m, if possible. * * (See the function get_evaluation_domain below.) */ evaluation_domain(const size_t m) : m(m) {}; /** * Get the idx-th element in S. */ virtual FieldT get_element(const size_t idx) = 0; /** * Compute the FFT, over the domain S, of the vector a. */ virtual void FFT(std::vector &a) = 0; /** * Compute the inverse FFT, over the domain S, of the vector a. */ virtual void iFFT(std::vector &a) = 0; /** * Compute the FFT, over the domain g*S, of the vector a. */ virtual void cosetFFT(std::vector &a, const FieldT &g) = 0; /** * Compute the inverse FFT, over the domain g*S, of the vector a. */ virtual void icosetFFT(std::vector &a, const FieldT &g) = 0; /** * Evaluate all Lagrange polynomials. * * The inputs are: * - an integer m * - an element t * The output is a vector (b_{0},...,b_{m-1}) * where b_{i} is the evaluation of L_{i,S}(z) at z = t. */ virtual std::vector lagrange_coeffs(const FieldT &t) = 0; /** * Evaluate the vanishing polynomial of S at the field element t. */ virtual FieldT compute_Z(const FieldT &t) = 0; /** * Add the coefficients of the vanishing polynomial of S to the coefficients of the polynomial H. */ virtual void add_poly_Z(const FieldT &coeff, std::vector &H) = 0; /** * Multiply by the evaluation, on a coset of S, of the inverse of the vanishing polynomial of S. */ virtual void divide_by_Z_on_coset(std::vector &P) = 0; }; /** * Return an evaluation domain object in which the domain S has size |S| >= min_size. * The function chooses from different supported domains, depending on min_size. */ template std::shared_ptr > get_evaluation_domain(const size_t min_size); /** * Naive evaluation of a *single* Lagrange polynomial, used for testing purposes. * * The inputs are: * - an integer m * - a domain S = (a_{0},...,a_{m-1}) of size m * - a field element element t * - an index idx in {0,...,m-1} * The output is the polynomial L_{idx,S}(z) evaluated at z = t. */ template FieldT lagrange_eval(const size_t m, const std::vector &domain, const FieldT &t, const size_t idx); } // libsnark #include "algebra/evaluation_domain/evaluation_domain.tcc" #endif // EVALUATION_DOMAIN_HPP_