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