Botan 3.13.0
Crypto and TLS for C&
Botan::Montgomery_Int Class Referencefinal

#include <monty.h>

Public Member Functions

void _const_time_poison () const
void _const_time_unpoison () const
const Montgomery_Params_params () const
 Montgomery_Int (const Montgomery_Params &params)
 Montgomery_Int (const Montgomery_Params &params, const BigInt &v, bool redc_needed=true)
 Montgomery_Int (const Montgomery_Params &params, std::span< const word > words)
Montgomery_Int mul (const Montgomery_Int &other, secure_vector< word > &ws) const
Montgomery_Intmul_by (const Montgomery_Int &other, secure_vector< word > &ws)
Montgomery_Intmul_by (std::span< const word > other, secure_vector< word > &ws)
Montgomery_Int operator+ (const Montgomery_Int &other) const
Montgomery_Int operator- (const Montgomery_Int &other) const
const secure_vector< word > & repr () const
std::vector< uint8_t > serialize () const
Montgomery_Int square (secure_vector< word > &ws) const
Montgomery_Intsquare_this_n_times (secure_vector< word > &ws, size_t n)
BigInt value () const

Static Public Member Functions

static Montgomery_Int from_wide_int (const Montgomery_Params &params, const BigInt &x)
static Montgomery_Int one (const Montgomery_Params &params)

Detailed Description

The Montgomery representation of an integer

Definition at line 103 of file monty.h.

Constructor & Destructor Documentation

◆ Montgomery_Int() [1/3]

Botan::Montgomery_Int::Montgomery_Int ( const Montgomery_Params & params)
explicit

Create a zero-initialized Montgomery_Int

Definition at line 224 of file monty.cpp.

224: m_params(params), m_v(m_params.p_words()) {}

Referenced by from_wide_int(), mul(), mul_by(), mul_by(), one(), operator+(), operator-(), square(), and square_this_n_times().

◆ Montgomery_Int() [2/3]

Botan::Montgomery_Int::Montgomery_Int ( const Montgomery_Params & params,
const BigInt & v,
bool redc_needed = true )

Create a Montgomery_Int from a BigInt

Definition at line 241 of file monty.cpp.

241 :
242 m_params(params), m_v(m_params.p_words()) {
243 BOTAN_ARG_CHECK(v.signum() >= 0 && v < m_params.p(), "Input out of range");
244
245 const size_t p_size = m_params.p_words();
246
247 auto v_span = v._as_span();
248
249 if(v_span.size() > p_size) {
250 // Safe to truncate the span since we already checked v < p
251 v_span = v_span.first(p_size);
252 }
253
254 BOTAN_ASSERT_NOMSG(m_v.size() >= v_span.size());
255
256 copy_mem(std::span{m_v}.first(v_span.size()), v_span);
257
258 if(redc_needed) {
260 this->mul_by(m_params.R2()._as_span().first(p_size), ws);
261 }
262}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33
Montgomery_Int & mul_by(const Montgomery_Int &other, secure_vector< word > &ws)
Definition monty.cpp:340
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128

References Botan::BigInt::_as_span(), BOTAN_ARG_CHECK, BOTAN_ASSERT_NOMSG, Botan::copy_mem(), mul_by(), and Botan::BigInt::signum().

◆ Montgomery_Int() [3/3]

Botan::Montgomery_Int::Montgomery_Int ( const Montgomery_Params & params,
std::span< const word > words )

Create a Montgomery_Int

The span must be exactly p_words long and encoding a value less than p already in Montgomery form

Definition at line 264 of file monty.cpp.

264 :
265 m_params(params), m_v(words.begin(), words.end()) {
266 BOTAN_ARG_CHECK(m_v.size() == m_params.p_words(), "Invalid input span");
267}

References BOTAN_ARG_CHECK.

Member Function Documentation

◆ _const_time_poison()

void Botan::Montgomery_Int::_const_time_poison ( ) const
inline

Definition at line 159 of file monty.h.

159{ CT::poison(m_v); }
constexpr void poison(const T *p, size_t n)
Definition ct_utils.h:56

References Botan::CT::poison().

◆ _const_time_unpoison()

void Botan::Montgomery_Int::_const_time_unpoison ( ) const
inline

Definition at line 161 of file monty.h.

161{ CT::unpoison(m_v); }
constexpr void unpoison(const T *p, size_t n)
Definition ct_utils.h:67

References Botan::CT::unpoison().

◆ _params()

const Montgomery_Params & Botan::Montgomery_Int::_params ( ) const
inline

Definition at line 163 of file monty.h.

163{ return m_params; }

◆ from_wide_int()

Montgomery_Int Botan::Montgomery_Int::from_wide_int ( const Montgomery_Params & params,
const BigInt & x )
static

Wide reduction - input can be at most 2*bytes long

Definition at line 235 of file monty.cpp.

