_ZN5Botan14expand_top_bitImEET_S1_:
   25|  25.6k|{
   26|  25.6k|   return static_cast<T>(0) - (a >> (sizeof(T) * 8 - 1));
   27|  25.6k|}
_ZN5Botan6chooseImEET_S1_S1_S1_:
  180|  24.8k|inline constexpr T choose(T mask, T a, T b) {
  181|       |   //return (mask & a) | (~mask & b);
  182|  24.8k|   return (b ^ (mask & (a ^ b)));
  183|  24.8k|}
_ZN5Botan10ct_is_zeroImEET_S1_:
   35|  23.7k|{
   36|  23.7k|   return expand_top_bit<T>(~x & (x - 1));
   37|  23.7k|}
_ZN5Botan8high_bitImEEmT_:
   60|      1|{
   61|      1|   size_t hb = 0;
   62|       |
   63|      7|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (63:38): [True: 6, False: 1]
  ------------------
   64|      6|      const size_t z = s * ((~ct_is_zero(n >> s)) & 1);
   65|      6|      hb += z;
   66|      6|      n >>= z;
   67|      6|   }
   68|       |
   69|      1|   hb += n;
   70|       |
   71|      1|   return hb;
   72|      1|}
_ZN5Botan10ct_is_zeroIhEET_S1_:
   35|    586|{
   36|    586|   return expand_top_bit<T>(~x & (x - 1));
   37|    586|}
_ZN5Botan14expand_top_bitIhEET_S1_:
   25|    842|{
   26|    842|   return static_cast<T>(0) - (a >> (sizeof(T) * 8 - 1));
   27|    842|}
_ZN5Botan6chooseIhEET_S1_S1_S1_:
  180|    842|inline constexpr T choose(T mask, T a, T b) {
  181|       |   //return (mask & a) | (~mask & b);
  182|    842|   return (b ^ (mask & (a ^ b)));
  183|    842|}

_ZN5Botan13reverse_bytesEm:
   48|    497|inline constexpr uint64_t reverse_bytes(uint64_t x) {
   49|    497|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_bswap64)
   50|    497|   return __builtin_bswap64(x);
   51|       |#else
   52|       |   uint32_t hi = static_cast<uint32_t>(x >> 32);
   53|       |   uint32_t lo = static_cast<uint32_t>(x);
   54|       |
   55|       |   hi = reverse_bytes(hi);
   56|       |   lo = reverse_bytes(lo);
   57|       |
   58|       |   return (static_cast<uint64_t>(lo) << 32) | hi;
   59|       |#endif
   60|    497|}

_ZN5Botan2CT4MaskImE8is_equalEmm:
  128|  1.88k|      static Mask<T> is_equal(T x, T y) { return Mask<T>::is_zero(static_cast<T>(x ^ y)); }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  133|  1.88k|      static Mask<T> is_lt(T x, T y) { return Mask<T>(expand_top_bit<T>(x ^ ((x ^ y) | ((x - y) ^ x)))); }
_ZN5Botan2CT4MaskImEC2Em:
  280|  12.7k|      Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskImE6selectEmm:
  228|  24.8k|      T select(T x, T y) const { return choose(value(), x, y); }
_ZNK5Botan2CT4MaskImE5valueEv:
  277|  30.5k|      T value() const { return m_mask; }
_ZN5Botan2CT4MaskImE7is_zeroEm:
  123|  6.76k|      static Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(x)); }
_ZN5Botan2CT8unpoisonImEEvRT_:
   64|  3.57k|inline void unpoison(T& p) {
   65|       |#if defined(BOTAN_HAS_VALGRIND)
   66|       |   VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T));
   67|       |#else
   68|  3.57k|   BOTAN_UNUSED(p);
  ------------------
  |  |  118|  3.57k|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   69|  3.57k|#endif
   70|  3.57k|}
_ZN5Botan2CT20conditional_swap_ptrIPKmEEvbRT_S5_:
  315|    584|inline void conditional_swap_ptr(bool cnd, T& x, T& y) {
  316|    584|   uintptr_t xp = reinterpret_cast<uintptr_t>(x);
  317|    584|   uintptr_t yp = reinterpret_cast<uintptr_t>(y);
  318|       |
  319|    584|   conditional_swap<uintptr_t>(cnd, xp, yp);
  320|       |
  321|    584|   x = reinterpret_cast<T>(xp);
  322|    584|   y = reinterpret_cast<T>(yp);
  323|    584|}
_ZN5Botan2CT16conditional_swapImEEvbRT_S3_:
  305|  1.16k|inline void conditional_swap(bool cnd, T& x, T& y) {
  306|  1.16k|   const auto swap = CT::Mask<T>::expand(cnd);
  307|       |
  308|  1.16k|   T t0 = swap.select(y, x);
  309|  1.16k|   T t1 = swap.select(x, y);
  310|  1.16k|   x = t0;
  311|  1.16k|   y = t1;
  312|  1.16k|}
_ZN5Botan2CT4MaskImE6expandEm:
  109|  3.43k|      static Mask<T> expand(T v) { return ~Mask<T>::is_zero(v); }
_ZNK5Botan2CT4MaskImEcoEv:
  213|  3.43k|      Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskImE13if_set_returnEm:
  218|  3.29k|      T if_set_return(T x) const { return m_mask & x; }
_ZNK5Botan2CT4MaskImE8select_nEPmPKmS5_m:
  245|    584|      void select_n(T output[], const T x[], const T y[], size_t len) const {
  246|  5.11k|         for(size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (246:28): [True: 4.53k, False: 584]
  ------------------
  247|  4.53k|            output[i] = this->select(x[i], y[i]);
  248|  4.53k|         }
  249|    584|      }
_ZNK5Botan2CT4MaskImE11select_maskES2_S2_:
  239|    691|      Mask<T> select_mask(Mask<T> x, Mask<T> y) const { return Mask<T>(select(x.value(), y.value())); }
_ZN5Botan2CT4MaskImEoRES2_:
  190|    288|      Mask<T>& operator|=(Mask<T> o) {
  191|    288|         m_mask |= o.value();
  192|    288|         return (*this);
  193|    288|      }
_ZNK5Botan2CT4MaskImE7as_boolEv:
  272|    585|      bool as_bool() const { return unpoisoned_value() != 0; }
_ZNK5Botan2CT4MaskImE16unpoisoned_valueEv:
  263|    585|      T unpoisoned_value() const {
  264|    585|         T r = value();
  265|    585|         CT::unpoison(r);
  266|    585|         return r;
  267|    585|      }
_ZN5Botan2CT8unpoisonIKmEEvRT_:
   64|      1|inline void unpoison(T& p) {
   65|       |#if defined(BOTAN_HAS_VALGRIND)
   66|       |   VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T));
   67|       |#else
   68|      1|   BOTAN_UNUSED(p);
  ------------------
  |  |  118|      1|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   69|      1|#endif
   70|      1|}
_ZN5Botan2CT4MaskIhE6expandEh:
  109|    586|      static Mask<T> expand(T v) { return ~Mask<T>::is_zero(v); }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  123|    586|      static Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(x)); }
_ZN5Botan2CT4MaskIhEC2Eh:
  280|  1.62k|      Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhEcoEv:
  213|    778|      Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskIhE5valueEv:
  277|  1.62k|      T value() const { return m_mask; }
_ZNK5Botan2CT4MaskIhE6selectEhh:
  228|    842|      T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT8unpoisonIlEEvRT_:
   64|    292|inline void unpoison(T& p) {
   65|       |#if defined(BOTAN_HAS_VALGRIND)
   66|       |   VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T));
   67|       |#else
   68|    292|   BOTAN_UNUSED(p);
  ------------------
  |  |  118|    292|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   69|    292|#endif
   70|    292|}
_ZN5Botan2CT4MaskIhE15is_within_rangeEhhh:
  150|    192|      static Mask<T> is_within_range(T v, T l, T u) {
  151|       |         //return Mask<T>::is_gte(v, l) & Mask<T>::is_lte(v, u);
  152|       |
  153|    192|         const T v_lt_l = v ^ ((v ^ l) | ((v - l) ^ v));
  154|    192|         const T v_gt_u = u ^ ((u ^ v) | ((u - v) ^ u));
  155|    192|         const T either = v_lt_l | v_gt_u;
  156|    192|         return ~Mask<T>(expand_top_bit(either));
  157|    192|      }
_ZN5Botan2CT4MaskIhE9is_any_ofEhSt16initializer_listIhE:
  159|     64|      static Mask<T> is_any_of(T v, std::initializer_list<T> accepted) {
  160|     64|         T accept = 0;
  161|       |
  162|    256|         for(auto a : accepted) {
  ------------------
  |  Branch (162:21): [True: 256, False: 64]
  ------------------
  163|    256|            const T diff = a ^ v;
  164|    256|            const T eq_zero = ~diff & (diff - 1);
  165|    256|            accept |= eq_zero;
  166|    256|         }
  167|       |
  168|     64|         return Mask<T>(expand_top_bit(accept));
  169|     64|      }

_ZN5Botan9ct_divideERKNS_6BigIntES2_:
   49|      1|inline BigInt ct_divide(const BigInt& x, const BigInt& y) {
   50|      1|   BigInt q, r;
   51|      1|   ct_divide(x, y, q, r);
   52|      1|   return q;
   53|      1|}

_ZN5Botan7load_beImEET_PKhm:
  226|    497|inline constexpr T load_be(const uint8_t in[], size_t off) {
  227|       |   // asserts that *in points to the correct amount of memory
  228|    497|   return load_be<T>(std::span<const uint8_t, sizeof(T)>(in + off * sizeof(T), sizeof(T)));
  229|    497|}
_ZN5Botan7load_beImNSt3__14spanIKhLm8EEEEET_OT0_:
   92|    497|inline constexpr T load_be(InR&& in_range) {
   93|    497|   ranges::assert_exact_byte_length<sizeof(T)>(in_range);
   94|    497|   std::span in{in_range};
   95|    497|   if constexpr(sizeof(T) == 1) {
  ------------------
  |  Branch (95:17): [Folded - Ignored]
  ------------------
   96|    497|      return static_cast<T>(in[0]);
   97|    497|   } else {
   98|       |#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
   99|       |      return typecast_copy<T>(in);
  100|       |#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
  101|    497|      return reverse_bytes(typecast_copy<T>(in));
  102|       |#else
  103|       |      return [&]<size_t... i>(std::index_sequence<i...>) {
  104|       |         return ((static_cast<T>(in[i]) << ((sizeof(T) - i - 1) * 8)) | ...);
  105|       |      }
  106|       |      (std::make_index_sequence<sizeof(T)>());
  107|       |#endif
  108|    497|   }
  109|    497|}

_ZN5Botan8word_addEmmPm:
  237|  3.06k|inline word word_add(word x, word y, word* carry) {
  238|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
  239|       |   asm(ADD_OR_SUBTRACT(ASM("adcl %[y],%[x]"))
  240|       |       : [x] "=r"(x), [carry] "=r"(*carry)
  241|       |       : "0"(x), [y] "rm"(y), "1"(*carry)
  242|       |       : "cc");
  243|       |   return x;
  244|       |
  245|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  246|       |
  247|  3.06k|   asm(ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]"))
  248|  3.06k|       : [x] "=r"(x), [carry] "=r"(*carry)
  249|  3.06k|       : "0"(x), [y] "rm"(y), "1"(*carry)
  250|  3.06k|       : "cc");
  251|  3.06k|   return x;
  252|       |
  253|       |#else
  254|       |   word z = x + y;
  255|       |   word c1 = (z < x);
  256|       |   z += *carry;
  257|       |   *carry = c1 | (z < *carry);
  258|       |   return z;
  259|       |#endif
  260|  3.06k|}
_ZN5Botan8word_subEmmPm:
  326|  13.4k|inline word word_sub(word x, word y, word* carry) {
  327|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
  328|       |   asm(ADD_OR_SUBTRACT(ASM("sbbl %[y],%[x]"))
  329|       |       : [x] "=r"(x), [carry] "=r"(*carry)
  330|       |       : "0"(x), [y] "rm"(y), "1"(*carry)
  331|       |       : "cc");
  332|       |   return x;
  333|       |
  334|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  335|  13.4k|   asm(ADD_OR_SUBTRACT(ASM("sbbq %[y],%[x]"))
  336|  13.4k|       : [x] "=r"(x), [carry] "=r"(*carry)
  337|  13.4k|       : "0"(x), [y] "rm"(y), "1"(*carry)
  338|  13.4k|       : "cc");
  339|  13.4k|   return x;
  340|       |
  341|       |#else
  342|       |   word t0 = x - y;
  343|       |   word c1 = (t0 > x);
  344|       |   word z = t0 - *carry;
  345|       |   *carry = c1 | (z > t0);
  346|       |   return z;
  347|       |#endif
  348|  13.4k|}
_ZN5Botan10word_madd2EmmPm:
   44|     38|inline word word_madd2(word a, word b, word* c) {
   45|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
   46|       |   asm(R"(
   47|       |      mull %[b]
   48|       |      addl %[c],%[a]
   49|       |      adcl $0,%[carry]
   50|       |      )"
   51|       |       : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c)
   52|       |       : "0"(a), "1"(b), [c] "g"(*c)
   53|       |       : "cc");
   54|       |
   55|       |   return a;
   56|       |
   57|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
   58|     38|   asm(R"(
   59|     38|      mulq %[b]
   60|     38|      addq %[c],%[a]
   61|     38|      adcq $0,%[carry]
   62|     38|      )"
   63|     38|       : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c)
   64|     38|       : "0"(a), "1"(b), [c] "g"(*c)
   65|     38|       : "cc");
   66|       |
   67|     38|   return a;
   68|       |
   69|       |#elif defined(BOTAN_MP_DWORD)
   70|       |   const BOTAN_MP_DWORD s = static_cast<BOTAN_MP_DWORD>(a) * b + *c;
   71|       |   *c = static_cast<word>(s >> BOTAN_MP_WORD_BITS);
   72|       |   return static_cast<word>(s);
   73|       |#else
   74|       |   static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size");
   75|       |
   76|       |   word hi = 0, lo = 0;
   77|       |
   78|       |   mul64x64_128(a, b, &lo, &hi);
   79|       |
   80|       |   lo += *c;
   81|       |   hi += (lo < *c);  // carry?
   82|       |
   83|       |   *c = hi;
   84|       |   return lo;
   85|       |#endif
   86|     38|}
