7#include <botan/numthry.h>
9#include <botan/internal/ct_utils.h>
10#include <botan/internal/divide.h>
11#include <botan/internal/mp_core.h>
12#include <botan/internal/rounding.h>
18BigInt inverse_mod_odd_modulus(
const BigInt& n,
const BigInt& mod) {
44 const size_t mod_words = mod.sig_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) {
73 const word odd_a = a_w[0] & 1;
92 const word odd_u = u_w[0] & 1;
102 for(
size_t i = 0; i != mod_words; ++i) {
107 for(
size_t i = 1; i != mod_words; ++i) {
115 (~b_is_1).if_set_zero_out(v_w, mod_words);
122 clear_mem(&tmp_mem[mod_words], 4 * mod_words);
131BigInt inverse_mod_pow2(
const BigInt& a1,
size_t k) {
137 if(a1.is_even() || k == 0) {
151 const size_t a_words = a.sig_words();
163 for(
size_t i = 0; i != iter; ++i) {
164 const bool b0 =
b.get_bit(0);
165 X.conditionally_set_bit(i, b0);
167 b.ct_cond_assign(b0, newb);
196 return inverse_mod_odd_modulus(n, mod);
198 return inverse_mod_odd_modulus(
ct_modulo(n, mod), mod);
208 const size_t mod_bits = mod.
bits();
211 if(mod_lz == mod_bits - 1) {
213 return inverse_mod_pow2(n, mod_lz);
231 const BigInt o = mod >> 1;
233 const BigInt inv_o = inverse_mod_odd_modulus(n_redc, o);
252 const BigInt o = mod >> mod_lz;
254 const BigInt inv_o = inverse_mod_odd_modulus(n_redc, o);
255 const BigInt inv_2k = inverse_mod_pow2(n, mod_lz);
258 if(inv_o == 0 || inv_2k == 0) {
264 const BigInt c = inverse_mod_pow2(o, mod_lz);
267 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 constexpr Mask< T > set()
static constexpr Mask< T > is_equal(T x, T y)
static constexpr Mask< T > is_zero(T x)
#define BOTAN_MP_WORD_BITS
constexpr void unpoison(const T *p, size_t n)
constexpr void poison(const T *p, size_t n)
constexpr void bigint_cnd_abs(W cnd, W x[], size_t size)
constexpr void bigint_cnd_swap(W cnd, W x[], W y[], size_t size)
constexpr void bigint_shr1(W x[], size_t x_size, size_t shift)
size_t low_zero_bits(const BigInt &n)
constexpr size_t round_up(size_t n, size_t align_to)
BigInt ct_modulo(const BigInt &x, const BigInt &y)
constexpr auto bigint_cnd_sub(W cnd, W x[], size_t x_size, const W y[], size_t y_size) -> W
constexpr W bigint_cnd_add(W cnd, W x[], size_t x_size, const W y[], size_t y_size)
void carry(int64_t &h0, int64_t &h1)
std::vector< T, secure_allocator< T > > secure_vector
constexpr auto bigint_add2_nc(W x[], size_t x_size, const W y[], size_t y_size) -> W
constexpr void copy_mem(T *out, const T *in, size_t n)
BigInt inverse_mod(const BigInt &n, const BigInt &mod)
constexpr void clear_mem(T *ptr, size_t n)