7#include <botan/internal/monty.h> 
    9#include <botan/numthry.h> 
   10#include <botan/internal/barrett.h> 
   11#include <botan/internal/mp_core.h> 
   20constexpr size_t MontgomeryUseStackLimit = 32;
 
   25   if(p.is_even() || p < 3) {
 
   26      throw Invalid_Argument(
"Montgomery_Params invalid modulus");
 
   30   m_p_words = m_p.sig_words();
 
   35   m_r1 = mod_p.reduce(r);
 
   36   m_r2 = mod_p.square(m_r1);
 
   37   m_r3 = mod_p.multiply(m_r1, m_r2);
 
   46      m_data(std::make_shared<Data>(
p, mod_p)) {}
 
 
   52   if(this->m_data == other.m_data) {
 
   56   return (this->m_data->p() == other.m_data->p());
 
 
   60   const size_t p_size = this->
p_words();
 
   62   if(ws.size() < p_size) {
 
 
   75   const size_t p_size = this->
p_words();
 
   77   this->
mul(z, x, y, ws);
 
 
   82   const size_t p_size = this->
p_words();
 
   84   if(ws.size() < 2 * p_size) {
 
   85      ws.resize(2 * p_size);
 
   91   if(z.
size() < 2 * p_size) {
 
   99              std::min(p_size, x.
size()),
 
  102              std::min(p_size, y.
size()),
 
 
  110   const size_t p_size = this->
p_words();
 
  112   if(ws.size() < 2 * p_size) {
 
  113      ws.resize(2 * p_size);
 
  115   if(z.
size() < 2 * p_size) {
 
  125              std::min(p_size, x.
size()),
 
  128              std::min(p_size, y.size()),
 
 
  136   const size_t p_size = this->
p_words();
 
  138   if(ws.size() < 4 * p_size) {
 
  139      ws.resize(4 * p_size);
 
  142   word* z_data = ws.data();
 
  143   word* ws_data = &ws[2 * p_size];
 
  151              std::min(p_size, x.
size()),
 
  154              std::min(p_size, y.
size()),
 
  160   if(x.
size() < 2 * p_size) {
 
 
  172   const size_t p_size = this->
p_words();
 
  183   const size_t p_size = this->
p_words();
 
  185   if(ws.size() < 2 * p_size) {
 
  186      ws.resize(2 * p_size);
 
  189   if(z.
size() < 2 * p_size) {
 
 
  199      m_params(params), m_v(std::move(words)) {
 
  209   auto redc_x = params.
mul(params.
redc(x, ws), params.
R3(), ws);
 
 
  214      m_params(params), m_v(m_params.p_words()) {
 
  217   const size_t p_size = m_params.p_words();
 
  221   if(v_span.size() > p_size) {
 
  223      v_span = v_span.first(p_size);
 
  228   copy_mem(std::span{m_v}.first(v_span.size()), v_span);
 
  232      this->
mul_by(m_params.R2()._as_span().first(p_size), ws);
 
 
  237      m_params(params), m_v(words.begin(), words.end()) {
 
  238   BOTAN_ARG_CHECK(m_v.size() == m_params.p_words(), 
"Invalid input span");
 
 
  249   z.resize(2 * m_params.p_words());  
 
  252      z.data(), m_params.p()._data(), m_params.p_words(), m_params.p_dash(), ws.data(), ws.size());
 
 
  260   const size_t p_size = m_params.p_words();
 
  265   word* r = std::span{z}.first(p_size).data();
 
  266   word* t = std::span{z}.last(p_size).data();
 
 
  281   const size_t p_size = m_params.p_words();
 
  285   const word borrow = 
bigint_sub3(t.data(), m_v.data(), p_size, other.m_v.data(), p_size);
 
 
  295   const size_t p_size = m_params.p_words();
 
  298   if(ws.size() < 2 * p_size) {
 
  299      ws.resize(2 * p_size);
 
  304   bigint_mul(z.data(), z.size(), m_v.data(), p_size, p_size, other.m_v.data(), p_size, p_size, ws.data(), ws.size());
 
 
  314   return this->
mul_by(std::span{other.m_v}, ws);
 
 
  318   const size_t p_size = m_params.p_words();
 
  321   if(ws.size() < 2 * p_size) {
 
  322      ws.resize(2 * p_size);
 
  325   auto do_mul_by = [&](std::span<word> z) {
 
  326      bigint_mul(z.data(), z.size(), m_v.data(), p_size, p_size, other.data(), p_size, p_size, ws.data(), ws.size());
 
  333   if(p_size <= MontgomeryUseStackLimit) {
 
  334      std::array<word, 2 * MontgomeryUseStackLimit> z{};
 
 
  345   const size_t p_size = m_params.p_words();
 
  348   if(ws.size() < 2 * p_size) {
 
  349      ws.resize(2 * p_size);
 
  352   auto do_sqr_n = [&](std::span<word> z) {
 
  353      for(
size_t i = 0; i != n; ++i) {
 
  354         bigint_sqr(z.data(), 2 * p_size, m_v.data(), p_size, p_size, ws.data(), ws.size());
 
  358         copy_mem(m_v, std::span{z}.first(p_size));
 
  362   if(p_size <= MontgomeryUseStackLimit) {
 
  363      std::array<word, 2 * MontgomeryUseStackLimit> z{};
 
 
#define BOTAN_ASSERT_NOMSG(expr)
 
#define BOTAN_DEBUG_ASSERT(expr)
 
#define BOTAN_STATE_CHECK(expr)
 
#define BOTAN_ARG_CHECK(expr, msg)
 
void grow_to(size_t n) const
 
static BigInt _from_words(secure_vector< word > &words)
 
static BigInt power_of_2(size_t n)
 
const word * _data() const
 
T serialize(size_t len) const
 
static BigInt with_capacity(size_t n)
 
std::span< const word > _as_span() const
 
static Montgomery_Int from_wide_int(const Montgomery_Params ¶ms, const BigInt &x)
 
Montgomery_Int square(secure_vector< word > &ws) const
 
static Montgomery_Int one(const Montgomery_Params ¶ms)
 
Montgomery_Int operator-(const Montgomery_Int &other) const
 
Montgomery_Int(const Montgomery_Params ¶ms)
 
Montgomery_Int operator+(const Montgomery_Int &other) const
 
Montgomery_Int & square_this_n_times(secure_vector< word > &ws, size_t n)
 
Montgomery_Int mul(const Montgomery_Int &other, secure_vector< word > &ws) const
 
Montgomery_Int & mul_by(const Montgomery_Int &other, secure_vector< word > &ws)
 
std::vector< uint8_t > serialize() const
 
BigInt redc(const BigInt &x, secure_vector< word > &ws) const
 
BigInt sqr(const BigInt &x, secure_vector< word > &ws) const
 
void mul(BigInt &z, const BigInt &x, const BigInt &y, secure_vector< word > &ws) const
 
bool operator==(const Montgomery_Params &other) const
 
void mul_by(BigInt &x, const BigInt &y, secure_vector< word > &ws) const
 
Montgomery_Params(const BigInt &p, const Barrett_Reduction &mod_p)
 
const BigInt & R3() const
 
const BigInt & R1() const
 
constexpr auto bigint_add3(W z[], const 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)
 
void bigint_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, word workspace[], size_t ws_size)
 
constexpr auto bigint_sub3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W
 
constexpr auto monty_inverse(W a) -> W
 
void bigint_mul(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, const word y[], size_t y_size, size_t y_sw, word workspace[], size_t ws_size)
 
void bigint_monty_redc_inplace(word z[], const word p[], size_t p_size, word p_dash, word ws[], size_t ws_size)
 
constexpr W bigint_cnd_add(W cnd, W x[], const W y[], size_t size)
 
constexpr void bigint_monty_maybe_sub(size_t N, W z[], W x0, const W x[], const W p[])
 
void carry(int64_t &h0, int64_t &h1)
 
std::vector< T, secure_allocator< T > > secure_vector
 
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word