Botan 3.10.0
Crypto and TLS for C&
Botan::divide_precomp< W > Class Template Referencefinal

#include <mp_core.h>

Public Member Functions

constexpr divide_precomp (W divisor)
constexpr W vartime_div_2to1 (W n1, W n0) const
constexpr W vartime_mod_2to1 (W n1, W n0) const

Detailed Description

template<WordType W>
class Botan::divide_precomp< W >

Setup for variable-time word level division/modulo operations

Currently this just uses the compiler's support for a 2/1 word division, but likely could be improved by precomputed values based on the divisor, for example using the approaches outlined in Hacker's Delight chapter 10.

Definition at line 539 of file mp_core.h.

Constructor & Destructor Documentation

◆ divide_precomp()

template<WordType W>
Botan::divide_precomp< W >::divide_precomp ( W divisor)
inlineexplicitconstexpr

Definition at line 541 of file mp_core.h.

541 : m_divisor(divisor) {
542 BOTAN_ARG_CHECK(m_divisor != 0, "Division by zero");
543 }
#define BOTAN_ARG_CHECK(expr, msg)
Definition assert.h:33

References BOTAN_ARG_CHECK.

Member Function Documentation

◆ vartime_div_2to1()

template<WordType W>
W Botan::divide_precomp< W >::vartime_div_2to1 ( W n1,
W n0 ) const
inlineconstexpr

Definition at line 548 of file mp_core.h.

548 {
549 BOTAN_ASSERT_NOMSG(n1 < m_divisor);
550
552#if defined(BOTAN_MP_USE_X86_64_ASM)
553 if constexpr(std::same_as<W, uint64_t>) {
554 W quotient = 0;
555 W remainder = 0;
556 // NOLINTNEXTLINE(*-no-assembler)
557 asm("divq %[v]" : "=a"(quotient), "=d"(remainder) : [v] "r"(m_divisor), "a"(n0), "d"(n1));
558 return quotient;
559 }
560#endif
561
562#if !defined(BOTAN_BUILD_COMPILER_IS_CLANGCL)
563
564 /* clang-cl has a bug where on encountering a 128/64 division it emits
565 * a call to __udivti3() but then fails to link the relevant builtin into
566 * the binary, causing a link failure. Work around this by simply omitting
567 * such code for clang-cl
568 *
569 * See https://github.com/llvm/llvm-project/issues/25679
570 */
571 if constexpr(WordInfo<W>::dword_is_native) {
572 typename WordInfo<W>::dword n = n1;
574 n |= n0;
575 return static_cast<W>(n / m_divisor);
576 }
577#endif
578 }
579
580 W high = n1;
581 W quotient = 0;
582
583 for(size_t i = 0; i != WordInfo<W>::bits; ++i) {
584 const W high_top_bit = high >> (WordInfo<W>::bits - 1);
585
586 high <<= 1;
587 high |= (n0 >> (WordInfo<W>::bits - 1 - i)) & 1;
588 quotient <<= 1;
589
590 if(high_top_bit || high >= m_divisor) {
591 high -= m_divisor;
592 quotient |= 1;
593 }
594 }
595
596 return quotient;
597 }
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG.

Referenced by Botan::vartime_divide(), Botan::vartime_divide_pow2k(), and vartime_mod_2to1().

◆ vartime_mod_2to1()

template<WordType W>
W Botan::divide_precomp< W >::vartime_mod_2to1 ( W n1,
W n0 ) const
inlineconstexpr

Definition at line 602 of file mp_core.h.

602 {
603 BOTAN_ASSERT_NOMSG(n1 < m_divisor);
604 W q = this->vartime_div_2to1(n1, n0);
605 W carry = 0;
606 q = word_madd2(q, m_divisor, &carry);
607 return (n0 - q);
608 }
constexpr W vartime_div_2to1(W n1, W n0) const
Definition mp_core.h:548
constexpr auto word_madd2(W a, W b, W *c) -> W
Definition mp_asmi.h:86

References BOTAN_ASSERT_NOMSG, Botan::carry(), vartime_div_2to1(), and Botan::word_madd2().

Referenced by Botan::operator%(), and Botan::BigInt::operator%=().


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