// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. #include "seal/util/polyarith.h" #include "seal/util/polyarithmod.h" #include "seal/util/polycore.h" #include "seal/util/uintarith.h" #include "seal/util/uintarithmod.h" #include "seal/util/uintcore.h" using namespace std; namespace seal { namespace util { void poly_infty_norm_coeffmod( const uint64_t *poly, size_t coeff_count, size_t coeff_uint64_count, const uint64_t *modulus, uint64_t *result, MemoryPool &pool) { // Construct negative threshold (first negative modulus value) to compute // absolute values of coeffs. auto modulus_neg_threshold(allocate_uint(coeff_uint64_count, pool)); // Set to value of (modulus + 1) / 2. To prevent overflowing with the +1, just // add 1 to the result if modulus was odd. half_round_up_uint(modulus, coeff_uint64_count, modulus_neg_threshold.get()); // Mod out the poly coefficients and choose a symmetric representative from // [-modulus,modulus). Keep track of the max. set_zero_uint(coeff_uint64_count, result); auto coeff_abs_value(allocate_uint(coeff_uint64_count, pool)); for (size_t i = 0; i < coeff_count; i++, poly += coeff_uint64_count) { if (is_greater_than_or_equal_uint_uint(poly, modulus_neg_threshold.get(), coeff_uint64_count)) { sub_uint_uint(modulus, poly, coeff_uint64_count, coeff_abs_value.get()); } else { set_uint_uint(poly, coeff_uint64_count, coeff_abs_value.get()); } if (is_greater_than_uint_uint(coeff_abs_value.get(), result, coeff_uint64_count)) { set_uint_uint(coeff_abs_value.get(), coeff_uint64_count, result); } } } } // namespace util } // namespace seal