_ZN5Botan10word_madd3EmmmPm:
   91|  1.60k|inline word word_madd3(word a, word b, word c, word* d) {
   92|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
   93|       |   asm(R"(
   94|       |      mull %[b]
   95|       |
   96|       |      addl %[c],%[a]
   97|       |      adcl $0,%[carry]
   98|       |
   99|       |      addl %[d],%[a]
  100|       |      adcl $0,%[carry]
  101|       |      )"
  102|       |       : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d)
  103|       |       : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d)
  104|       |       : "cc");
  105|       |
  106|       |   return a;
  107|       |
  108|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  109|  1.60k|   asm(R"(
  110|  1.60k|      mulq %[b]
  111|  1.60k|
  112|  1.60k|      addq %[c],%[a]
  113|  1.60k|      adcq $0,%[carry]
  114|  1.60k|
  115|  1.60k|      addq %[d],%[a]
  116|  1.60k|      adcq $0,%[carry]
  117|  1.60k|      )"
  118|  1.60k|       : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d)
  119|  1.60k|       : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d)
  120|  1.60k|       : "cc");
  121|       |
  122|  1.60k|   return a;
  123|       |
  124|       |#elif defined(BOTAN_MP_DWORD)
  125|       |   const BOTAN_MP_DWORD s = static_cast<BOTAN_MP_DWORD>(a) * b + c + *d;
  126|       |   *d = static_cast<word>(s >> BOTAN_MP_WORD_BITS);
  127|       |   return static_cast<word>(s);
  128|       |#else
  129|       |   static_assert(BOTAN_MP_WORD_BITS == 64, "Unexpected word size");
  130|       |
  131|       |   word hi = 0, lo = 0;
  132|       |
  133|       |   mul64x64_128(a, b, &lo, &hi);
  134|       |
  135|       |   lo += c;
  136|       |   hi += (lo < c);  // carry?
  137|       |
  138|       |   lo += *d;
  139|       |   hi += (lo < *d);  // carry?
  140|       |
  141|       |   *d = hi;
  142|       |   return lo;
  143|       |#endif
  144|  1.60k|}
_ZN5Botan13word8_linmul2EPmmm:
  443|    513|inline word word8_linmul2(word x[8], word y, word carry) {
  444|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
  445|       |   asm(DO_8_TIMES(LINMUL_OP, "x") : [carry] "=r"(carry) : [x] "r"(x), [y] "rm"(y), "0"(carry) : "cc", "%eax", "%edx");
  446|       |
  447|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  448|    513|   asm(DO_8_TIMES(LINMUL_OP, "x") : [carry] "=r"(carry) : [x] "r"(x), [y] "rm"(y), "0"(carry) : "cc", "%rax", "%rdx");
  449|       |
  450|       |#else
  451|       |   x[0] = word_madd2(x[0], y, &carry);
  452|       |   x[1] = word_madd2(x[1], y, &carry);
  453|       |   x[2] = word_madd2(x[2], y, &carry);
  454|       |   x[3] = word_madd2(x[3], y, &carry);
  455|       |   x[4] = word_madd2(x[4], y, &carry);
  456|       |   x[5] = word_madd2(x[5], y, &carry);
  457|       |   x[6] = word_madd2(x[6], y, &carry);
  458|       |   x[7] = word_madd2(x[7], y, &carry);
  459|       |#endif
  460|       |
  461|    513|   return carry;
  462|    513|}
_ZN5Botan12word3_muladdEPmS0_S0_mm:
  528|    144|inline void word3_muladd(word* w2, word* w1, word* w0, word x, word y) {
  529|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
  530|       |   word z0 = 0, z1 = 0;
  531|       |
  532|       |   asm("mull %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc");
  533|       |
  534|       |   asm(R"(
  535|       |       addl %[z0],%[w0]
  536|       |       adcl %[z1],%[w1]
  537|       |       adcl $0,%[w2]
  538|       |       )"
  539|       |       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  540|       |       : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2)
  541|       |       : "cc");
  542|       |
  543|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  544|    144|   word z0 = 0, z1 = 0;
  545|       |
  546|    144|   asm("mulq %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc");
  547|       |
  548|    144|   asm(R"(
  549|    144|       addq %[z0],%[w0]
  550|    144|       adcq %[z1],%[w1]
  551|    144|       adcq $0,%[w2]
  552|    144|       )"
  553|    144|       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  554|    144|       : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2)
  555|    144|       : "cc");
  556|       |
  557|       |#else
  558|       |   word carry = *w0;
  559|       |   *w0 = word_madd2(x, y, &carry);
  560|       |   *w1 += carry;
  561|       |   *w2 += (*w1 < carry);
  562|       |#endif
  563|    144|}

_ZN5Botan14bigint_sub_absEPmPKmmS2_m:
  604|    584|inline int32_t bigint_sub_abs(word z[], const word x[], size_t x_size, const word y[], size_t y_size) {
  605|    584|   const int32_t relative_size = bigint_cmp(x, x_size, y, y_size);
  606|       |
  607|       |   // Swap if relative_size == -1
  608|    584|   const bool need_swap = relative_size < 0;
  609|    584|   CT::conditional_swap_ptr(need_swap, x, y);
  610|    584|   CT::conditional_swap(need_swap, x_size, y_size);
  611|       |
  612|       |   /*
  613|       |   * We know at this point that x >= y so if y_size is larger than
  614|       |   * x_size, we are guaranteed they are just leading zeros which can
  615|       |   * be ignored
  616|       |   */
  617|    584|   y_size = std::min(x_size, y_size);
  618|       |
  619|    584|   bigint_sub3(z, x, x_size, y, y_size);
  620|       |
  621|    584|   return relative_size;
  622|    584|}
_ZN5Botan10bigint_cmpEPKmmS1_m:
  490|    646|inline int32_t bigint_cmp(const word x[], size_t x_size, const word y[], size_t y_size) {
  491|    646|   static_assert(sizeof(word) >= sizeof(uint32_t), "Size assumption");
  492|       |
  493|    646|   const word LT = static_cast<word>(-1);
  494|    646|   const word EQ = 0;
  495|    646|   const word GT = 1;
  496|       |
  497|    646|   const size_t common_elems = std::min(x_size, y_size);
  498|       |
  499|    646|   word result = EQ;  // until found otherwise
  500|       |
  501|  1.84k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (501:22): [True: 1.19k, False: 646]
  ------------------
  502|  1.19k|      const auto is_eq = CT::Mask<word>::is_equal(x[i], y[i]);
  503|  1.19k|      const auto is_lt = CT::Mask<word>::is_lt(x[i], y[i]);
  504|       |
  505|  1.19k|      result = is_eq.select(result, is_lt.select(LT, GT));
  506|  1.19k|   }
  507|       |
  508|    646|   if(x_size < y_size) {
  ------------------
  |  Branch (508:7): [True: 573, False: 73]
  ------------------
  509|    573|      word mask = 0;
  510|  2.68k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (510:30): [True: 2.11k, False: 573]
  ------------------
  511|  2.11k|         mask |= y[i];
  512|  2.11k|      }
  513|       |
  514|       |      // If any bits were set in high part of y, then x < y
  515|    573|      result = CT::Mask<word>::is_zero(mask).select(result, LT);
  516|    573|   } else if(y_size < x_size) {
  ------------------
  |  Branch (516:14): [True: 0, False: 73]
  ------------------
  517|      0|      word mask = 0;
  518|      0|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (518:30): [True: 0, False: 0]
  ------------------
  519|      0|         mask |= x[i];
  520|      0|      }
  521|       |
  522|       |      // If any bits were set in high part of x, then x > y
  523|      0|      result = CT::Mask<word>::is_zero(mask).select(result, GT);
  524|      0|   }
  525|       |
  526|    646|   CT::unpoison(result);
  527|    646|   BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ);
  ------------------
  |  |   99|    646|      do {                          \
  |  |  100|    646|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  528|    646|   return static_cast<int32_t>(result);
  529|    646|}
_ZN5Botan11bigint_sub3EPmPKmmS2_m:
  321|  1.68k|inline word bigint_sub3(word z[], const word x[], size_t x_size, const word y[], size_t y_size) {
  322|  1.68k|   word borrow = 0;
  323|       |
  324|  1.68k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|  1.68k|   do {                                                                                 \
  |  |   52|  1.68k|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   53|  1.68k|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  325|       |
  326|  1.68k|   const size_t blocks = y_size - (y_size % 8);
  327|       |
  328|  1.68k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (328:22): [True: 0, False: 1.68k]
  ------------------
  329|      0|      borrow = word8_sub3(z + i, x + i, y + i, borrow);
  330|      0|   }
  331|       |
  332|  6.95k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (332:27): [True: 5.27k, False: 1.68k]
  ------------------
  333|  5.27k|      z[i] = word_sub(x[i], y[i], &borrow);
  334|  5.27k|   }
  335|       |
  336|  7.98k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (336:27): [True: 6.30k, False: 1.68k]
  ------------------
  337|  6.30k|      z[i] = word_sub(x[i], 0, &borrow);
  338|  6.30k|   }
  339|       |
  340|  1.68k|   return borrow;
  341|  1.68k|}
_ZN5Botan14bigint_linmul3EPmPKmmm:
  468|      8|inline void bigint_linmul3(word z[], const word x[], size_t x_size, word y) {
  469|      8|   const size_t blocks = x_size - (x_size % 8);
  470|       |
  471|      8|   word carry = 0;
  472|       |
  473|      8|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (473:22): [True: 0, False: 8]
  ------------------
  474|      0|      carry = word8_linmul3(z + i, x + i, y, carry);
  475|      0|   }
  476|       |
  477|     46|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (477:27): [True: 38, False: 8]
  ------------------
  478|     38|      z[i] = word_madd2(x[i], y, &carry);
  479|     38|   }
  480|       |
  481|      8|   z[x_size] = carry;
  482|      8|}
_ZN5Botan15bigint_cnd_swapEmPmS0_m:
   29|    805|inline void bigint_cnd_swap(word cnd, word x[], word y[], size_t size) {
   30|    805|   const auto mask = CT::Mask<word>::expand(cnd);
   31|       |
   32|  7.24k|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (32:22): [True: 6.44k, False: 805]
  ------------------
   33|  6.44k|      const word a = x[i];
   34|  6.44k|      const word b = y[i];
   35|  6.44k|      x[i] = mask.select(b, a);
   36|  6.44k|      y[i] = mask.select(a, b);
   37|  6.44k|   }
   38|    805|}
_ZN5Botan14bigint_cnd_addEmPmmPKmm:
   40|    292|inline word bigint_cnd_add(word cnd, word x[], word x_size, const word y[], size_t y_size) {
   41|    292|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|    292|   do {                                                                                 \
  |  |   52|    292|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 292]
  |  |  ------------------
  |  |   53|    292|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|    292|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   42|       |
   43|    292|   const auto mask = CT::Mask<word>::expand(cnd);
   44|       |
   45|    292|   word carry = 0;
   46|       |
   47|    292|   const size_t blocks = y_size - (y_size % 8);
   48|    292|   word z[8] = {0};
   49|       |
   50|    292|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (50:22): [True: 0, False: 292]
  ------------------
   51|      0|      carry = word8_add3(z, x + i, y + i, carry);
   52|      0|      mask.select_n(x + i, z, x + i, 8);
   53|      0|   }
   54|       |
   55|  1.46k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (55:27): [True: 1.16k, False: 292]
  ------------------
   56|  1.16k|      z[0] = word_add(x[i], y[i], &carry);
   57|  1.16k|      x[i] = mask.select(z[0], x[i]);
   58|  1.16k|   }
   59|       |
   60|    584|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (60:27): [True: 292, False: 292]
  ------------------
   61|    292|      z[0] = word_add(x[i], 0, &carry);
   62|    292|      x[i] = mask.select(z[0], x[i]);
   63|    292|   }
   64|       |
   65|    292|   return mask.if_set_return(carry);
   66|    292|}
_ZN5Botan14bigint_add2_ncEPmmPKmm:
  203|    230|inline word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) {
  204|    230|   word carry = 0;
  205|       |
  206|    230|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|    230|   do {                                                                                 \
  |  |   52|    230|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 230]
  |  |  ------------------
  |  |   53|    230|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|    230|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  207|       |
  208|    230|   const size_t blocks = y_size - (y_size % 8);
  209|       |
  210|    230|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (210:22): [True: 0, False: 230]
  ------------------
  211|      0|      carry = word8_add2(x + i, y + i, carry);
  212|      0|   }
  213|       |
  214|  1.61k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (214:27): [True: 1.38k, False: 230]
  ------------------
  215|  1.38k|      x[i] = word_add(x[i], y[i], &carry);
  216|  1.38k|   }
  217|       |
  218|    451|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (218:27): [True: 221, False: 230]
  ------------------
  219|    221|      x[i] = word_add(x[i], 0, &carry);
  220|    221|   }
  221|       |
  222|    230|   return carry;
  223|    230|}
_ZN5Botan11bigint_add2EPmmPKmm:
  259|    230|inline void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) {
  260|    230|   x[x_size] += bigint_add2_nc(x, x_size, y, y_size);
  261|    230|}
_ZN5Botan11bigint_sub2EPmmPKmm:
  273|    292|inline word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size) {
  274|    292|   word borrow = 0;
  275|       |
  276|    292|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|    292|   do {                                                                                 \
  |  |   52|    292|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 292]
  |  |  ------------------
  |  |   53|    292|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|    292|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  277|       |
  278|    292|   const size_t blocks = y_size - (y_size % 8);
  279|       |
  280|    292|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (280:22): [True: 0, False: 292]
  ------------------
  281|      0|      borrow = word8_sub2(x + i, y + i, borrow);
  282|      0|   }
  283|       |
  284|  1.46k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (284:27): [True: 1.16k, False: 292]
  ------------------
  285|  1.16k|      x[i] = word_sub(x[i], y[i], &borrow);
  286|  1.16k|   }
  287|       |
  288|    584|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (288:27): [True: 292, False: 292]
  ------------------
  289|    292|      x[i] = word_sub(x[i], 0, &borrow);
  290|    292|   }
  291|       |
  292|    292|   return borrow;
  293|    292|}
