#pragma once
#include "seal/modulus.h"
#include "seal/util/common.h"
#include "seal/util/defines.h"
#include "seal/util/iterator.h"
#include "seal/util/pointer.h"
#include "seal/util/polycore.h"
#include "seal/util/uintarithsmallmod.h"
#include <algorithm>
#include <cstdint>
#include <stdexcept>
namespace seal
{
namespace util
{
void modulo_poly_coeffs(ConstCoeffIter poly, std::size_t coeff_count, const Modulus &modulus, CoeffIter result);
inline void modulo_poly_coeffs(
ConstRNSIter poly, std::size_t coeff_modulus_size, ConstModulusIter modulus, RNSIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
modulo_poly_coeffs(get<0>(I), poly_modulus_degree, get<1>(I), get<2>(I));
});
}
inline void modulo_poly_coeffs(
ConstPolyIter poly_array, std::size_t size, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
modulo_poly_coeffs(get<0>(I), coeff_modulus_size, modulus, get<1>(I));
});
}
inline void negate_poly_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, const Modulus &modulus, CoeffIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_count > 0)
{
throw std::invalid_argument("poly");
}
if (modulus.is_zero())
{
throw std::invalid_argument("modulus");
}
if (!result && coeff_count > 0)
{
throw std::invalid_argument("result");
}
#endif
const uint64_t modulus_value = modulus.value();
SEAL_ITERATE(iter(poly, result), coeff_count, [&](auto I) {
auto coeff = get<0>(I);
#ifdef SEAL_DEBUG
if (coeff >= modulus_value)
{
throw std::out_of_range("poly");
}
#endif
std::int64_t non_zero = (coeff != 0);
get<1>(I) = (modulus_value - coeff) & static_cast<std::uint64_t>(-non_zero);
});
}
inline void negate_poly_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, ConstModulusIter modulus, RNSIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
negate_poly_coeffmod(get<0>(I), poly_modulus_degree, get<1>(I), get<2>(I));
});
}
inline void negate_poly_coeffmod(
ConstPolyIter poly_array, std::size_t size, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
negate_poly_coeffmod(get<0>(I), coeff_modulus_size, modulus, get<1>(I));
});
}
void add_poly_coeffmod(
ConstCoeffIter operand1, ConstCoeffIter operand2, std::size_t coeff_count, const Modulus &modulus,
CoeffIter result);
inline void add_poly_coeffmod(
ConstRNSIter operand1, ConstRNSIter operand2, std::size_t coeff_modulus_size, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!operand1 && coeff_modulus_size > 0)
{
throw std::invalid_argument("operand1");
}
if (!operand2 && coeff_modulus_size > 0)
{
throw std::invalid_argument("operand2");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (operand1.poly_modulus_degree() != result.poly_modulus_degree() ||
operand2.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(operand1, operand2, modulus, result), coeff_modulus_size, [&](auto I) {
add_poly_coeffmod(get<0>(I), get<1>(I), poly_modulus_degree, get<2>(I), get<3>(I));
});
}
inline void add_poly_coeffmod(
ConstPolyIter operand1, ConstPolyIter operand2, std::size_t size, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!operand1 && size > 0)
{
throw std::invalid_argument("operand1");
}
if (!operand2 && size > 0)
{
throw std::invalid_argument("operand2");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (operand1.coeff_modulus_size() != result.coeff_modulus_size() ||
operand2.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(operand1, operand2, result), size, [&](auto I) {
add_poly_coeffmod(get<0>(I), get<1>(I), coeff_modulus_size, modulus, get<2>(I));
});
}
void sub_poly_coeffmod(
ConstCoeffIter operand1, ConstCoeffIter operand2, std::size_t coeff_count, const Modulus &modulus,
CoeffIter result);
inline void sub_poly_coeffmod(
ConstRNSIter operand1, ConstRNSIter operand2, std::size_t coeff_modulus_size, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!operand1 && coeff_modulus_size > 0)
{
throw std::invalid_argument("operand1");
}
if (!operand2 && coeff_modulus_size > 0)
{
throw std::invalid_argument("operand2");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (operand1.poly_modulus_degree() != result.poly_modulus_degree() ||
operand2.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(operand1, operand2, modulus, result), coeff_modulus_size, [&](auto I) {
sub_poly_coeffmod(get<0>(I), get<1>(I), poly_modulus_degree, get<2>(I), get<3>(I));
});
}
inline void sub_poly_coeffmod(
ConstPolyIter operand1, ConstPolyIter operand2, std::size_t size, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!operand1 && size > 0)
{
throw std::invalid_argument("operand1");
}
if (!operand2 && size > 0)
{
throw std::invalid_argument("operand2");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (operand1.coeff_modulus_size() != result.coeff_modulus_size() ||
operand2.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(operand1, operand2, result), size, [&](auto I) {
sub_poly_coeffmod(get<0>(I), get<1>(I), coeff_modulus_size, modulus, get<2>(I));
});
}
void add_poly_scalar_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, std::uint64_t scalar, const Modulus &modulus,
CoeffIter result);
inline void add_poly_scalar_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, std::uint64_t scalar, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
add_poly_scalar_coeffmod(get<0>(I), poly_modulus_degree, scalar, get<1>(I), get<2>(I));
});
}
inline void add_poly_scalar_coeffmod(
ConstPolyIter poly_array, std::size_t size, std::uint64_t scalar, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
add_poly_scalar_coeffmod(get<0>(I), coeff_modulus_size, scalar, modulus, get<1>(I));
});
}
void sub_poly_scalar_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, std::uint64_t scalar, const Modulus &modulus,
CoeffIter result);
inline void sub_poly_scalar_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, std::uint64_t scalar, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
sub_poly_scalar_coeffmod(get<0>(I), poly_modulus_degree, scalar, get<1>(I), get<2>(I));
});
}
inline void sub_poly_scalar_coeffmod(
ConstPolyIter poly_array, std::size_t size, std::uint64_t scalar, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
sub_poly_scalar_coeffmod(get<0>(I), coeff_modulus_size, scalar, modulus, get<1>(I));
});
}
void multiply_poly_scalar_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, MultiplyUIntModOperand scalar, const Modulus &modulus,
CoeffIter result);
inline void multiply_poly_scalar_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, std::uint64_t scalar, const Modulus &modulus,
CoeffIter result)
{
MultiplyUIntModOperand temp_scalar;
temp_scalar.set(barrett_reduce_64(scalar, modulus), modulus);
multiply_poly_scalar_coeffmod(poly, coeff_count, temp_scalar, modulus, result);
}
inline void multiply_poly_scalar_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, std::uint64_t scalar, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
multiply_poly_scalar_coeffmod(get<0>(I), poly_modulus_degree, scalar, get<1>(I), get<2>(I));
});
}
inline void multiply_poly_scalar_coeffmod(
ConstPolyIter poly_array, std::size_t size, std::uint64_t scalar, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
multiply_poly_scalar_coeffmod(get<0>(I), coeff_modulus_size, scalar, modulus, get<1>(I));
});
}
void dyadic_product_coeffmod(
ConstCoeffIter operand1, ConstCoeffIter operand2, std::size_t coeff_count, const Modulus &modulus,
CoeffIter result);
inline void dyadic_product_coeffmod(
ConstRNSIter operand1, ConstRNSIter operand2, std::size_t coeff_modulus_size, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!operand1 && coeff_modulus_size > 0)
{
throw std::invalid_argument("operand1");
}
if (!operand2 && coeff_modulus_size > 0)
{
throw std::invalid_argument("operand2");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (operand1.poly_modulus_degree() != result.poly_modulus_degree() ||
operand2.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(operand1, operand2, modulus, result), coeff_modulus_size, [&](auto I) {
dyadic_product_coeffmod(get<0>(I), get<1>(I), poly_modulus_degree, get<2>(I), get<3>(I));
});
}
inline void dyadic_product_coeffmod(
ConstPolyIter operand1, ConstPolyIter operand2, std::size_t size, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!operand1 && size > 0)
{
throw std::invalid_argument("operand1");
}
if (!operand2 && size > 0)
{
throw std::invalid_argument("operand2");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (operand1.coeff_modulus_size() != result.coeff_modulus_size() ||
operand2.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(operand1, operand2, result), size, [&](auto I) {
dyadic_product_coeffmod(get<0>(I), get<1>(I), coeff_modulus_size, modulus, get<2>(I));
});
}
std::uint64_t poly_infty_norm_coeffmod(ConstCoeffIter operand, std::size_t coeff_count, const Modulus &modulus);
void negacyclic_shift_poly_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, std::size_t shift, const Modulus &modulus, CoeffIter result);
inline void negacyclic_shift_poly_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, std::size_t shift, ConstModulusIter modulus,
RNSIter result)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
negacyclic_shift_poly_coeffmod(get<0>(I), poly_modulus_degree, shift, get<1>(I), get<2>(I));
});
}
inline void negacyclic_shift_poly_coeffmod(
ConstPolyIter poly_array, std::size_t size, std::size_t shift, ConstModulusIter modulus, PolyIter result)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
negacyclic_shift_poly_coeffmod(get<0>(I), coeff_modulus_size, shift, modulus, get<1>(I));
});
}
inline void negacyclic_multiply_poly_mono_coeffmod(
ConstCoeffIter poly, std::size_t coeff_count, std::uint64_t mono_coeff, std::size_t mono_exponent,
const Modulus &modulus, CoeffIter result, MemoryPool &pool)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_count > 0)
{
throw std::invalid_argument("poly");
}
if (modulus.is_zero())
{
throw std::invalid_argument("modulus");
}
if (!result && coeff_count > 0)
{
throw std::invalid_argument("result");
}
#endif
SEAL_ALLOCATE_GET_COEFF_ITER(temp, coeff_count, pool);
multiply_poly_scalar_coeffmod(poly, coeff_count, mono_coeff, modulus, temp);
negacyclic_shift_poly_coeffmod(temp, coeff_count, mono_exponent, modulus, result);
}
inline void negacyclic_multiply_poly_mono_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, std::uint64_t mono_coeff, std::size_t mono_exponent,
ConstModulusIter modulus, RNSIter result, MemoryPool &pool)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, modulus, result), coeff_modulus_size, [&](auto I) {
negacyclic_multiply_poly_mono_coeffmod(
get<0>(I), poly_modulus_degree, mono_coeff, mono_exponent, get<1>(I), get<2>(I), pool);
});
}
inline void negacyclic_multiply_poly_mono_coeffmod(
ConstPolyIter poly_array, std::size_t size, std::uint64_t mono_coeff, std::size_t mono_exponent,
ConstModulusIter modulus, PolyIter result, MemoryPool &pool)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
negacyclic_multiply_poly_mono_coeffmod(
get<0>(I), coeff_modulus_size, mono_coeff, mono_exponent, modulus, get<1>(I), pool);
});
}
inline void negacyclic_multiply_poly_mono_coeffmod(
ConstRNSIter poly, std::size_t coeff_modulus_size, ConstCoeffIter mono_coeff, std::size_t mono_exponent,
ConstModulusIter modulus, RNSIter result, MemoryPool &pool)
{
#ifdef SEAL_DEBUG
if (!poly && coeff_modulus_size > 0)
{
throw std::invalid_argument("poly");
}
if (!mono_coeff && coeff_modulus_size > 0)
{
throw std::invalid_argument("mono_coeff");
}
if (!result && coeff_modulus_size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && coeff_modulus_size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly.poly_modulus_degree() != result.poly_modulus_degree())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto poly_modulus_degree = result.poly_modulus_degree();
SEAL_ITERATE(iter(poly, mono_coeff, modulus, result), coeff_modulus_size, [&](auto I) {
negacyclic_multiply_poly_mono_coeffmod(
get<0>(I), poly_modulus_degree, get<1>(I), mono_exponent, get<2>(I), get<3>(I), pool);
});
}
inline void negacyclic_multiply_poly_mono_coeffmod(
ConstPolyIter poly_array, std::size_t size, ConstCoeffIter mono_coeff, std::size_t mono_exponent,
ConstModulusIter modulus, PolyIter result, MemoryPool &pool)
{
#ifdef SEAL_DEBUG
if (!poly_array && size > 0)
{
throw std::invalid_argument("poly_array");
}
if (!mono_coeff && size > 0)
{
throw std::invalid_argument("mono_coeff");
}
if (!result && size > 0)
{
throw std::invalid_argument("result");
}
if (!modulus && size > 0)
{
throw std::invalid_argument("modulus");
}
if (poly_array.coeff_modulus_size() != result.coeff_modulus_size())
{
throw std::invalid_argument("incompatible iterators");
}
#endif
auto coeff_modulus_size = result.coeff_modulus_size();
SEAL_ITERATE(iter(poly_array, result), size, [&](auto I) {
negacyclic_multiply_poly_mono_coeffmod(
get<0>(I), coeff_modulus_size, mono_coeff, mono_exponent, modulus, get<1>(I), pool);
});
}
} }