235 {
237 auto redc_x = params.mul(params.redc(x, ws), params.R3(), ws);
238 return Montgomery_Int(params, redc_x, false);
239}
Montgomery_Int(const Montgomery_Params &params)
Definition monty.cpp:224

References Montgomery_Int(), Botan::Montgomery_Params::mul(), Botan::Montgomery_Params::R3(), and Botan::Montgomery_Params::redc().

◆ mul()

Montgomery_Int Botan::Montgomery_Int::mul ( const Montgomery_Int & other,
secure_vector< word > & ws ) const

Definition at line 320 of file monty.cpp.

320 {
321 BOTAN_STATE_CHECK(other.m_params == m_params);
322
323 const size_t p_size = m_params.p_words();
324 BOTAN_ASSERT_NOMSG(m_v.size() == p_size && other.m_v.size() == p_size);
325
326 if(ws.size() < 2 * p_size) {
327 ws.resize(2 * p_size);
328 }
329
330 secure_vector<word> z(2 * p_size);
331
332 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());
333
334 bigint_monty_redc_inplace(z.data(), m_params.p()._data(), p_size, m_params.p_dash(), ws.data(), ws.size());
335 z.resize(p_size); // truncate off high zero words
336
337 return Montgomery_Int(m_params, std::move(z));
338}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
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)
Definition mp_karat.cpp:283
void bigint_monty_redc_inplace(word z[], const word p[], size_t p_size, word p_dash, word ws[], size_t ws_size)
Definition mp_core.h:948

References Botan::bigint_monty_redc_inplace(), Botan::bigint_mul(), BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, and Montgomery_Int().

Referenced by Botan::monty_multi_exp().

◆ mul_by() [1/2]

Montgomery_Int & Botan::Montgomery_Int::mul_by ( const Montgomery_Int & other,
secure_vector< word > & ws )

Definition at line 340 of file monty.cpp.

340 {
341 BOTAN_STATE_CHECK(other.m_params == m_params);
342 return this->mul_by(std::span{other.m_v}, ws);
343}

References BOTAN_STATE_CHECK, Montgomery_Int(), and mul_by().

Referenced by Montgomery_Int(), Botan::monty_multi_exp(), and mul_by().

◆ mul_by() [2/2]

Montgomery_Int & Botan::Montgomery_Int::mul_by ( std::span< const word > other,
secure_vector< word > & ws )

Definition at line 345 of file monty.cpp.

345 {
346 const size_t p_size = m_params.p_words();
347 BOTAN_ASSERT_NOMSG(m_v.size() == p_size && other.size() == p_size);
348
349 if(ws.size() < 2 * p_size) {
350 ws.resize(2 * p_size);
351 }
352
353 auto do_mul_by = [&](std::span<word> z) {
354 bigint_mul(z.data(), z.size(), m_v.data(), p_size, p_size, other.data(), p_size, p_size, ws.data(), ws.size());
355
356 bigint_monty_redc_inplace(z.data(), m_params.p()._data(), p_size, m_params.p_dash(), ws.data(), ws.size());
357
358 copy_mem(m_v, z.first(p_size));
359 };
360
361 if(p_size <= MontgomeryUseStackLimit) {
362 std::array<word, 2 * MontgomeryUseStackLimit> z{};
363 do_mul_by(z);
364 } else {
365 secure_vector<word> z(2 * p_size);
366 do_mul_by(z);
367 }
368
369 return (*this);
370}

References Botan::bigint_monty_redc_inplace(), Botan::bigint_mul(), BOTAN_ASSERT_NOMSG, Botan::copy_mem(), and Montgomery_Int().

◆ one()

Montgomery_Int Botan::Montgomery_Int::one ( const Montgomery_Params & params)
static

Return the value 1 in Montgomery form

Definition at line 231 of file monty.cpp.

231 {
232 return Montgomery_Int(params, params.R1(), false);
233}

References Montgomery_Int(), and Botan::Montgomery_Params::R1().

Referenced by Botan::monty_multi_exp().

◆ operator+()

Montgomery_Int Botan::Montgomery_Int::operator+ ( const Montgomery_Int & other) const

Definition at line 285 of file monty.cpp.

285 {
286 BOTAN_STATE_CHECK(other.m_params == m_params);
287
288 const size_t p_size = m_params.p_words();
289 BOTAN_ASSERT_NOMSG(m_v.size() == p_size && other.m_v.size() == p_size);
290
291 secure_vector<word> z(2 * p_size);
292
293 word* r = std::span{z}.first(p_size).data();
294 word* t = std::span{z}.last(p_size).data();
295
296 // t = this + other
297 const word carry = bigint_add3(t, m_v.data(), p_size, other.m_v.data(), p_size);
298
299 // Conditionally subtract r = t - p
300 bigint_monty_maybe_sub(p_size, r, carry, t, m_params.p()._data());
301
302 z.resize(p_size); // truncate leaving only r
303 return Montgomery_Int(m_params, std::move(z));
304}
constexpr auto bigint_add3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W
Definition mp_core.h:120
constexpr void bigint_monty_maybe_sub(size_t N, W z[], W x0, const W x[], const W p[])
Definition mp_core.h:225
void carry(int64_t &h0, int64_t &h1)
std::conditional_t< HasNative64BitRegisters, std::uint64_t, uint32_t > word
The native machine word, used as the limb type for multiprecision integers.
Definition types.h:131

