1 // Copyright (c) Microsoft Corporation. All rights reserved. 2 // Licensed under the MIT license. 3 4 #pragma once 5 6 #include "seal/util/common.h" 7 #include "seal/util/pointer.h" 8 #include "seal/util/uintcore.h" 9 #include <algorithm> 10 #include <cstdint> 11 #include <cstring> 12 #include <limits> 13 #include <sstream> 14 #include <stdexcept> 15 16 namespace seal 17 { 18 namespace util 19 { poly_to_hex_string(const std::uint64_t * value,std::size_t coeff_count,std::size_t coeff_uint64_count)20 SEAL_NODISCARD inline std::string poly_to_hex_string( 21 const std::uint64_t *value, std::size_t coeff_count, std::size_t coeff_uint64_count) 22 { 23 #ifdef SEAL_DEBUG 24 if (!value) 25 { 26 throw std::invalid_argument("value"); 27 } 28 #endif 29 // First check if there is anything to print 30 if (!coeff_count || !coeff_uint64_count) 31 { 32 return "0"; 33 } 34 35 std::ostringstream result; 36 bool empty = true; 37 value += util::mul_safe(coeff_count - 1, coeff_uint64_count); 38 while (coeff_count--) 39 { 40 if (is_zero_uint(value, coeff_uint64_count)) 41 { 42 value -= coeff_uint64_count; 43 continue; 44 } 45 if (!empty) 46 { 47 result << " + "; 48 } 49 result << uint_to_hex_string(value, coeff_uint64_count); 50 if (coeff_count) 51 { 52 result << "x^" << coeff_count; 53 } 54 empty = false; 55 value -= coeff_uint64_count; 56 } 57 if (empty) 58 { 59 result << "0"; 60 } 61 return result.str(); 62 } 63 poly_to_dec_string(const std::uint64_t * value,std::size_t coeff_count,std::size_t coeff_uint64_count,MemoryPool & pool)64 SEAL_NODISCARD inline std::string poly_to_dec_string( 65 const std::uint64_t *value, std::size_t coeff_count, std::size_t coeff_uint64_count, MemoryPool &pool) 66 { 67 #ifdef SEAL_DEBUG 68 if (!value) 69 { 70 throw std::invalid_argument("value"); 71 } 72 #endif 73 // First check if there is anything to print 74 if (!coeff_count || !coeff_uint64_count) 75 { 76 return "0"; 77 } 78 79 std::ostringstream result; 80 bool empty = true; 81 value += coeff_count - 1; 82 while (coeff_count--) 83 { 84 if (is_zero_uint(value, coeff_uint64_count)) 85 { 86 value -= coeff_uint64_count; 87 continue; 88 } 89 if (!empty) 90 { 91 result << " + "; 92 } 93 result << uint_to_dec_string(value, coeff_uint64_count, pool); 94 if (coeff_count) 95 { 96 result << "x^" << coeff_count; 97 } 98 empty = false; 99 value -= coeff_uint64_count; 100 } 101 if (empty) 102 { 103 result << "0"; 104 } 105 return result.str(); 106 } 107 allocate_poly(std::size_t coeff_count,std::size_t coeff_uint64_count,MemoryPool & pool)108 SEAL_NODISCARD inline auto allocate_poly( 109 std::size_t coeff_count, std::size_t coeff_uint64_count, MemoryPool &pool) 110 { 111 return allocate_uint(util::mul_safe(coeff_count, coeff_uint64_count), pool); 112 } 113 set_zero_poly(std::size_t coeff_count,std::size_t coeff_uint64_count,std::uint64_t * result)114 inline void set_zero_poly(std::size_t coeff_count, std::size_t coeff_uint64_count, std::uint64_t *result) 115 { 116 #ifdef SEAL_DEBUG 117 if (!result && coeff_count && coeff_uint64_count) 118 { 119 throw std::invalid_argument("result"); 120 } 121 #endif 122 set_zero_uint(util::mul_safe(coeff_count, coeff_uint64_count), result); 123 } 124 allocate_zero_poly(std::size_t coeff_count,std::size_t coeff_uint64_count,MemoryPool & pool)125 SEAL_NODISCARD inline auto allocate_zero_poly( 126 std::size_t coeff_count, std::size_t coeff_uint64_count, MemoryPool &pool) 127 { 128 return allocate_zero_uint(util::mul_safe(coeff_count, coeff_uint64_count), pool); 129 } 130 allocate_poly_array(std::size_t poly_count,std::size_t coeff_count,std::size_t coeff_uint64_count,MemoryPool & pool)131 SEAL_NODISCARD inline auto allocate_poly_array( 132 std::size_t poly_count, std::size_t coeff_count, std::size_t coeff_uint64_count, MemoryPool &pool) 133 { 134 return allocate_uint(util::mul_safe(poly_count, coeff_count, coeff_uint64_count), pool); 135 } 136 set_zero_poly_array(std::size_t poly_count,std::size_t coeff_count,std::size_t coeff_uint64_count,std::uint64_t * result)137 inline void set_zero_poly_array( 138 std::size_t poly_count, std::size_t coeff_count, std::size_t coeff_uint64_count, std::uint64_t *result) 139 { 140 #ifdef SEAL_DEBUG 141 if (!result && poly_count && coeff_count && coeff_uint64_count) 142 { 143 throw std::invalid_argument("result"); 144 } 145 #endif 146 set_zero_uint(util::mul_safe(poly_count, coeff_count, coeff_uint64_count), result); 147 } 148 allocate_zero_poly_array(std::size_t poly_count,std::size_t coeff_count,std::size_t coeff_uint64_count,MemoryPool & pool)149 SEAL_NODISCARD inline auto allocate_zero_poly_array( 150 std::size_t poly_count, std::size_t coeff_count, std::size_t coeff_uint64_count, MemoryPool &pool) 151 { 152 return allocate_zero_uint(util::mul_safe(poly_count, coeff_count, coeff_uint64_count), pool); 153 } 154 set_poly(const std::uint64_t * poly,std::size_t coeff_count,std::size_t coeff_uint64_count,std::uint64_t * result)155 inline void set_poly( 156 const std::uint64_t *poly, std::size_t coeff_count, std::size_t coeff_uint64_count, std::uint64_t *result) 157 { 158 #ifdef SEAL_DEBUG 159 if (!poly && coeff_count && coeff_uint64_count) 160 { 161 throw std::invalid_argument("poly"); 162 } 163 if (!result && coeff_count && coeff_uint64_count) 164 { 165 throw std::invalid_argument("result"); 166 } 167 #endif 168 set_uint(poly, util::mul_safe(coeff_count, coeff_uint64_count), result); 169 } 170 set_poly_array(const std::uint64_t * poly,std::size_t poly_count,std::size_t coeff_count,std::size_t coeff_uint64_count,std::uint64_t * result)171 inline void set_poly_array( 172 const std::uint64_t *poly, std::size_t poly_count, std::size_t coeff_count, std::size_t coeff_uint64_count, 173 std::uint64_t *result) 174 { 175 #ifdef SEAL_DEBUG 176 if (!poly && poly_count && coeff_count && coeff_uint64_count) 177 { 178 throw std::invalid_argument("poly"); 179 } 180 if (!result && poly_count && coeff_count && coeff_uint64_count) 181 { 182 throw std::invalid_argument("result"); 183 } 184 #endif 185 set_uint(poly, util::mul_safe(poly_count, coeff_count, coeff_uint64_count), result); 186 } 187 } // namespace util 188 } // namespace seal 189