4 #ifndef __NUMBER_THEORY_H__
5 #define __NUMBER_THEORY_H__
22 inline bool IsPowerOfTwo(uint64_t num) {
return num && !(num & (num - 1)); }
25 inline uint64_t
MSB(uint64_t modulus) {
26 return static_cast<uint64_t
>(std::log2l(modulus));
30 inline uint64_t
Log2(uint64_t x) {
37 FPGA_ASSERT(bits <= 64,
"MaximumValue requires bits <= 64");
39 return (std::numeric_limits<uint64_t>::max)();
41 return (1ULL << bits) - 1;
56 *prod_hi =
static_cast<uint64_t
>(prod >> 64);
57 *prod_lo =
static_cast<uint64_t
>(prod);
61 template <
int BitShift>
64 return static_cast<uint64_t
>(product >> BitShift);
73 return static_cast<uint64_t
>(q);
78 template <
int BitShift>
80 uint64_t y_barrett_factor,
82 FPGA_ASSERT(y_operand < modulus,
"y_operand must be less than modulus");
86 uint64_t Q = MultiplyUInt64Hi<BitShift>(x, y_barrett_factor);
87 return y_operand * x - Q * modulus;
91 template <
int BitShift>
93 FPGA_ASSERT(BitShift == 64 || BitShift == 52,
"Unsupport BitShift");
95 FPGA_ASSERT(y < modulus,
"y must be less than modulus");
102 }
else if (BitShift == 52) {
107 return MultiplyUIntModLazy<BitShift>(x, y, y_barrett, modulus);
115 inline unsigned char AddUInt64(uint64_t operand1, uint64_t operand2,
117 *result = operand1 + operand2;
118 return static_cast<unsigned char>(*result < operand1);
131 std::vector<uint64_t>
GeneratePrimes(
size_t num_primes,
size_t bit_size,
132 size_t ntt_size = 1);
136 uint64_t
BarrettReduce64(uint64_t input, uint64_t modulus, uint64_t q_barr);
138 template <
int InputModFactor>
140 const uint64_t* twice_modulus =
nullptr,
141 const uint64_t* four_times_modulus =
nullptr) {
142 FPGA_ASSERT(InputModFactor == 1 || InputModFactor == 2 ||
143 InputModFactor == 4 || InputModFactor == 8,
144 "InputModFactor should be 1, 2, 4, or 8");
145 if (InputModFactor == 1) {
148 if (InputModFactor == 2) {
154 if (InputModFactor == 4) {
156 "twice_modulus should not be nullptr");
157 if (x >= *twice_modulus) {
165 if (InputModFactor == 8) {
167 "twice_modulus should not be nullptr");
169 "four_times_modulus should not be nullptr");
171 if (x >= *four_times_modulus) {
172 x -= *four_times_modulus;
174 if (x >= *twice_modulus) {
192 return static_cast<uint64_t
>(n % modulus);
203 : m_operand(operand) {
204 FPGA_ASSERT(operand <= modulus,
"operand must be less than modulus");
205 FPGA_ASSERT(bit_shift == 64 || bit_shift == 52,
"Unsupport BitShift");
209 if (bit_shift == 64) {
212 }
else if (bit_shift == 52) {
213 op_hi = operand >> 12;
214 op_lo = operand << 52;
220 inline uint64_t
Operand()
const {
return m_operand; }
224 uint64_t m_barrett_factor;
239 uint64_t
MultiplyMod(uint64_t x, uint64_t y, uint64_t y_precon,
244 uint64_t
AddUIntMod(uint64_t x, uint64_t y, uint64_t modulus);
248 uint64_t
SubUIntMod(uint64_t x, uint64_t y, uint64_t modulus);
251 uint64_t
PowMod(uint64_t base, uint64_t exp, uint64_t modulus);
255 bool IsPrimitiveRoot(uint64_t root, uint64_t degree, uint64_t modulus);
266 uint64_t m_degree_bits, uint64_t m_w,
267 uint64_t* inv_root_of_unity_powers,
268 uint64_t* precon64_inv_root_of_unity_powers,
269 uint64_t* root_of_unity_powers,
270 uint64_t* precon64_root_of_unity_powers);
uint64_t MaximumValue(uint64_t bits)
Definition: number_theory_util.h:36
#define FPGA_ASSERT(...)
Definition: fpga_assert.h:15
uint64_t SubUIntMod(uint64_t x, uint64_t y, uint64_t modulus)
Definition: ntt.cpp:76
std::vector< uint64_t > GeneratePrimes(size_t num_primes, size_t bit_size, size_t ntt_size=1)
Definition: ntt.cpp:221
bool IsPrimitiveRoot(uint64_t root, uint64_t degree, uint64_t modulus)
Definition: ntt.cpp:99
unsigned char AddUInt64(uint64_t operand1, uint64_t operand2, uint64_t *result)
Definition: number_theory_util.h:115
bool IsPrime(uint64_t n)
Definition: ntt.cpp:173
uint64_t GeneratePrimitiveRoot(uint64_t degree, uint64_t modulus)
Definition: ntt.cpp:111
uint64_t AddUIntMod(uint64_t x, uint64_t y, uint64_t modulus)
Definition: ntt.cpp:69
__extension__ typedef unsigned __int128 uint128_t
Definition: number_theory_util.h:19
Definition: number_theory_util.h:197
uint128_t MultiplyUInt64(uint64_t x, uint64_t y)
Definition: number_theory_util.h:46
uint64_t BarrettReduce64(uint64_t input, uint64_t modulus, uint64_t q_barr)
Definition: ntt.cpp:45
MultiplyFactor(uint64_t operand, uint64_t bit_shift, uint64_t modulus)
Definition: number_theory_util.h:202
uint64_t ReverseBitsUInt(uint64_t x, uint64_t bits)
Definition: ntt.cpp:160
uint64_t DivideUInt128UInt64Lo(uint64_t x1, uint64_t x0, uint64_t y)
Definition: number_theory_util.h:68
uint64_t InverseUIntMod(uint64_t a, uint64_t modulus)
Definition: ntt.cpp:14
uint64_t ReduceMod(uint64_t x, uint64_t modulus, const uint64_t *twice_modulus=nullptr, const uint64_t *four_times_modulus=nullptr)
Definition: number_theory_util.h:139
uint64_t BarrettReduce128(uint64_t input_hi, uint64_t input_lo, uint64_t modulus)
Definition: number_theory_util.h:186
uint64_t MultiplyUInt64Hi(uint64_t x, uint64_t y)
Definition: number_theory_util.h:62
uint64_t MultiplyUIntMod(uint64_t x, uint64_t y, uint64_t modulus)
Definition: ntt.cpp:52
uint64_t MultiplyUIntModLazy(uint64_t x, uint64_t y_operand, uint64_t y_barrett_factor, uint64_t modulus)
Definition: number_theory_util.h:79
void ComputeRootOfUnityPowers(uint64_t m_q, uint64_t m_degree, uint64_t m_degree_bits, uint64_t m_w, uint64_t *inv_root_of_unity_powers, uint64_t *precon64_inv_root_of_unity_powers, uint64_t *root_of_unity_powers, uint64_t *precon64_root_of_unity_powers)
bool IsPowerOfTwo(uint64_t num)
Definition: number_theory_util.h:22
uint64_t Operand() const
Definition: number_theory_util.h:220
uint64_t MSB(uint64_t modulus)
Definition: number_theory_util.h:25
uint64_t PowMod(uint64_t base, uint64_t exp, uint64_t modulus)
Definition: ntt.cpp:84
uint64_t MinimalPrimitiveRoot(uint64_t degree, uint64_t modulus)
Definition: ntt.cpp:137
uint64_t BarrettFactor() const
Definition: number_theory_util.h:219
uint64_t MultiplyMod(uint64_t x, uint64_t y, uint64_t y_precon, uint64_t modulus)
Definition: ntt.cpp:62
uint64_t Log2(uint64_t x)
Definition: number_theory_util.h:30