_ZN5Botan15bigint_sub2_revEPmPKmm:
  298|     62|inline void bigint_sub2_rev(word x[], const word y[], size_t y_size) {
  299|     62|   word borrow = 0;
  300|       |
  301|     62|   const size_t blocks = y_size - (y_size % 8);
  302|       |
  303|     62|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (303:22): [True: 0, False: 62]
  ------------------
  304|      0|      borrow = word8_sub2_rev(x + i, y + i, borrow);
  305|      0|   }
  306|       |
  307|    434|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (307:27): [True: 372, False: 62]
  ------------------
  308|    372|      x[i] = word_sub(y[i], x[i], &borrow);
  309|    372|   }
  310|       |
  311|     62|   BOTAN_ASSERT(borrow == 0, "y must be greater than x");
  ------------------
  |  |   51|     62|   do {                                                                                 \
  |  |   52|     62|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 62]
  |  |  ------------------
  |  |   53|     62|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|     62|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  312|     62|}
_ZN5Botan11bigint_shr1EPmmmm:
  397|    584|inline void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) {
  398|    584|   const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0;
  ------------------
  |  Branch (398:23): [True: 584, False: 0]
  ------------------
  399|       |
  400|    584|   if(top > 0) {
  ------------------
  |  Branch (400:7): [True: 584, False: 0]
  ------------------
  401|    584|      copy_mem(x, x + word_shift, top);
  402|    584|   }
  403|    584|   clear_mem(x + top, std::min(word_shift, x_size));
  404|       |
  405|    584|   const auto carry_mask = CT::Mask<word>::expand(bit_shift);
  406|    584|   const word carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift);
  ------------------
  |  |   50|    584|#define BOTAN_MP_WORD_BITS 64
  ------------------
  407|       |
  408|    584|   word carry = 0;
  409|       |
  410|  3.00k|   for(size_t i = 0; i != top; ++i) {
  ------------------
  |  Branch (410:22): [True: 2.41k, False: 584]
  ------------------
  411|  2.41k|      const word w = x[top - i - 1];
  412|  2.41k|      x[top - i - 1] = (w >> bit_shift) | carry;
  413|  2.41k|      carry = carry_mask.if_set_return(w << carry_shift);
  414|  2.41k|   }
  415|    584|}
_ZN5Botan14bigint_linmul2EPmmm:
  452|    513|[[nodiscard]] inline word bigint_linmul2(word x[], size_t x_size, word y) {
  453|    513|   const size_t blocks = x_size - (x_size % 8);
  454|       |
  455|    513|   word carry = 0;
  456|       |
  457|  1.02k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (457:22): [True: 513, False: 513]
  ------------------
  458|    513|      carry = word8_linmul2(x + i, y, carry);
  459|    513|   }
  460|       |
  461|    513|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (461:27): [True: 0, False: 513]
  ------------------
  462|      0|      x[i] = word_madd2(x[i], y, &carry);
  463|      0|   }
  464|       |
  465|    513|   return carry;
  466|    513|}
_ZN5Botan15bigint_ct_is_ltEPKmmS1_mb:
  537|    293|   const word x[], size_t x_size, const word y[], size_t y_size, bool lt_or_equal = false) {
  538|    293|   const size_t common_elems = std::min(x_size, y_size);
  539|       |
  540|    293|   auto is_lt = CT::Mask<word>::expand(lt_or_equal);
  541|       |
  542|    984|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (542:22): [True: 691, False: 293]
  ------------------
  543|    691|      const auto eq = CT::Mask<word>::is_equal(x[i], y[i]);
  544|    691|      const auto lt = CT::Mask<word>::is_lt(x[i], y[i]);
  545|    691|      is_lt = eq.select_mask(is_lt, lt);
  546|    691|   }
  547|       |
  548|    293|   if(x_size < y_size) {
  ------------------
  |  Branch (548:7): [True: 288, False: 5]
  ------------------
  549|    288|      word mask = 0;
  550|  1.94k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (550:30): [True: 1.65k, False: 288]
  ------------------
  551|  1.65k|         mask |= y[i];
  552|  1.65k|      }
  553|       |      // If any bits were set in high part of y, then is_lt should be forced true
  554|    288|      is_lt |= CT::Mask<word>::expand(mask);
  555|    288|   } else if(y_size < x_size) {
  ------------------
  |  Branch (555:14): [True: 0, False: 5]
  ------------------
  556|      0|      word mask = 0;
  557|      0|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (557:30): [True: 0, False: 0]
  ------------------
  558|      0|         mask |= x[i];
  559|      0|      }
  560|       |
  561|       |      // If any bits were set in high part of x, then is_lt should be false
  562|      0|      is_lt &= CT::Mask<word>::is_zero(mask);
  563|      0|   }
  564|       |
  565|    293|   return is_lt;
  566|    293|}
_ZN5Botan15bigint_ct_is_eqEPKmmS1_m:
  568|    292|inline CT::Mask<word> bigint_ct_is_eq(const word x[], size_t x_size, const word y[], size_t y_size) {
  569|    292|   const size_t common_elems = std::min(x_size, y_size);
  570|       |
  571|    292|   word diff = 0;
  572|       |
  573|    821|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (573:22): [True: 529, False: 292]
  ------------------
  574|    529|      diff |= (x[i] ^ y[i]);
  575|    529|   }
  576|       |
  577|       |   // If any bits were set in high part of x/y, then they are not equal
  578|    292|   if(x_size < y_size) {
  ------------------
  |  Branch (578:7): [True: 0, False: 292]
  ------------------
  579|      0|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (579:30): [True: 0, False: 0]
  ------------------
  580|      0|         diff |= y[i];
  581|      0|      }
  582|    292|   } else if(y_size < x_size) {
  ------------------
  |  Branch (582:14): [True: 0, False: 292]
  ------------------
  583|      0|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (583:30): [True: 0, False: 0]
  ------------------
  584|      0|         diff |= x[i];
  585|      0|      }
  586|      0|   }
  587|       |
  588|    292|   return CT::Mask<word>::is_zero(diff);
  589|    292|}

_ZN5Botan8round_upEmm:
   21|    294|inline size_t round_up(size_t n, size_t align_to) {
   22|    294|   BOTAN_ARG_CHECK(align_to != 0, "align_to must not be 0");
  ------------------
  |  |   30|    294|   do {                                                          \
  |  |   31|    294|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 294]
  |  |  ------------------
  |  |   32|    294|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|    294|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   23|       |
   24|    294|   if(n % align_to) {
  ------------------
  |  Branch (24:7): [True: 288, False: 6]
  ------------------
   25|    288|      n += align_to - (n % align_to);
   26|    288|   }
   27|    294|   return n;
   28|    294|}

_ZN5Botan11checked_mulEmm:
   47|  1.31k|inline std::optional<size_t> checked_mul(size_t x, size_t y) {
   48|  1.31k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_add_overflow)
   49|  1.31k|   size_t z;
   50|  1.31k|   if(__builtin_mul_overflow(x, y, &z)) [[unlikely]]
  ------------------
  |  Branch (50:7): [True: 0, False: 1.31k]
  ------------------
   51|       |#elif defined(_MSC_VER)
   52|       |   size_t z;
   53|       |   if(SizeTMult(x, y, &z) != S_OK) [[unlikely]]
   54|       |#else
   55|       |   size_t z = x * y;
   56|       |   if(y && z / y != x) [[unlikely]]
   57|       |#endif
   58|      0|   {
   59|      0|      return std::nullopt;
   60|      0|   }
   61|  1.31k|   return z;
   62|  1.31k|}

_ZN5Botan13ignore_paramsIJRmEEEvDpOT_:
  114|  3.57k|void ignore_params(T&&... args) {
  115|  3.57k|   (ignore_param(args), ...);
  116|  3.57k|}
_ZN5Botan12ignore_paramIRmEEvOT_:
  111|  3.57k|void ignore_param(T&&) {}
_ZN5Botan12ignore_paramIRKmEEvOT_:
  111|      1|void ignore_param(T&&) {}
_ZN5Botan13ignore_paramsIJRKmEEEvDpOT_:
  114|      1|void ignore_params(T&&... args) {
  115|      1|   (ignore_param(args), ...);
  116|      1|}
_ZN5Botan13ignore_paramsIJRNSt3__16vectorImNS_16secure_allocatorImEEEEEEEvDpOT_:
  114|    292|void ignore_params(T&&... args) {
  115|    292|   (ignore_param(args), ...);
  116|    292|}
_ZN5Botan12ignore_paramIRNSt3__16vectorImNS_16secure_allocatorImEEEEEEvOT_:
  111|    292|void ignore_param(T&&) {}
_ZN5Botan13ignore_paramsIJRlEEEvDpOT_:
  114|    292|void ignore_params(T&&... args) {
  115|    292|   (ignore_param(args), ...);
  116|    292|}
_ZN5Botan12ignore_paramIRlEEvOT_:
  111|    292|void ignore_param(T&&) {}

_ZN5Botan6BigIntD2Ev:
  148|    595|      ~BigInt() { const_time_unpoison(); }
_ZNK5Botan6BigInt19const_time_unpoisonEv:
  726|    595|      void const_time_unpoison() const {}
_ZN5Botan6BigInt6decodeEPKhm:
  776|    293|      static BigInt decode(const uint8_t buf[], size_t length) { return BigInt(buf, length); }
_ZN5BotanltERKNS_6BigIntES2_:
 1011|    293|inline bool operator<(const BigInt& a, const BigInt& b) {
 1012|    293|   return a.is_less_than(b);
 1013|    293|}
_ZN5BotanneERKNS_6BigIntES2_:
  999|    292|inline bool operator!=(const BigInt& a, const BigInt& b) {
 1000|    292|   return !a.is_equal(b);
 1001|    292|}
_ZN5Botan6BigIntaSEOS0_:
  153|      2|      BigInt& operator=(BigInt&& other) {
  154|      2|         if(this != &other) {
  ------------------
  |  Branch (154:13): [True: 2, False: 0]
  ------------------
  155|      2|            this->swap(other);
  156|      2|         }
  157|       |
  158|      2|         return (*this);
  159|      2|      }
_ZN5Botan6BigInt4swapERS0_:
  170|      2|      void swap(BigInt& other) {
  171|      2|         m_data.swap(other.m_data);
  172|      2|         std::swap(m_signedness, other.m_signedness);
  173|      2|      }
_ZN5Botan6BigInt8swap_regERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  177|    433|      void swap_reg(secure_vector<word>& reg) {
  178|    433|         m_data.swap(reg);
  179|       |         // sign left unchanged
  180|    433|      }
_ZN5Botan6BigInt5clearEv:
  370|    729|      void clear() {
  371|    729|         m_data.set_to_zero();
  372|    729|         m_signedness = Positive;
  373|    729|      }
_ZNK5Botan6BigInt10is_nonzeroEv:
  422|    292|      bool is_nonzero() const { return (!is_zero()); }
_ZNK5Botan6BigInt7is_zeroEv:
  428|    355|      bool is_zero() const { return (sig_words() == 0); }
_ZN5Botan6BigInt7set_bitEm:
  434|      1|      void set_bit(size_t n) { conditionally_set_bit(n, true); }
_ZN5Botan6BigInt21conditionally_set_bitEmb:
  444|  1.02k|      void conditionally_set_bit(size_t n, bool set_it) {
  445|  1.02k|         const size_t which = n / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  1.02k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  446|  1.02k|         const word mask = static_cast<word>(set_it) << (n % BOTAN_MP_WORD_BITS);
  ------------------
  |  |   50|  1.02k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  447|  1.02k|         m_data.set_word_at(which, word_at(which) | mask);
  448|  1.02k|      }
_ZN5Botan6BigInt9mask_bitsEm:
  460|    584|      void mask_bits(size_t n) { m_data.mask_bits(n); }
_ZNK5Botan6BigInt7get_bitEm:
  467|    513|      bool get_bit(size_t n) const { return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1); }
  ------------------
  |  |   50|    513|#define BOTAN_MP_WORD_BITS 64
  ------------------
                    bool get_bit(size_t n) const { return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1); }
  ------------------
  |  |   50|    513|#define BOTAN_MP_WORD_BITS 64
  ------------------
_ZNK5Botan6BigInt7word_atEm:
  518|  1.54k|      word word_at(size_t n) const { return m_data.get_word_at(n); }
_ZN5Botan6BigInt11set_word_atEmm:
  520|    513|      void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
_ZNK5Botan6BigInt11is_negativeEv:
  528|  2.63k|      bool is_negative() const { return (sign() == Negative); }
_ZNK5Botan6BigInt11is_positiveEv:
  534|    293|      bool is_positive() const { return (sign() == Positive); }
_ZNK5Botan6BigInt4signEv:
  540|  6.14k|      Sign sign() const { return (m_signedness); }
_ZN5Botan6BigInt8set_signENS0_4SignE:
  561|  1.96k|      void set_sign(Sign sign) {
  562|  1.96k|         if(sign == Negative && is_zero()) {
  ------------------
  |  Branch (562:13): [True: 62, False: 1.89k]
  |  Branch (562:33): [True: 0, False: 62]
  ------------------
  563|      0|            sign = Positive;
  564|      0|         }
  565|       |
  566|  1.96k|         m_signedness = sign;
  567|  1.96k|      }
_ZNK5Botan6BigInt4sizeEv:
  578|  3.95k|      size_t size() const { return m_data.size(); }
_ZNK5Botan6BigInt9sig_wordsEv:
  584|  4.16k|      size_t sig_words() const { return m_data.sig_words(); }
_ZN5Botan6BigInt12mutable_dataEv:
  609|  4.10k|      word* mutable_data() { return m_data.mutable_data(); }
_ZNK5Botan6BigInt4dataEv:
  615|  5.47k|      const word* data() const { return m_data.const_data(); }
_ZNK5Botan6BigInt7grow_toEm:
  631|  2.20k|      void grow_to(size_t n) const { m_data.grow_to(n); }