References Botan::bigint_add3(), Botan::bigint_monty_maybe_sub(), BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, Botan::carry(), and Montgomery_Int().

◆ operator-()

Montgomery_Int Botan::Montgomery_Int::operator- ( const Montgomery_Int & other) const

Definition at line 306 of file monty.cpp.

306 {
307 BOTAN_STATE_CHECK(other.m_params == m_params);
308
309 const size_t p_size = m_params.p_words();
310 BOTAN_ASSERT_NOMSG(m_v.size() == p_size && other.m_v.size() == p_size);
311
312 secure_vector<word> t(p_size);
313 const word borrow = bigint_sub3(t.data(), m_v.data(), p_size, other.m_v.data(), p_size);
314
315 bigint_cnd_add(borrow, t.data(), m_params.p()._data(), p_size);
316
317 return Montgomery_Int(m_params, std::move(t));
318}
constexpr auto bigint_sub3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W
Definition mp_core.h:192
constexpr W bigint_cnd_add(W cnd, W x[], const W y[], size_t size)
Definition mp_core.h:45

References Botan::bigint_cnd_add(), Botan::bigint_sub3(), BOTAN_ASSERT_NOMSG, BOTAN_STATE_CHECK, and Montgomery_Int().

◆ repr()

const secure_vector< word > & Botan::Montgomery_Int::repr ( ) const
inline

Return the Montgomery representation

Definition at line 143 of file monty.h.

143{ return m_v; }

◆ serialize()

std::vector< uint8_t > Botan::Montgomery_Int::serialize ( ) const

Definition at line 269 of file monty.cpp.

269 {
270 return value().serialize();
271}
T serialize(size_t len) const
Definition bigint.h:790
BigInt value() const
Definition monty.cpp:273

References Botan::BigInt::serialize(), and value().

◆ square()

Montgomery_Int Botan::Montgomery_Int::square ( secure_vector< word > & ws) const

Definition at line 401 of file monty.cpp.

401 {
402 auto z = (*this);
403 z.square_this_n_times(ws, 1);
404 return z;
405}

References Montgomery_Int(), and square_this_n_times().

Referenced by Botan::monty_multi_exp().

◆ square_this_n_times()

Montgomery_Int & Botan::Montgomery_Int::square_this_n_times ( secure_vector< word > & ws,
size_t n )

Definition at line 372 of file monty.cpp.

372 {
373 const size_t p_size = m_params.p_words();
374 BOTAN_ASSERT_NOMSG(m_v.size() == p_size);
375
376 if(ws.size() < 2 * p_size) {
377 ws.resize(2 * p_size);
378 }
379
380 auto do_sqr_n = [&](std::span<word> z) {
381 for(size_t i = 0; i != n; ++i) {
382 bigint_sqr(z.data(), 2 * p_size, m_v.data(), p_size, p_size, ws.data(), ws.size());
383
384 bigint_monty_redc_inplace(z.data(), m_params.p()._data(), p_size, m_params.p_dash(), ws.data(), ws.size());
385
386 copy_mem(m_v, std::span{z}.first(p_size));
387 }
388 };
389
390 if(p_size <= MontgomeryUseStackLimit) {
391 std::array<word, 2 * MontgomeryUseStackLimit> z{};
392 do_sqr_n(z);
393 } else {
394 secure_vector<word> z(2 * p_size);
395 do_sqr_n(z);
396 }
397
398 return (*this);
399}
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)
Definition mp_karat.cpp:327

References Botan::bigint_monty_redc_inplace(), Botan::bigint_sqr(), BOTAN_ASSERT_NOMSG, Botan::copy_mem(), and Montgomery_Int().

Referenced by Botan::monty_multi_exp(), and square().

◆ value()

BigInt Botan::Montgomery_Int::value ( ) const

Return the value to normal mod-p space

Definition at line 273 of file monty.cpp.

273 {
274 secure_vector<word> ws(m_params.p_words());
275
276 secure_vector<word> z = m_v;
277 z.resize(2 * m_params.p_words()); // zero extend
278
280 z.data(), m_params.p()._data(), m_params.p_words(), m_params.p_dash(), ws.data(), ws.size());
281
282 return BigInt::_from_words(z);
283}
static BigInt _from_words(secure_vector< word > &words)
Definition bigint.h:1052

References Botan::BigInt::_from_words(), and Botan::bigint_monty_redc_inplace().

Referenced by Botan::DL_Group::multi_exponentiate(), Botan::passes_miller_rabin_test(), Botan::power_mod(), serialize(), and Botan::sqrt_modulo_prime().


The documentation for this class was generated from the following files: