7#include <botan/numthry.h>
8#include <botan/internal/divide.h>
9#include <botan/internal/ct_utils.h>
10#include <botan/internal/mp_core.h>
11#include <botan/internal/rounding.h>
17BigInt inverse_mod_odd_modulus(
const BigInt& n,
const BigInt& mod)
44 const size_t mod_words = mod.sig_words();
47 secure_vector<word> tmp_mem(5*mod_words);
49 word* v_w = &tmp_mem[0];
50 word* u_w = &tmp_mem[1*mod_words];
51 word* b_w = &tmp_mem[2*mod_words];
52 word* a_w = &tmp_mem[3*mod_words];
53 word* mp1o2 = &tmp_mem[4*mod_words];
57 copy_mem(a_w, n.data(), std::min(n.size(), mod_words));
58 copy_mem(b_w, mod.data(), std::min(mod.size(), mod_words));
64 copy_mem(mp1o2, mod.data(), std::min(mod.size(), mod_words));
70 const size_t execs = 2 * mod.bits();
72 for(
size_t i = 0; i != execs; ++i)
74 const word odd_a = a_w[0] & 1;
93 const word odd_u = u_w[0] & 1;
103 for(
size_t i = 0; i != mod_words; ++i)
107 for(
size_t i = 1; i != mod_words; ++i)
114 (~b_is_1).if_set_zero_out(v_w, mod_words);
121 clear_mem(&tmp_mem[mod_words], 4*mod_words);
130BigInt inverse_mod_pow2(
const BigInt& a1,
size_t k)
137 if(a1.is_even() || k == 0)
149 const size_t a_words = a.sig_words();
161 for(
size_t i = 0; i != iter; ++i)
163 const bool b0 = b.get_bit(0);
164 X.conditionally_set_bit(i, b0);
166 b.ct_cond_assign(b0, newb);
171 X.const_time_unpoison();
193 return inverse_mod_odd_modulus(n, mod);
195 return inverse_mod_odd_modulus(
ct_modulo(n, mod), mod);
204 const size_t mod_bits = mod.
bits();
207 if(mod_lz == mod_bits - 1)
210 return inverse_mod_pow2(n, mod_lz);
229 const BigInt o = mod >> 1;
231 const BigInt inv_o = inverse_mod_odd_modulus(n_redc, o);
249 const BigInt o = mod >> mod_lz;
251 const BigInt inv_o = inverse_mod_odd_modulus(n_redc, o);
252 const BigInt inv_2k = inverse_mod_pow2(n, mod_lz);
255 if(inv_o == 0 || inv_2k == 0)
260 const BigInt c = inverse_mod_pow2(o, mod_lz);
263 BigInt h = c * (inv_2k - inv_o);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_DEBUG_ASSERT(expr)
#define BOTAN_ASSERT(expr, assertion_made)
void ct_cond_add(bool predicate, const BigInt &value)
void ct_cond_assign(bool predicate, const BigInt &other)
static BigInt power_of_2(size_t n)
bool get_bit(size_t n) const
static Mask< T > is_equal(T x, T y)
static Mask< T > is_zero(T x)
#define BOTAN_MP_WORD_BITS
void poison(const T *p, size_t n)
void unpoison(const T *p, size_t n)
void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift)
word bigint_cnd_add(word cnd, word x[], word x_size, const word y[], size_t y_size)
size_t low_zero_bits(const BigInt &n)
word bigint_cnd_sub(word cnd, word x[], size_t x_size, const word y[], size_t y_size)
void bigint_cnd_swap(word cnd, word x[], word y[], size_t size)
constexpr void copy_mem(T *out, const T *in, size_t n)
void carry(int64_t &h0, int64_t &h1)
BigInt ct_modulo(const BigInt &x, const BigInt &y)
word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size)
void bigint_cnd_abs(word cnd, word x[], size_t size)
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
constexpr void clear_mem(T *ptr, size_t n)
size_t round_up(size_t n, size_t align_to)