_ZN5Botan6BigInt4Data12mutable_dataEv:
  834|  4.68k|            word* mutable_data() {
  835|  4.68k|               invalidate_sig_words();
  836|  4.68k|               return m_reg.data();
  837|  4.68k|            }
_ZNK5Botan6BigInt4Data10const_dataEv:
  839|  5.47k|            const word* const_data() const { return m_reg.data(); }
_ZNK5Botan6BigInt4Data11get_word_atEm:
  848|  1.54k|            word get_word_at(size_t n) const {
  849|  1.54k|               if(n < m_reg.size()) {
  ------------------
  |  Branch (849:19): [True: 1.54k, False: 1]
  ------------------
  850|  1.54k|                  return m_reg[n];
  851|  1.54k|               }
  852|      1|               return 0;
  853|  1.54k|            }
_ZN5Botan6BigInt4Data11set_word_atEmm:
  855|  1.54k|            void set_word_at(size_t i, word w) {
  856|  1.54k|               invalidate_sig_words();
  857|  1.54k|               if(i >= m_reg.size()) {
  ------------------
  |  Branch (857:19): [True: 514, False: 1.02k]
  ------------------
  858|    514|                  if(w == 0) {
  ------------------
  |  Branch (858:22): [True: 513, False: 1]
  ------------------
  859|    513|                     return;
  860|    513|                  }
  861|      1|                  grow_to(i + 1);
  862|      1|               }
  863|  1.02k|               m_reg[i] = w;
  864|  1.02k|            }
_ZN5Botan6BigInt4Data11set_to_zeroEv:
  871|    729|            void set_to_zero() {
  872|    729|               m_reg.resize(m_reg.capacity());
  873|    729|               clear_mem(m_reg.data(), m_reg.size());
  874|    729|               m_sig_words = 0;
  875|    729|            }
_ZN5Botan6BigInt4Data9mask_bitsEm:
  883|    584|            void mask_bits(size_t n) {
  884|    584|               if(n == 0) {
  ------------------
  |  Branch (884:19): [True: 0, False: 584]
  ------------------
  885|      0|                  return set_to_zero();
  886|      0|               }
  887|       |
  888|    584|               const size_t top_word = n / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|    584|#define BOTAN_MP_WORD_BITS 64
  ------------------
  889|       |
  890|       |               // if(top_word < sig_words()) ?
  891|    584|               if(top_word < size()) {
  ------------------
  |  Branch (891:19): [True: 584, False: 0]
  ------------------
  892|    584|                  const word mask = (static_cast<word>(1) << (n % BOTAN_MP_WORD_BITS)) - 1;
  ------------------
  |  |   50|    584|#define BOTAN_MP_WORD_BITS 64
  ------------------
  893|    584|                  const size_t len = size() - (top_word + 1);
  894|    584|                  if(len > 0) {
  ------------------
  |  Branch (894:22): [True: 584, False: 0]
  ------------------
  895|    584|                     clear_mem(&m_reg[top_word + 1], len);
  896|    584|                  }
  897|    584|                  m_reg[top_word] &= mask;
  898|    584|                  invalidate_sig_words();
  899|    584|               }
  900|    584|            }
_ZNK5Botan6BigInt4Data7grow_toEm:
  902|  2.20k|            void grow_to(size_t n) const {
  903|  2.20k|               if(n > size()) {
  ------------------
  |  Branch (903:19): [True: 368, False: 1.83k]
  ------------------
  904|    368|                  if(n <= m_reg.capacity()) {
  ------------------
  |  Branch (904:22): [True: 142, False: 226]
  ------------------
  905|    142|                     m_reg.resize(n);
  906|    226|                  } else {
  907|    226|                     m_reg.resize(n + (8 - (n % 8)));
  908|    226|                  }
  909|    368|               }
  910|  2.20k|            }
_ZNK5Botan6BigInt4Data4sizeEv:
  912|  7.91k|            size_t size() const { return m_reg.size(); }
_ZN5Botan6BigInt4Data4swapERS1_:
  921|      2|            void swap(Data& other) {
  922|      2|               m_reg.swap(other.m_reg);
  923|      2|               std::swap(m_sig_words, other.m_sig_words);
  924|      2|            }
_ZN5Botan6BigInt4Data4swapERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  926|    727|            void swap(secure_vector<word>& reg) {
  927|    727|               m_reg.swap(reg);
  928|    727|               invalidate_sig_words();
  929|    727|            }
_ZNK5Botan6BigInt4Data20invalidate_sig_wordsEv:
  931|  7.54k|            void invalidate_sig_words() const { m_sig_words = sig_words_npos; }
_ZNK5Botan6BigInt4Data9sig_wordsEv:
  933|  4.16k|            size_t sig_words() const {
  934|  4.16k|               if(m_sig_words == sig_words_npos) {
  ------------------
  |  Branch (934:19): [True: 2.34k, False: 1.82k]
  ------------------
  935|  2.34k|                  m_sig_words = calc_sig_words();
  936|  2.34k|               } else {
  937|  1.82k|                  BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words());
  ------------------
  |  |   99|  1.82k|      do {                          \
  |  |  100|  1.82k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  938|  1.82k|               }
  939|  4.16k|               return m_sig_words;
  940|  4.16k|            }
_ZN5BotanltERKNS_6BigIntEm:
 1035|      1|inline bool operator<(const BigInt& a, word b) {
 1036|      1|   return (a.cmp_word(b) < 0);
 1037|      1|}
_ZN5BotangtERKNS_6BigIntEm:
 1039|      1|inline bool operator>(const BigInt& a, word b) {
 1040|      1|   return (a.cmp_word(b) > 0);
 1041|      1|}
_ZN5Botan6BigIntC2Ev:
   40|    301|      BigInt() = default;
_ZN5Botan6BigIntaSERKS0_:
  164|    295|      BigInt& operator=(const BigInt&) = default;

_ZN5Botan6ranges24assert_exact_byte_lengthILm8ERNSt3__14spanIKhLm8EEEEEvOT0_:
   86|    994|inline constexpr void assert_exact_byte_length(R&& r) {
   87|    994|   const std::span s{r};
   88|    994|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|    994|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|    994|   } else {
   91|    994|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|    994|   }
   93|    994|}
_ZN5Botan6ranges25assert_equal_byte_lengthsIRNSt3__14spanImLm1EEEJRNS3_IKhLm8EEEEEEvOT_DpOT0_:
  107|    497|{
  108|    497|   const std::span s0{r0};
  109|       |
  110|    497|   if constexpr(decltype(s0)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (110:17): [Folded - Ignored]
  ------------------
  111|    497|      constexpr size_t expected_size = s0.size_bytes();
  112|    497|      (assert_exact_byte_length<expected_size>(rs), ...);
  113|    497|   } else {
  114|    497|      const size_t expected_size = s0.size_bytes();
  115|    497|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  116|    497|                      "memory regions don't have equal lengths");
  117|    497|   }
  118|    497|}
_ZN5Botan6ranges10size_bytesIRNSt3__14spanImLm1EEEEEmOT_:
   73|    497|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   74|    497|   return std::span{r}.size_bytes();
   75|    497|}

_ZN5Botan11clear_bytesEPvm:
  103|  3.34k|inline constexpr void clear_bytes(void* ptr, size_t bytes) {
  104|  3.34k|   if(bytes > 0) {
  ------------------
  |  Branch (104:7): [True: 3.04k, False: 296]
  ------------------
  105|  3.04k|      std::memset(ptr, 0, bytes);
  106|  3.04k|   }
  107|  3.34k|}
_ZN5Botan22cast_char_ptr_to_uint8EPKc:
  272|      1|inline const uint8_t* cast_char_ptr_to_uint8(const char* s) {
  273|      1|   return reinterpret_cast<const uint8_t*>(s);
  274|      1|}
_ZN5Botan22cast_uint8_ptr_to_charEPKh:
  276|      1|inline const char* cast_uint8_ptr_to_char(const uint8_t* b) {
  277|      1|   return reinterpret_cast<const char*>(b);
  278|      1|}
_ZN5Botan9clear_memImEEvPT_m:
  120|  3.34k|inline constexpr void clear_mem(T* ptr, size_t n) {
  121|  3.34k|   clear_bytes(ptr, sizeof(T) * n);
  122|  3.34k|}
_ZN5Botan8copy_memImEEvPT_PKS1_m:
  146|    584|inline constexpr void copy_mem(T* out, const T* in, size_t n) {
  147|    584|   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
  ------------------
  |  |   78|    584|   do {                                                                                          \
  |  |   79|  1.16k|      if((expr1) && !(expr2))                                                                    \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 584, False: 0]
  |  |  |  Branch (79:23): [True: 584, False: 0]
  |  |  |  Branch (79:23): [True: 584, False: 0]
  |  |  ------------------
  |  |   80|    584|         Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, __LINE__); \
  |  |   81|    584|   } while(0)
  |  |  ------------------
  |  |  |  Branch (81:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  148|       |
  149|    584|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (149:7): [True: 584, False: 0]
  |  Branch (149:24): [True: 584, False: 0]
  |  Branch (149:42): [True: 584, False: 0]
  ------------------
  150|    584|      std::memmove(out, in, sizeof(T) * n);
  151|    584|   }
  152|    584|}
_ZN5Botan13typecast_copyImRNSt3__14spanIKhLm8EEEEET_OT0_:
  209|    497|inline constexpr ToT typecast_copy(FromR&& src) noexcept {
  210|    497|   ToT dst;
  211|    497|   typecast_copy(dst, src);
  212|    497|   return dst;
  213|    497|}
_ZN5Botan13typecast_copyImRNSt3__14spanIKhLm8EEEEEvRT_OT0_:
  188|    497|inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
  189|    497|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|    497|}
_ZN5Botan13typecast_copyINSt3__14spanImLm1EEERNS2_IKhLm8EEEEEvOT_OT0_:
  176|    497|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  177|    497|   ranges::assert_equal_byte_lengths(out, in);
  178|    497|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|    497|}
_ZN5Botan9clear_memIhEEvPT_m:
  120|      1|inline constexpr void clear_mem(T* ptr, size_t n) {
  121|      1|   clear_bytes(ptr, sizeof(T) * n);
  122|      1|}

_ZN5Botan16secure_allocatorImE10deallocateEPmm:
   47|  1.30k|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorIhE8allocateEm:
   45|      1|      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
_ZN5Botan16secure_allocatorIhE10deallocateEPhm:
   47|      1|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorImE8allocateEm:
   45|  1.30k|      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
_ZN5BotanneIhhEEbRKNS_16secure_allocatorIT_EERKNS1_IT0_EE:
   56|      1|inline bool operator!=(const secure_allocator<T>&, const secure_allocator<U>&) {
   57|      1|   return false;
   58|      1|}

LLVMFuzzerInitialize:
   24|      2|extern "C" int LLVMFuzzerInitialize(int*, char***) {
   25|       |   /*
   26|       |   * This disables the mlock pool, as overwrites within the pool are
   27|       |   * opaque to ASan or other instrumentation.
   28|       |   */
   29|      2|   ::setenv("BOTAN_MLOCK_POOL_SIZE", "0", 1);
   30|      2|   return 0;
   31|      2|}
LLVMFuzzerTestOneInput:
   34|    328|extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) {
   35|    328|   if(len <= max_fuzzer_input_size) {
  ------------------
  |  Branch (35:7): [True: 318, False: 10]
  ------------------
   36|    318|      fuzz(in, len);
   37|    318|   }
   38|    328|   return 0;
   39|    328|}

_Z4fuzzPKhm:
   12|    318|void fuzz(const uint8_t in[], size_t len) {
   13|    318|   if(len > 2 * 256 / 8) {
  ------------------
  |  Branch (13:7): [True: 25, False: 293]
  ------------------
   14|     25|      return;
   15|     25|   }
   16|       |
   17|    293|   static const Botan::BigInt& prime = Botan::prime_p256();
   18|    293|   static const Botan::BigInt prime_2 = prime * prime;
   19|    293|   static Botan::Modular_Reducer prime_redc(prime);
   20|       |
   21|    293|   Botan::BigInt input = Botan::BigInt::decode(in, len);
   22|       |
   23|    293|   if(input < prime_2) {
  ------------------
  |  Branch (23:7): [True: 292, False: 1]
  ------------------
   24|    292|      const Botan::BigInt ref = prime_redc.reduce(input);
   25|       |
   26|    292|      Botan::secure_vector<Botan::word> ws;
   27|    292|      Botan::redc_p256(input, ws);
   28|       |
   29|    292|      FUZZER_ASSERT_EQUAL(ref, input);
  ------------------
  |  |   60|    292|   do {                                                                                  \
  |  |   61|    292|      if(x != y) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 292]
  |  |  ------------------
  |  |   62|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << x << " != " << #y << " = " << y << "\n"); \
  |  |  ------------------
  |  |  |  |   54|      0|   do {                                                                          \
  |  |  |  |   55|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; \
  |  |  |  |   56|      0|      abort();                                                                   \
  |  |  |  |   57|      0|   } while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (57:12): [Folded - Ignored]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   63|      0|      }                                                                                  \
  |  |   64|    292|   } while(0)
  |  |  ------------------
  |  |  |  Branch (64:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   30|    292|   }
   31|    293|}

_ZN5Botan10hex_decodeEPhPKcmRmb:
   81|      1|size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t& input_consumed, bool ignore_ws) {
   82|      1|   uint8_t* out_ptr = output;
   83|      1|   bool top_nibble = true;
   84|       |
   85|      1|   clear_mem(output, input_length / 2);
   86|       |
   87|     65|   for(size_t i = 0; i != input_length; ++i) {
  ------------------
  |  Branch (87:22): [True: 64, False: 1]
  ------------------
   88|     64|      const uint8_t bin = hex_char_to_bin(input[i]);
   89|       |
   90|     64|      if(bin >= 0x10) {
  ------------------
  |  Branch (90:10): [True: 0, False: 64]
  ------------------
   91|      0|         if(bin == 0x80 && ignore_ws) {
  ------------------
  |  Branch (91:13): [True: 0, False: 0]
  |  Branch (91:28): [True: 0, False: 0]
  ------------------
   92|      0|            continue;
   93|      0|         }
   94|       |
   95|      0|         throw Invalid_Argument(fmt("hex_decode: invalid character '{}'", format_char_for_display(input[i])));
   96|      0|      }
   97|       |
   98|     64|      if(top_nibble) {
  ------------------
  |  Branch (98:10): [True: 32, False: 32]
  ------------------
   99|     32|         *out_ptr |= bin << 4;
  100|     32|      } else {
  101|     32|         *out_ptr |= bin;
  102|     32|      }
  103|       |
  104|     64|      top_nibble = !top_nibble;
  105|     64|      if(top_nibble) {
  ------------------
  |  Branch (105:10): [True: 32, False: 32]
  ------------------
  106|     32|         ++out_ptr;
  107|     32|      }
  108|     64|   }
  109|       |
  110|      1|   input_consumed = input_length;
  111|      1|   size_t written = (out_ptr - output);
  112|       |
  113|       |   /*
  114|       |   * We only got half of a uint8_t at the end; zap the half-written
  115|       |   * output and mark it as unread
  116|       |   */
  117|      1|   if(!top_nibble) {
  ------------------
  |  Branch (117:7): [True: 0, False: 1]
  ------------------
  118|      0|      *out_ptr = 0;
  119|      0|      input_consumed -= 1;
  120|      0|   }
  121|       |
  122|      1|   return written;
  123|      1|}
_ZN5Botan10hex_decodeEPhPKcmb:
  125|      1|size_t hex_decode(uint8_t output[], const char input[], size_t input_length, bool ignore_ws) {
  126|      1|   size_t consumed = 0;
  127|      1|   size_t written = hex_decode(output, input, input_length, consumed, ignore_ws);
  128|       |
  129|      1|   if(consumed != input_length) {
  ------------------
  |  Branch (129:7): [True: 0, False: 1]
  ------------------
  130|      0|      throw Invalid_Argument("hex_decode: input did not have full bytes");
  131|      0|   }
  132|       |
  133|      1|   return written;
  134|      1|}
_ZN5Botan17hex_decode_lockedEPKcmb:
  144|      1|secure_vector<uint8_t> hex_decode_locked(const char input[], size_t input_length, bool ignore_ws) {
  145|      1|   secure_vector<uint8_t> bin(1 + input_length / 2);
  146|       |
  147|      1|   size_t written = hex_decode(bin.data(), input, input_length, ignore_ws);
  148|       |
  149|      1|   bin.resize(written);
  150|      1|   return bin;
  151|      1|}
hex.cpp:_ZN5Botan12_GLOBAL__N_115hex_char_to_binEc:
   55|     64|uint8_t hex_char_to_bin(char input) {
   56|     64|   const uint8_t c = static_cast<uint8_t>(input);
   57|       |
   58|     64|   const auto is_alpha_upper = CT::Mask<uint8_t>::is_within_range(c, uint8_t('A'), uint8_t('F'));
   59|     64|   const auto is_alpha_lower = CT::Mask<uint8_t>::is_within_range(c, uint8_t('a'), uint8_t('f'));
   60|     64|   const auto is_decimal = CT::Mask<uint8_t>::is_within_range(c, uint8_t('0'), uint8_t('9'));
   61|       |
   62|     64|   const auto is_whitespace =
   63|     64|      CT::Mask<uint8_t>::is_any_of(c, {uint8_t(' '), uint8_t('\t'), uint8_t('\n'), uint8_t('\r')});
   64|       |
   65|     64|   const uint8_t c_upper = c - uint8_t('A') + 10;
   66|     64|   const uint8_t c_lower = c - uint8_t('a') + 10;
   67|     64|   const uint8_t c_decim = c - uint8_t('0');
   68|       |
   69|     64|   uint8_t ret = 0xFF;  // default value
   70|       |
   71|     64|   ret = is_alpha_upper.select(c_upper, ret);
   72|     64|   ret = is_alpha_lower.select(c_lower, ret);
   73|     64|   ret = is_decimal.select(c_decim, ret);
   74|     64|   ret = is_whitespace.select(0x80, ret);
   75|       |
   76|     64|   return ret;
   77|     64|}

_ZN5Botan6BigInt6decodeEPKhmNS0_4BaseE:
  151|      1|BigInt BigInt::decode(const uint8_t buf[], size_t length, Base base) {
  152|      1|   BigInt r;
  153|      1|   if(base == Binary) {
  ------------------
  |  Branch (153:7): [True: 0, False: 1]
  ------------------
  154|      0|      r.binary_decode(buf, length);
  155|      1|   } else if(base == Hexadecimal) {
  ------------------
  |  Branch (155:14): [True: 1, False: 0]
  ------------------
  156|      1|      secure_vector<uint8_t> binary;
  157|       |
  158|      1|      if(length % 2) {
  ------------------
  |  Branch (158:10): [True: 0, False: 1]
  ------------------
  159|       |         // Handle lack of leading 0
  160|      0|         const char buf0_with_leading_0[2] = {'0', static_cast<char>(buf[0])};
  161|       |
  162|      0|         binary = hex_decode_locked(buf0_with_leading_0, 2);
  163|       |
  164|      0|         binary += hex_decode_locked(cast_uint8_ptr_to_char(&buf[1]), length - 1, false);
  165|      1|      } else {
  166|      1|         binary = hex_decode_locked(cast_uint8_ptr_to_char(buf), length, false);
  167|      1|      }
  168|       |
  169|      1|      r.binary_decode(binary.data(), binary.size());
  170|      1|   } else if(base == Decimal) {
  ------------------
  |  Branch (170:14): [True: 0, False: 0]
  ------------------
  171|       |      // This could be made faster using the same trick as to_dec_string
  172|      0|      for(size_t i = 0; i != length; ++i) {
  ------------------
  |  Branch (172:25): [True: 0, False: 0]
  ------------------
  173|      0|         const char c = buf[i];
  174|       |
  175|      0|         if(c < '0' || c > '9') {
  ------------------
  |  Branch (175:13): [True: 0, False: 0]
  |  Branch (175:24): [True: 0, False: 0]
  ------------------
  176|      0|            throw Invalid_Argument("BigInt::decode: invalid decimal char");
  177|      0|         }
  178|       |
  179|      0|         const uint8_t x = c - '0';
  180|      0|         BOTAN_ASSERT_NOMSG(x < 10);
  ------------------
  |  |   60|      0|   do {                                                                     \
  |  |   61|      0|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 0]
  |  |  ------------------
  |  |   62|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      0|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  181|       |
  182|      0|         r *= 10;
  183|      0|         r += x;
  184|      0|      }
  185|      0|   } else {
  186|      0|      throw Invalid_Argument("Unknown BigInt decoding method");
  187|      0|   }
  188|      1|   return r;
  189|      1|}

_ZN5Botan6BigInt3addEPKmmNS0_4SignE:
   16|    292|BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) {
   17|    292|   const size_t x_sw = sig_words();
   18|       |
   19|    292|   grow_to(std::max(x_sw, y_words) + 1);
   20|       |
   21|    292|   if(sign() == y_sign) {
  ------------------
  |  Branch (21:7): [True: 230, False: 62]
  ------------------
   22|    230|      bigint_add2(mutable_data(), size() - 1, y, y_words);
   23|    230|   } else {
   24|     62|      const int32_t relative_size = bigint_cmp(data(), x_sw, y, y_words);
   25|       |
   26|     62|      if(relative_size >= 0) {
  ------------------
  |  Branch (26:10): [True: 0, False: 62]
  ------------------
   27|       |         // *this >= y
   28|      0|         bigint_sub2(mutable_data(), x_sw, y, y_words);
   29|     62|      } else {
   30|       |         // *this < y
   31|     62|         bigint_sub2_rev(mutable_data(), y, y_words);
   32|     62|      }
   33|       |
   34|       |      //this->sign_fixup(relative_size, y_sign);
   35|     62|      if(relative_size < 0) {
  ------------------
  |  Branch (35:10): [True: 62, False: 0]
  ------------------
   36|     62|         set_sign(y_sign);
   37|     62|      } else if(relative_size == 0) {
  ------------------
  |  Branch (37:17): [True: 0, False: 0]
  ------------------
   38|      0|         set_sign(Positive);
   39|      0|      }
   40|     62|   }
   41|       |
   42|    292|   return (*this);
   43|    292|}
_ZN5Botan6BigInt7rev_subEPKmmRNSt3__16vectorImNS_16secure_allocatorImEEEE:
  130|    292|BigInt& BigInt::rev_sub(const word y[], size_t y_sw, secure_vector<word>& ws) {
  131|    292|   if(this->sign() != BigInt::Positive) {
  ------------------
  |  Branch (131:7): [True: 0, False: 292]
  ------------------
  132|      0|      throw Invalid_State("BigInt::sub_rev requires this is positive");
  133|      0|   }
  134|       |
  135|    292|   const size_t x_sw = this->sig_words();
  136|       |
  137|    292|   ws.resize(std::max(x_sw, y_sw));
  138|    292|   clear_mem(ws.data(), ws.size());
  139|       |
  140|    292|   const int32_t relative_size = bigint_sub_abs(ws.data(), data(), x_sw, y, y_sw);
  141|       |
  142|    292|   this->cond_flip_sign(relative_size > 0);
  143|    292|   this->swap_reg(ws);
  144|       |
  145|    292|   return (*this);
  146|    292|}
_ZN5Botan6BigInt3mulERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  156|    584|BigInt& BigInt::mul(const BigInt& y, secure_vector<word>& ws) {
  157|    584|   const size_t x_sw = sig_words();
  158|    584|   const size_t y_sw = y.sig_words();
  159|    584|   set_sign((sign() == y.sign()) ? Positive : Negative);
  ------------------
  |  Branch (159:13): [True: 584, False: 0]
  ------------------
  160|       |
  161|    584|   if(x_sw == 0 || y_sw == 0) {
  ------------------
  |  Branch (161:7): [True: 435, False: 149]
  |  Branch (161:20): [True: 0, False: 149]
  ------------------
  162|    435|      clear();
  163|    435|      set_sign(Positive);
  164|    435|   } else if(x_sw == 1 && y_sw) {
  ------------------
  |  Branch (164:14): [True: 8, False: 141]
  |  Branch (164:27): [True: 8, False: 0]
  ------------------
  165|      8|      grow_to(y_sw + 1);
  166|      8|      bigint_linmul3(mutable_data(), y.data(), y_sw, word_at(0));
  167|    141|   } else if(y_sw == 1 && x_sw) {
  ------------------
  |  Branch (167:14): [True: 0, False: 141]
  |  Branch (167:27): [True: 0, False: 0]
  ------------------
  168|      0|      word carry = bigint_linmul2(mutable_data(), x_sw, y.word_at(0));
  169|      0|      set_word_at(x_sw, carry);
  170|    141|   } else {
  171|    141|      const size_t new_size = x_sw + y_sw + 1;
  172|    141|      ws.resize(new_size);
  173|    141|      secure_vector<word> z_reg(new_size);
  174|       |
  175|    141|      bigint_mul(z_reg.data(), z_reg.size(), data(), size(), x_sw, y.data(), y.size(), y_sw, ws.data(), ws.size());
  176|       |
  177|    141|      this->swap_reg(z_reg);
  178|    141|   }
  179|       |
  180|    584|   return (*this);
  181|    584|}
_ZN5Botan6BigIntmLEm:
  197|    513|BigInt& BigInt::operator*=(word y) {
  198|    513|   if(y == 0) {
  ------------------
  |  Branch (198:7): [True: 0, False: 513]
  ------------------
  199|      0|      clear();
  200|      0|      set_sign(Positive);
  201|      0|   }
  202|       |
  203|    513|   const word carry = bigint_linmul2(mutable_data(), size(), y);
  204|    513|   set_word_at(size(), carry);
  205|       |
  206|    513|   return (*this);
  207|    513|}
_ZN5Botan6BigIntrSEm:
  279|    584|BigInt& BigInt::operator>>=(size_t shift) {
  280|    584|   const size_t shift_words = shift / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|    584|#define BOTAN_MP_WORD_BITS 64
  ------------------
  281|    584|   const size_t shift_bits = shift % BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|    584|#define BOTAN_MP_WORD_BITS 64
  ------------------
  282|       |
  283|    584|   bigint_shr1(m_data.mutable_data(), m_data.size(), shift_words, shift_bits);
  284|       |
  285|    584|   if(is_negative() && is_zero()) {
  ------------------
  |  Branch (285:7): [True: 0, False: 584]
  |  Branch (285:24): [True: 0, False: 0]
  ------------------
  286|      0|      set_sign(Positive);
  287|      0|   }
  288|       |
  289|    584|   return (*this);
  290|    584|}

_ZN5BotanmlERKNS_6BigIntES2_:
   46|      1|BigInt operator*(const BigInt& x, const BigInt& y) {
   47|      1|   const size_t x_sw = x.sig_words();
   48|      1|   const size_t y_sw = y.sig_words();
   49|       |
   50|      1|   BigInt z = BigInt::with_capacity(x.size() + y.size());
   51|       |
   52|      1|   if(x_sw == 1 && y_sw) {
  ------------------
  |  Branch (52:7): [True: 0, False: 1]
  |  Branch (52:20): [True: 0, False: 0]
  ------------------
   53|      0|      bigint_linmul3(z.mutable_data(), y.data(), y_sw, x.word_at(0));
   54|      1|   } else if(y_sw == 1 && x_sw) {
  ------------------
  |  Branch (54:14): [True: 0, False: 1]
  |  Branch (54:27): [True: 0, False: 0]
  ------------------
   55|      0|      bigint_linmul3(z.mutable_data(), x.data(), x_sw, y.word_at(0));
   56|      1|   } else if(x_sw && y_sw) {
  ------------------
  |  Branch (56:14): [True: 1, False: 0]
  |  Branch (56:22): [True: 1, False: 0]
  ------------------
   57|      1|      secure_vector<word> workspace(z.size());
   58|       |
   59|      1|      bigint_mul(z.mutable_data(),
   60|      1|                 z.size(),
   61|      1|                 x.data(),
   62|      1|                 x.size(),
   63|      1|                 x_sw,
   64|      1|                 y.data(),
   65|      1|                 y.size(),
   66|      1|                 y_sw,
   67|      1|                 workspace.data(),
   68|      1|                 workspace.size());
   69|      1|   }
   70|       |
   71|      1|   z.cond_flip_sign(x_sw > 0 && y_sw > 0 && x.sign() != y.sign());
  ------------------
  |  Branch (71:21): [True: 1, False: 0]
  |  Branch (71:33): [True: 1, False: 0]
  |  Branch (71:45): [True: 0, False: 1]
  ------------------
   72|       |
   73|      1|   return z;
   74|      1|}

_ZN5Botan6BigInt13with_capacityEm:
   58|      4|BigInt BigInt::with_capacity(size_t size) {
   59|      4|   BigInt bn;
   60|      4|   bn.grow_to(size);
   61|      4|   return bn;
   62|      4|}
_ZN5Botan6BigIntC2ENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
   67|      1|BigInt::BigInt(std::string_view str) {
   68|      1|   Base base = Decimal;
   69|      1|   size_t markers = 0;
   70|      1|   bool negative = false;
   71|       |
   72|      1|   if(str.length() > 0 && str[0] == '-') {
  ------------------
  |  Branch (72:7): [True: 1, False: 0]
  |  Branch (72:27): [True: 0, False: 1]
  ------------------
   73|      0|      markers += 1;
   74|      0|      negative = true;
   75|      0|   }
   76|       |
   77|      1|   if(str.length() > markers + 2 && str[markers] == '0' && str[markers + 1] == 'x') {
  ------------------
  |  Branch (77:7): [True: 1, False: 0]
  |  Branch (77:37): [True: 1, False: 0]
  |  Branch (77:60): [True: 1, False: 0]
  ------------------
   78|      1|      markers += 2;
   79|      1|      base = Hexadecimal;
   80|      1|   }
   81|       |
   82|      1|   *this = decode(cast_char_ptr_to_uint8(str.data()) + markers, str.length() - markers, base);
   83|       |
   84|      1|   if(negative) {
  ------------------
  |  Branch (84:7): [True: 0, False: 1]
  ------------------
   85|      0|      set_sign(Negative);
   86|      1|   } else {
   87|      1|      set_sign(Positive);
   88|      1|   }
   89|      1|}
_ZN5Botan6BigIntC2EPKhm:
   91|    293|BigInt::BigInt(const uint8_t input[], size_t length) {
   92|    293|   binary_decode(input, length);
   93|    293|}
_ZNK5Botan6BigInt8cmp_wordEm:
  129|      2|int32_t BigInt::cmp_word(word other) const {
  130|      2|   if(is_negative()) {
  ------------------
  |  Branch (130:7): [True: 0, False: 2]
  ------------------
  131|      0|      return -1;  // other is positive ...
  132|      0|   }
  133|       |
  134|      2|   const size_t sw = this->sig_words();
  135|      2|   if(sw > 1) {
  ------------------
  |  Branch (135:7): [True: 2, False: 0]
  ------------------
  136|      2|      return 1;  // must be larger since other is just one word ...
  137|      2|   }
  138|       |
  139|      0|   return bigint_cmp(this->data(), sw, &other, 1);
  140|      2|}
_ZNK5Botan6BigInt8is_equalERKS0_:
  163|    292|bool BigInt::is_equal(const BigInt& other) const {
  164|    292|   if(this->sign() != other.sign()) {
  ------------------
  |  Branch (164:7): [True: 0, False: 292]
  ------------------
  165|      0|      return false;
  166|      0|   }
  167|       |
  168|    292|   return bigint_ct_is_eq(this->data(), this->sig_words(), other.data(), other.sig_words()).as_bool();
  169|    292|}
_ZNK5Botan6BigInt12is_less_thanERKS0_:
  171|    293|bool BigInt::is_less_than(const BigInt& other) const {
  172|    293|   if(this->is_negative() && other.is_positive()) {
  ------------------
  |  Branch (172:7): [True: 0, False: 293]
  |  Branch (172:30): [True: 0, False: 0]
  ------------------
  173|      0|      return true;
  174|      0|   }
  175|       |
  176|    293|   if(this->is_positive() && other.is_negative()) {
  ------------------
  |  Branch (176:7): [True: 293, False: 0]
  |  Branch (176:30): [True: 0, False: 293]
  ------------------
  177|      0|      return false;
  178|      0|   }
  179|       |
  180|    293|   if(other.is_negative() && this->is_negative()) {
  ------------------
  |  Branch (180:7): [True: 0, False: 293]
  |  Branch (180:30): [True: 0, False: 0]
  ------------------
  181|      0|      return bigint_ct_is_lt(other.data(), other.sig_words(), this->data(), this->sig_words()).as_bool();
  182|      0|   }
  183|       |
  184|    293|   return bigint_ct_is_lt(this->data(), this->sig_words(), other.data(), other.sig_words()).as_bool();
  185|    293|}
_ZNK5Botan6BigInt4Data14calc_sig_wordsEv:
  198|  2.34k|size_t BigInt::Data::calc_sig_words() const {
  199|  2.34k|   const size_t sz = m_reg.size();
  200|  2.34k|   size_t sig = sz;
  201|       |
  202|  2.34k|   word sub = 1;
  203|       |
  204|  19.3k|   for(size_t i = 0; i != sz; ++i) {
  ------------------
  |  Branch (204:22): [True: 16.9k, False: 2.34k]
  ------------------
  205|  16.9k|      const word w = m_reg[sz - i - 1];
  206|  16.9k|      sub &= ct_is_zero(w);
  207|  16.9k|      sig -= sub;
  208|  16.9k|   }
  209|       |
  210|       |   /*
  211|       |   * This depends on the data so is poisoned, but unpoison it here as
  212|       |   * later conditionals are made on the size.
  213|       |   */
  214|  2.34k|   CT::unpoison(sig);
  215|       |
  216|  2.34k|   return sig;
  217|  2.34k|}
_ZNK5Botan6BigInt13top_bits_freeEv:
  281|      1|size_t BigInt::top_bits_free() const {
  282|      1|   const size_t words = sig_words();
  283|       |
  284|      1|   const word top_word = word_at(words - 1);
  285|      1|   const size_t bits_used = high_bit(top_word);
  286|      1|   CT::unpoison(bits_used);
  287|      1|   return BOTAN_MP_WORD_BITS - bits_used;
  ------------------
  |  |   50|      1|#define BOTAN_MP_WORD_BITS 64
  ------------------
  288|      1|}
_ZNK5Botan6BigInt4bitsEv:
  290|      1|size_t BigInt::bits() const {
  291|      1|   const size_t words = sig_words();
  292|       |
  293|      1|   if(words == 0) {
  ------------------
  |  Branch (293:7): [True: 0, False: 1]
  ------------------
  294|      0|      return 0;
  295|      0|   }
  296|       |
  297|      1|   const size_t full_words = (words - 1) * BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|      1|#define BOTAN_MP_WORD_BITS 64
  ------------------
  298|      1|   const size_t top_bits = BOTAN_MP_WORD_BITS - top_bits_free();
  ------------------
  |  |   50|      1|#define BOTAN_MP_WORD_BITS 64
  ------------------
  299|       |
  300|      1|   return full_words + top_bits;
  301|      1|}
_ZN5Botan6BigInt15ct_reduce_belowERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEEm:
  344|    292|void BigInt::ct_reduce_below(const BigInt& mod, secure_vector<word>& ws, size_t bound) {
  345|    292|   if(mod.is_negative() || this->is_negative()) {
  ------------------
  |  Branch (345:7): [True: 0, False: 292]
  |  Branch (345:28): [True: 0, False: 292]
  ------------------
  346|      0|      throw Invalid_Argument("BigInt::ct_reduce_below both values must be positive");
  347|      0|   }
  348|       |
  349|    292|   const size_t mod_words = mod.sig_words();
  350|       |
  351|    292|   grow_to(mod_words);
  352|       |
  353|    292|   const size_t sz = size();
  354|       |
  355|    292|   ws.resize(sz);
  356|       |
  357|    292|   clear_mem(ws.data(), sz);
  358|       |
  359|    876|   for(size_t i = 0; i != bound; ++i) {
  ------------------
  |  Branch (359:22): [True: 584, False: 292]
  ------------------
  360|    584|      word borrow = bigint_sub3(ws.data(), data(), sz, mod.data(), mod_words);
  361|       |
  362|    584|      CT::Mask<word>::is_zero(borrow).select_n(mutable_data(), ws.data(), data(), sz);
  363|    584|   }
  364|    292|}
_ZN5Botan6BigInt13binary_decodeEPKhm:
  403|    294|void BigInt::binary_decode(const uint8_t buf[], size_t length) {
  404|    294|   clear();
  405|       |
  406|    294|   const size_t full_words = length / sizeof(word);
  407|    294|   const size_t extra_bytes = length % sizeof(word);
  408|       |
  409|    294|   secure_vector<word> reg((round_up(full_words + (extra_bytes > 0 ? 1 : 0), 8)));
  ------------------
  |  Branch (409:52): [True: 207, False: 87]
  ------------------
  410|       |
  411|    791|   for(size_t i = 0; i != full_words; ++i) {
  ------------------
  |  Branch (411:22): [True: 497, False: 294]
  ------------------
  412|    497|      reg[i] = load_be<word>(buf + length - sizeof(word) * (i + 1), 0);
  413|    497|   }
  414|       |
  415|    294|   if(extra_bytes > 0) {
  ------------------
  |  Branch (415:7): [True: 207, False: 87]
  ------------------
  416|    850|      for(size_t i = 0; i != extra_bytes; ++i) {
  ------------------
  |  Branch (416:25): [True: 643, False: 207]
  ------------------
  417|    643|         reg[full_words] = (reg[full_words] << 8) | buf[i];
  418|    643|      }
  419|    207|   }
  420|       |
  421|    294|   m_data.swap(reg);
  422|    294|}
_ZN5Botan6BigInt12ct_cond_swapEbRS0_:
  467|    513|void BigInt::ct_cond_swap(bool predicate, BigInt& other) {
  468|    513|   const size_t max_words = std::max(size(), other.size());
  469|    513|   grow_to(max_words);
  470|    513|   other.grow_to(max_words);
  471|       |
  472|    513|   bigint_cnd_swap(predicate, this->mutable_data(), other.mutable_data(), max_words);
  473|    513|}
_ZN5Botan6BigInt14cond_flip_signEb:
  475|    586|void BigInt::cond_flip_sign(bool predicate) {
  476|       |   // This code is assuming Negative == 0, Positive == 1
  477|       |
  478|    586|   const auto mask = CT::Mask<uint8_t>::expand(predicate);
  479|       |
  480|    586|   const uint8_t current_sign = static_cast<uint8_t>(sign());
  481|       |
  482|    586|   const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign);
  483|       |
  484|    586|   set_sign(static_cast<Sign>(new_sign));
  485|    586|}

_ZN5Botan9ct_divideERKNS_6BigIntES2_RS0_S3_:
   48|      1|void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) {
   49|      1|   if(y.is_zero()) {
  ------------------
  |  Branch (49:7): [True: 0, False: 1]
  ------------------
   50|      0|      throw Invalid_Argument("ct_divide: cannot divide by zero");
   51|      0|   }
   52|       |
   53|      1|   const size_t x_words = x.sig_words();
   54|      1|   const size_t y_words = y.sig_words();
   55|       |
   56|      1|   const size_t x_bits = x.bits();
   57|       |
   58|      1|   BigInt q = BigInt::with_capacity(x_words);
   59|      1|   BigInt r = BigInt::with_capacity(y_words);
   60|      1|   BigInt t = BigInt::with_capacity(y_words);  // a temporary
   61|       |
   62|    514|   for(size_t i = 0; i != x_bits; ++i) {
  ------------------
  |  Branch (62:22): [True: 513, False: 1]
  ------------------
   63|    513|      const size_t b = x_bits - 1 - i;
   64|    513|      const bool x_b = x.get_bit(b);
   65|       |
   66|    513|      r *= 2;
   67|    513|      r.conditionally_set_bit(0, x_b);
   68|       |
   69|    513|      const bool r_gte_y = bigint_sub3(t.mutable_data(), r.data(), r.size(), y.data(), y_words) == 0;
   70|       |
   71|    513|      q.conditionally_set_bit(b, r_gte_y);
   72|    513|      r.ct_cond_swap(r_gte_y, t);
   73|    513|   }
   74|       |
   75|      1|   sign_fixup(x, y, q, r);
   76|      1|   r_out = r;
   77|      1|   q_out = q;
   78|      1|}
divide.cpp:_ZN5Botan12_GLOBAL__N_110sign_fixupERKNS_6BigIntES3_RS1_S4_:
   21|      1|void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) {
   22|      1|   q.cond_flip_sign(x.sign() != y.sign());
   23|       |
   24|      1|   if(x.is_negative() && r.is_nonzero()) {
  ------------------
  |  Branch (24:7): [True: 0, False: 1]
  |  Branch (24:26): [True: 0, False: 0]
  ------------------
   25|      0|      q -= 1;
   26|      0|      r = y.abs() - r;
   27|      0|   }
   28|      1|}

_ZN5Botan17bigint_comba_mul4EPmPKmS2_:
   54|      9|void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) {
   55|      9|   word w2 = 0, w1 = 0, w0 = 0;
   56|       |
   57|      9|   word3_muladd(&w2, &w1, &w0, x[0], y[0]);
   58|      9|   z[0] = w0;
   59|      9|   w0 = 0;
   60|       |
   61|      9|   word3_muladd(&w0, &w2, &w1, x[0], y[1]);
   62|      9|   word3_muladd(&w0, &w2, &w1, x[1], y[0]);
   63|      9|   z[1] = w1;
   64|      9|   w1 = 0;
   65|       |
   66|      9|   word3_muladd(&w1, &w0, &w2, x[0], y[2]);
   67|      9|   word3_muladd(&w1, &w0, &w2, x[1], y[1]);
   68|      9|   word3_muladd(&w1, &w0, &w2, x[2], y[0]);
   69|      9|   z[2] = w2;
   70|      9|   w2 = 0;
   71|       |
   72|      9|   word3_muladd(&w2, &w1, &w0, x[0], y[3]);
   73|      9|   word3_muladd(&w2, &w1, &w0, x[1], y[2]);
   74|      9|   word3_muladd(&w2, &w1, &w0, x[2], y[1]);
   75|      9|   word3_muladd(&w2, &w1, &w0, x[3], y[0]);
   76|      9|   z[3] = w0;
   77|      9|   w0 = 0;
   78|       |
   79|      9|   word3_muladd(&w0, &w2, &w1, x[1], y[3]);
   80|      9|   word3_muladd(&w0, &w2, &w1, x[2], y[2]);
   81|      9|   word3_muladd(&w0, &w2, &w1, x[3], y[1]);
   82|      9|   z[4] = w1;
   83|      9|   w1 = 0;
   84|       |
   85|      9|   word3_muladd(&w1, &w0, &w2, x[2], y[3]);
   86|      9|   word3_muladd(&w1, &w0, &w2, x[3], y[2]);
   87|      9|   z[5] = w2;
   88|      9|   w2 = 0;
   89|       |
   90|      9|   word3_muladd(&w2, &w1, &w0, x[3], y[3]);
   91|      9|   z[6] = w0;
   92|      9|   z[7] = w1;
   93|      9|}

_ZN5Botan12basecase_mulEPmmPKmmS2_m:
   20|    133|void basecase_mul(word z[], size_t z_size, const word x[], size_t x_size, const word y[], size_t y_size) {
   21|    133|   if(z_size < x_size + y_size) {
  ------------------
  |  Branch (21:7): [True: 0, False: 133]
  ------------------
   22|      0|      throw Invalid_Argument("basecase_mul z_size too small");
   23|      0|   }
   24|       |
   25|    133|   const size_t x_size_8 = x_size - (x_size % 8);
   26|       |
   27|    133|   clear_mem(z, z_size);
   28|       |
   29|    736|   for(size_t i = 0; i != y_size; ++i) {
  ------------------
  |  Branch (29:22): [True: 603, False: 133]
  ------------------
   30|    603|      const word y_i = y[i];
   31|       |
   32|    603|      word carry = 0;
   33|       |
   34|    603|      for(size_t j = 0; j != x_size_8; j += 8) {
  ------------------
  |  Branch (34:25): [True: 0, False: 603]
  ------------------
   35|      0|         carry = word8_madd3(z + i + j, x + j, y_i, carry);
   36|      0|      }
   37|       |
   38|  2.20k|      for(size_t j = x_size_8; j != x_size; ++j) {
  ------------------
  |  Branch (38:32): [True: 1.60k, False: 603]
  ------------------
   39|  1.60k|         z[i + j] = word_madd3(x[j], y_i, z[i + j], &carry);
   40|  1.60k|      }
   41|       |
   42|    603|      z[x_size + i] = carry;
   43|    603|   }
   44|    133|}
_ZN5Botan10bigint_mulEPmmPKmmmS2_mmS0_m:
  291|    142|                size_t ws_size) {
  292|    142|   clear_mem(z, z_size);
  293|       |
  294|    142|   if(x_sw == 1) {
  ------------------
  |  Branch (294:7): [True: 0, False: 142]
  ------------------
  295|      0|      bigint_linmul3(z, y, y_sw, x[0]);
  296|    142|   } else if(y_sw == 1) {
  ------------------
  |  Branch (296:14): [True: 0, False: 142]
  ------------------
  297|      0|      bigint_linmul3(z, x, x_sw, y[0]);
  298|    142|   } else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (298:14): [True: 9, False: 133]
  ------------------
  299|      9|      bigint_comba_mul4(z, x, y);
  300|    133|   } else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (300:14): [True: 0, False: 133]
  ------------------
  301|      0|      bigint_comba_mul6(z, x, y);
  302|    133|   } else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (302:14): [True: 0, False: 133]
  ------------------
  303|      0|      bigint_comba_mul8(z, x, y);
  304|    133|   } else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (304:14): [True: 0, False: 133]
  ------------------
  305|      0|      bigint_comba_mul9(z, x, y);
  306|    133|   } else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (306:14): [True: 0, False: 133]
  ------------------
  307|      0|      bigint_comba_mul16(z, x, y);
  308|    133|   } else if(sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (308:14): [True: 0, False: 133]
  ------------------
  309|      0|      bigint_comba_mul24(z, x, y);
  310|    133|   } else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || y_sw < KARATSUBA_MULTIPLY_THRESHOLD || !workspace) {
  ------------------
  |  Branch (310:14): [True: 133, False: 0]
  |  Branch (310:53): [True: 0, False: 0]
  |  Branch (310:92): [True: 0, False: 0]
  ------------------
  311|    133|      basecase_mul(z, z_size, x, x_sw, y, y_sw);
  312|    133|   } else {
  313|      0|      const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw);
  314|       |
  315|      0|      if(N && z_size >= 2 * N && ws_size >= 2 * N) {
  ------------------
  |  Branch (315:10): [True: 0, False: 0]
  |  Branch (315:15): [True: 0, False: 0]
  |  Branch (315:34): [True: 0, False: 0]
  ------------------
  316|      0|         karatsuba_mul(z, x, y, N, workspace);
  317|      0|      } else {
  318|      0|         basecase_mul(z, z_size, x, x_sw, y, y_sw);
  319|      0|      }
  320|      0|   }
  321|    142|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm4EEEbmmmmm:
  271|    142|inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, size_t z_size) {
  272|    142|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 138, False: 4]
  |  Branch (272:26): [True: 138, False: 0]
  |  Branch (272:42): [True: 71, False: 67]
  |  Branch (272:56): [True: 71, False: 0]
  |  Branch (272:72): [True: 9, False: 62]
  ------------------
  273|    142|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm6EEEbmmmmm:
  271|    133|inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, size_t z_size) {
  272|    133|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 133, False: 0]
  |  Branch (272:26): [True: 133, False: 0]
  |  Branch (272:42): [True: 133, False: 0]
  |  Branch (272:56): [True: 133, False: 0]
  |  Branch (272:72): [True: 0, False: 133]
  ------------------
  273|    133|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm8EEEbmmmmm:
  271|    133|inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, size_t z_size) {
  272|    133|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 133, False: 0]
  |  Branch (272:26): [True: 133, False: 0]
  |  Branch (272:42): [True: 133, False: 0]
  |  Branch (272:56): [True: 133, False: 0]
  |  Branch (272:72): [True: 0, False: 133]
  ------------------
  273|    133|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm9EEEbmmmmm:
  271|    133|inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, size_t z_size) {
  272|    133|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 133, False: 0]
  |  Branch (272:26): [True: 61, False: 72]
  |  Branch (272:42): [True: 61, False: 0]
  |  Branch (272:56): [True: 0, False: 61]
  |  Branch (272:72): [True: 0, False: 0]
  ------------------
  273|    133|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm16EEEbmmmmm:
  271|    133|inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, size_t z_size) {
  272|    133|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 133, False: 0]
  |  Branch (272:26): [True: 0, False: 133]
  |  Branch (272:42): [True: 0, False: 0]
  |  Branch (272:56): [True: 0, False: 0]
  |  Branch (272:72): [True: 0, False: 0]
  ------------------
  273|    133|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm24EEEbmmmmm:
  271|    133|inline bool sized_for_comba_mul(size_t x_sw, size_t x_size, size_t y_sw, size_t y_size, size_t z_size) {
  272|    133|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 133, False: 0]
  |  Branch (272:26): [True: 0, False: 133]
  |  Branch (272:42): [True: 0, False: 0]
  |  Branch (272:56): [True: 0, False: 0]
  |  Branch (272:72): [True: 0, False: 0]
  ------------------
  273|    133|}

_ZN5Botan10prime_p256Ev:
  319|      1|const BigInt& prime_p256() {
  320|      1|   static const BigInt p256("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF");
  321|      1|   return p256;
  322|      1|}
_ZN5Botan9redc_p256ERNS_6BigIntERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  324|    292|void redc_p256(BigInt& x, secure_vector<word>& ws) {
  325|    292|   BOTAN_DEBUG_ASSERT(x.is_positive());
  ------------------
  |  |   99|    292|      do {                          \
  |  |  100|    292|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  326|       |
  327|    292|   static const size_t p256_limbs = (BOTAN_MP_WORD_BITS == 32) ? 8 : 4;
  ------------------
  |  |   50|    292|#define BOTAN_MP_WORD_BITS 64
  ------------------
  |  Branch (327:37): [Folded - Ignored]
  ------------------
  328|       |
  329|    292|   BOTAN_UNUSED(ws);
  ------------------
  |  |  118|    292|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
  330|       |
  331|    292|   x.grow_to(2 * p256_limbs);
  332|    292|   word* xw = x.mutable_data();
  333|       |
  334|    292|   const int64_t X00 = get_uint32(xw, 0);
  335|    292|   const int64_t X01 = get_uint32(xw, 1);
  336|    292|   const int64_t X02 = get_uint32(xw, 2);
  337|    292|   const int64_t X03 = get_uint32(xw, 3);
  338|    292|   const int64_t X04 = get_uint32(xw, 4);
  339|    292|   const int64_t X05 = get_uint32(xw, 5);
  340|    292|   const int64_t X06 = get_uint32(xw, 6);
  341|    292|   const int64_t X07 = get_uint32(xw, 7);
  342|    292|   const int64_t X08 = get_uint32(xw, 8);
  343|    292|   const int64_t X09 = get_uint32(xw, 9);
  344|    292|   const int64_t X10 = get_uint32(xw, 10);
  345|    292|   const int64_t X11 = get_uint32(xw, 11);
  346|    292|   const int64_t X12 = get_uint32(xw, 12);
  347|    292|   const int64_t X13 = get_uint32(xw, 13);
  348|    292|   const int64_t X14 = get_uint32(xw, 14);
  349|    292|   const int64_t X15 = get_uint32(xw, 15);
  350|       |
  351|       |   // Adds 6 * P-256 to prevent underflow
  352|    292|   const int64_t S0 = 0xFFFFFFFA + X00 + X08 + X09 - (X11 + X12 + X13) - X14;
  353|    292|   const int64_t S1 = 0xFFFFFFFF + X01 + X09 + X10 - X12 - (X13 + X14 + X15);
  354|    292|   const int64_t S2 = 0xFFFFFFFF + X02 + X10 + X11 - (X13 + X14 + X15);
  355|    292|   const int64_t S3 = 0x00000005 + X03 + (X11 + X12) * 2 + X13 - X15 - X08 - X09;
  356|    292|   const int64_t S4 = 0x00000000 + X04 + (X12 + X13) * 2 + X14 - X09 - X10;
  357|    292|   const int64_t S5 = 0x00000000 + X05 + (X13 + X14) * 2 + X15 - X10 - X11;
  358|    292|   const int64_t S6 = 0x00000006 + X06 + X13 + X14 * 3 + X15 * 2 - X08 - X09;
  359|    292|   const int64_t S7 = 0xFFFFFFFA + X07 + X15 * 3 + X08 - X10 - (X11 + X12 + X13);
  360|       |
  361|    292|   int64_t S = 0;
  362|       |
  363|    292|   uint32_t R0 = 0, R1 = 0;
  364|       |
  365|    292|   S += S0;
  366|    292|   R0 = static_cast<uint32_t>(S);
  367|    292|   S >>= 32;
  368|       |
  369|    292|   S += S1;
  370|    292|   R1 = static_cast<uint32_t>(S);
  371|    292|   S >>= 32;
  372|       |
  373|    292|   set_words(xw, 0, R0, R1);
  374|       |
  375|    292|   S += S2;
  376|    292|   R0 = static_cast<uint32_t>(S);
  377|    292|   S >>= 32;
  378|       |
  379|    292|   S += S3;
  380|    292|   R1 = static_cast<uint32_t>(S);
  381|    292|   S >>= 32;
  382|       |
  383|    292|   set_words(xw, 2, R0, R1);
  384|       |
  385|    292|   S += S4;
  386|    292|   R0 = static_cast<uint32_t>(S);
  387|    292|   S >>= 32;
  388|       |
  389|    292|   S += S5;
  390|    292|   R1 = static_cast<uint32_t>(S);
  391|    292|   S >>= 32;
  392|       |
  393|    292|   set_words(xw, 4, R0, R1);
  394|       |
  395|    292|   S += S6;
  396|    292|   R0 = static_cast<uint32_t>(S);
  397|    292|   S >>= 32;
  398|       |
  399|    292|   S += S7;
  400|    292|   R1 = static_cast<uint32_t>(S);
  401|    292|   S >>= 32;
  402|    292|   set_words(xw, 6, R0, R1);
  403|       |
  404|    292|   S += 5;  // the top digits of 6*P-256
  405|       |
  406|       |   /*
  407|       |   This is a table of (i*P-256) % 2**256 for i in 1...10
  408|       |   */
  409|    292|   static const word p256_mults[11][p256_limbs] = {
  410|    292|#if(BOTAN_MP_WORD_BITS == 64)
  411|    292|      {0xFFFFFFFFFFFFFFFF, 0x00000000FFFFFFFF, 0x0000000000000000, 0xFFFFFFFF00000001},
  412|    292|      {0xFFFFFFFFFFFFFFFE, 0x00000001FFFFFFFF, 0x0000000000000000, 0xFFFFFFFE00000002},
  413|    292|      {0xFFFFFFFFFFFFFFFD, 0x00000002FFFFFFFF, 0x0000000000000000, 0xFFFFFFFD00000003},
  414|    292|      {0xFFFFFFFFFFFFFFFC, 0x00000003FFFFFFFF, 0x0000000000000000, 0xFFFFFFFC00000004},
  415|    292|      {0xFFFFFFFFFFFFFFFB, 0x00000004FFFFFFFF, 0x0000000000000000, 0xFFFFFFFB00000005},
  416|    292|      {0xFFFFFFFFFFFFFFFA, 0x00000005FFFFFFFF, 0x0000000000000000, 0xFFFFFFFA00000006},
  417|    292|      {0xFFFFFFFFFFFFFFF9, 0x00000006FFFFFFFF, 0x0000000000000000, 0xFFFFFFF900000007},
  418|    292|      {0xFFFFFFFFFFFFFFF8, 0x00000007FFFFFFFF, 0x0000000000000000, 0xFFFFFFF800000008},
  419|    292|      {0xFFFFFFFFFFFFFFF7, 0x00000008FFFFFFFF, 0x0000000000000000, 0xFFFFFFF700000009},
  420|    292|      {0xFFFFFFFFFFFFFFF6, 0x00000009FFFFFFFF, 0x0000000000000000, 0xFFFFFFF60000000A},
  421|    292|      {0xFFFFFFFFFFFFFFF5, 0x0000000AFFFFFFFF, 0x0000000000000000, 0xFFFFFFF50000000B},
  422|       |#else
  423|       |      {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF},
  424|       |      {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE},
  425|       |      {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD},
  426|       |      {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC},
  427|       |      {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB},
  428|       |      {0xFFFFFFFA, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000005, 0x00000000, 0x00000000, 0x00000006, 0xFFFFFFFA},
  429|       |      {0xFFFFFFF9, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000006, 0x00000000, 0x00000000, 0x00000007, 0xFFFFFFF9},
  430|       |      {0xFFFFFFF8, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000007, 0x00000000, 0x00000000, 0x00000008, 0xFFFFFFF8},
  431|       |      {0xFFFFFFF7, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000008, 0x00000000, 0x00000000, 0x00000009, 0xFFFFFFF7},
  432|       |      {0xFFFFFFF6, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000009, 0x00000000, 0x00000000, 0x0000000A, 0xFFFFFFF6},
  433|       |      {0xFFFFFFF5, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000A, 0x00000000, 0x00000000, 0x0000000B, 0xFFFFFFF5},
  434|       |#endif
  435|    292|   };
  436|       |
  437|    292|   CT::unpoison(S);
  438|    292|   BOTAN_ASSERT(S >= 0 && S <= 10, "Expected overflow");
  ------------------
  |  |   51|    292|   do {                                                                                 \
  |  |   52|    584|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:12): [True: 292, False: 0]
  |  |  |  Branch (52:12): [True: 292, False: 0]
  |  |  ------------------
  |  |   53|    292|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|    292|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  439|       |
  440|    292|   BOTAN_ASSERT_NOMSG(x.size() >= p256_limbs + 1);
  ------------------
  |  |   60|    292|   do {                                                                     \
  |  |   61|    292|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 292]
  |  |  ------------------
  |  |   62|    292|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|    292|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  441|    292|   x.mask_bits(256);
  442|    292|   word borrow = bigint_sub2(x.mutable_data(), p256_limbs + 1, p256_mults[S], p256_limbs);
  443|    292|   BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1);
  ------------------
  |  |   99|    292|      do {                          \
  |  |  100|    292|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  444|    292|   bigint_cnd_add(borrow, x.mutable_data(), p256_limbs + 1, p256_mults[0], p256_limbs);
  445|    292|}
nistp_redc.cpp:_ZN5Botan12_GLOBAL__N_110get_uint32EPKmm:
  103|  4.67k|inline uint32_t get_uint32(const word xw[], size_t i) {
  104|       |#if(BOTAN_MP_WORD_BITS == 32)
  105|       |   return xw[i];
  106|       |#else
  107|  4.67k|   return static_cast<uint32_t>(xw[i / 2] >> ((i % 2) * 32));
  108|  4.67k|#endif
  109|  4.67k|}
nistp_redc.cpp:_ZN5Botan12_GLOBAL__N_19set_wordsEPmmjj:
  111|  1.16k|inline void set_words(word x[], size_t i, uint32_t R0, uint32_t R1) {
  112|       |#if(BOTAN_MP_WORD_BITS == 32)
  113|       |   x[i] = R0;
  114|       |   x[i + 1] = R1;
  115|       |#else
  116|  1.16k|   x[i / 2] = (static_cast<uint64_t>(R1) << 32) | R0;
  117|  1.16k|#endif
  118|  1.16k|}

_ZN5Botan15Modular_ReducerC2ERKNS_6BigIntE:
   19|      1|Modular_Reducer::Modular_Reducer(const BigInt& mod) {
   20|      1|   if(mod < 0) {
  ------------------
  |  Branch (20:7): [True: 0, False: 1]
  ------------------
   21|      0|      throw Invalid_Argument("Modular_Reducer: modulus must be positive");
   22|      0|   }
   23|       |
   24|       |   // Left uninitialized if mod == 0
   25|      1|   m_mod_words = 0;
   26|       |
   27|      1|   if(mod > 0) {
  ------------------
  |  Branch (27:7): [True: 1, False: 0]
  ------------------
   28|      1|      m_modulus = mod;
   29|      1|      m_mod_words = m_modulus.sig_words();
   30|       |
   31|       |      // Compute mu = floor(2^{2k} / m)
   32|      1|      m_mu.set_bit(2 * BOTAN_MP_WORD_BITS * m_mod_words);
  ------------------
  |  |   50|      1|#define BOTAN_MP_WORD_BITS 64
  ------------------
   33|      1|      m_mu = ct_divide(m_mu, m_modulus);
   34|      1|   }
   35|      1|}
_ZNK5Botan15Modular_Reducer6reduceERKNS_6BigIntE:
   37|    292|BigInt Modular_Reducer::reduce(const BigInt& x) const {
   38|    292|   BigInt r;
   39|    292|   secure_vector<word> ws;
   40|    292|   reduce(r, x, ws);
   41|    292|   return r;
   42|    292|}
_ZNK5Botan15Modular_Reducer6reduceERNS_6BigIntERKS1_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
   69|    292|void Modular_Reducer::reduce(BigInt& t1, const BigInt& x, secure_vector<word>& ws) const {
   70|    292|   if(&t1 == &x) {
  ------------------
  |  Branch (70:7): [True: 0, False: 292]
  ------------------
   71|      0|      throw Invalid_State("Modular_Reducer arguments cannot alias");
   72|      0|   }
   73|    292|   if(m_mod_words == 0) {
  ------------------
  |  Branch (73:7): [True: 0, False: 292]
  ------------------
   74|      0|      throw Invalid_State("Modular_Reducer: Never initalized");
   75|      0|   }
   76|       |
   77|    292|   const size_t x_sw = x.sig_words();
   78|       |
   79|    292|   if(x_sw > 2 * m_mod_words) {
  ------------------
  |  Branch (79:7): [True: 0, False: 292]
  ------------------
   80|       |      // too big, fall back to slow boat division
   81|      0|      t1 = ct_modulo(x, m_modulus);
   82|      0|      return;
   83|      0|   }
   84|       |
   85|    292|   t1 = x;
   86|    292|   t1.set_sign(BigInt::Positive);
   87|    292|   t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words - 1));
  ------------------
  |  |   50|    292|#define BOTAN_MP_WORD_BITS 64
  ------------------
   88|       |
   89|    292|   t1.mul(m_mu, ws);
   90|    292|   t1 >>= (BOTAN_MP_WORD_BITS * (m_mod_words + 1));
  ------------------
  |  |   50|    292|#define BOTAN_MP_WORD_BITS 64
  ------------------
   91|       |
   92|       |   // TODO add masked mul to avoid computing high bits
   93|    292|   t1.mul(m_modulus, ws);
   94|    292|   t1.mask_bits(BOTAN_MP_WORD_BITS * (m_mod_words + 1));
  ------------------
  |  |   50|    292|#define BOTAN_MP_WORD_BITS 64
  ------------------
   95|       |
   96|    292|   t1.rev_sub(x.data(), std::min(x_sw, m_mod_words + 1), ws);
   97|       |
   98|       |   /*
   99|       |   * If t1 < 0 then we must add b^(k+1) where b = 2^w. To avoid a
  100|       |   * side channel perform the addition unconditionally, with ws set
  101|       |   * to either b^(k+1) or else 0.
  102|       |   */
  103|    292|   const word t1_neg = t1.is_negative();
  104|       |
  105|    292|   if(ws.size() < m_mod_words + 2) {
  ------------------
  |  Branch (105:7): [True: 0, False: 292]
  ------------------
  106|      0|      ws.resize(m_mod_words + 2);
  107|      0|   }
  108|    292|   clear_mem(ws.data(), ws.size());
  109|    292|   ws[m_mod_words + 1] = t1_neg;
  110|       |
  111|    292|   t1.add(ws.data(), m_mod_words + 2, BigInt::Positive);
  112|       |
  113|       |   // Per HAC this step requires at most 2 subtractions
  114|    292|   t1.ct_reduce_below(m_modulus, ws, 2);
  115|       |
  116|    292|   cnd_rev_sub(t1.is_nonzero() && x.is_negative(), t1, m_modulus.data(), m_modulus.size(), ws);
  ------------------
  |  Branch (116:16): [True: 290, False: 2]
  |  Branch (116:35): [True: 0, False: 290]
  ------------------
  117|    292|}
reducer.cpp:_ZN5Botan12_GLOBAL__N_111cnd_rev_subEbRNS_6BigIntEPKmmRNSt3__16vectorImNS_16secure_allocatorImEEEE:
   49|    292|void cnd_rev_sub(bool cnd, BigInt& x, const word y[], size_t y_sw, secure_vector<word>& ws) {
   50|    292|   if(x.sign() != BigInt::Positive) {
  ------------------
  |  Branch (50:7): [True: 0, False: 292]
  ------------------
   51|      0|      throw Invalid_State("BigInt::sub_rev requires this is positive");
   52|      0|   }
   53|       |
   54|    292|   const size_t x_sw = x.sig_words();
   55|       |
   56|    292|   const size_t max_words = std::max(x_sw, y_sw);
   57|    292|   ws.resize(std::max(x_sw, y_sw));
   58|    292|   clear_mem(ws.data(), ws.size());
   59|    292|   x.grow_to(max_words);
   60|       |
   61|    292|   const int32_t relative_size = bigint_sub_abs(ws.data(), x.data(), x_sw, y, y_sw);
   62|       |
   63|    292|   x.cond_flip_sign((relative_size > 0) && cnd);
  ------------------
  |  Branch (63:21): [True: 0, False: 292]
  |  Branch (63:44): [True: 0, False: 0]
  ------------------
   64|    292|   bigint_cnd_swap(cnd, x.mutable_data(), ws.data(), max_words);
   65|    292|}

_ZN5Botan15allocate_memoryEmm:
   20|  1.31k|BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size) {
   21|  1.31k|   if(elems == 0 || elem_size == 0) {
  ------------------
  |  Branch (21:7): [True: 0, False: 1.31k]
  |  Branch (21:21): [True: 0, False: 1.31k]
  ------------------
   22|      0|      return nullptr;
   23|      0|   }
   24|       |
   25|       |   // Some calloc implementations do not check for overflow (?!?)
   26|       |
   27|  1.31k|   if(!BOTAN_CHECKED_MUL(elems, elem_size).has_value()) {
  ------------------
  |  |   74|  1.31k|#define BOTAN_CHECKED_MUL(x, y) checked_mul(x, y)
  ------------------
  |  Branch (27:7): [True: 0, False: 1.31k]
  ------------------
   28|      0|      throw std::bad_alloc();
   29|      0|   }
   30|       |
   31|       |#if defined(BOTAN_HAS_LOCKING_ALLOCATOR)
   32|       |   if(void* p = mlock_allocator::instance().allocate(elems, elem_size)) {
   33|       |      return p;
   34|       |   }
   35|       |#endif
   36|       |
   37|       |#if defined(BOTAN_TARGET_OS_HAS_ALLOC_CONCEAL)
   38|       |   void* ptr = ::calloc_conceal(elems, elem_size);
   39|       |#else
   40|  1.31k|   void* ptr = std::calloc(elems, elem_size);  // NOLINT(*-no-malloc)
   41|  1.31k|#endif
   42|  1.31k|   if(!ptr) {
  ------------------
  |  Branch (42:7): [True: 0, False: 1.31k]
  ------------------
   43|      0|      [[unlikely]] throw std::bad_alloc();
   44|      0|   }
   45|  1.31k|   return ptr;
   46|  1.31k|}
_ZN5Botan17deallocate_memoryEPvmm:
   48|  1.31k|void deallocate_memory(void* p, size_t elems, size_t elem_size) {
   49|  1.31k|   if(p == nullptr) {
  ------------------
  |  Branch (49:7): [True: 0, False: 1.31k]
  ------------------
   50|      0|      [[unlikely]] return;
   51|      0|   }
   52|       |
   53|  1.31k|   secure_scrub_memory(p, elems * elem_size);
   54|       |
   55|       |#if defined(BOTAN_HAS_LOCKING_ALLOCATOR)
   56|       |   if(mlock_allocator::instance().deallocate(p, elems, elem_size)) {
   57|       |      return;
   58|       |   }
   59|       |#endif
   60|       |
   61|  1.31k|   std::free(p);  // NOLINT(*-no-malloc)
   62|  1.31k|}

_ZN5Botan19secure_scrub_memoryEPvm:
   87|  1.31k|void secure_scrub_memory(void* ptr, size_t n) {
   88|       |#if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY)
   89|       |   ::RtlSecureZeroMemory(ptr, n);
   90|       |
   91|       |#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO)
   92|  1.31k|   ::explicit_bzero(ptr, n);
   93|       |
   94|       |#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_MEMSET)
   95|       |   (void)::explicit_memset(ptr, 0, n);
   96|       |
   97|       |#elif defined(BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO) && (BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO == 1)
   98|       |   /*
   99|       |   Call memset through a static volatile pointer, which the compiler
  100|       |   should not elide. This construct should be safe in conforming
  101|       |   compilers, but who knows. I did confirm that on x86-64 GCC 6.1 and
  102|       |   Clang 3.8 both create code that saves the memset address in the
  103|       |   data segment and unconditionally loads and jumps to that address.
  104|       |   */
  105|       |   static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset;
  106|       |   (memset_ptr)(ptr, 0, n);
  107|       |#else
  108|       |
  109|       |   volatile uint8_t* p = reinterpret_cast<volatile uint8_t*>(ptr);
  110|       |
  111|       |   for(size_t i = 0; i != n; ++i)
  112|       |      p[i] = 0;
  113|       |#endif
  114|  1.31k|}

