_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EED2Ev:
   65|      1|      ~AlignmentBuffer() { secure_scrub_memory(m_buffer.data(), m_buffer.size()); }
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EEC2Ev:
   63|      1|      AlignmentBuffer() : m_position(0) {}
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE5clearEv:
   72|      7|      void clear() {
   73|      7|         clear_mem(m_buffer.data(), m_buffer.size());
   74|      7|         m_position = 0;
   75|      7|      }
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE21handle_unaligned_dataERNS_12BufferSlicerE:
  167|      9|      [[nodiscard]] std::optional<std::span<const T>> handle_unaligned_data(BufferSlicer& slicer) {
  168|       |         // When the final block is to be deferred, we would need to store and
  169|       |         // hold a buffer that contains exactly one block until more data is
  170|       |         // passed or it is explicitly consumed.
  171|      9|         const size_t defer = (defers_final_block()) ? 1 : 0;
  ------------------
  |  Branch (171:31): [True: 0, False: 9]
  ------------------
  172|       |
  173|      9|         if(in_alignment() && slicer.remaining() >= m_buffer.size() + defer) {
  ------------------
  |  Branch (173:13): [True: 9, False: 0]
  |  Branch (173:31): [True: 6, False: 3]
  ------------------
  174|       |            // We are currently in alignment and the passed-in data source
  175|       |            // contains enough data to benefit from aligned processing.
  176|       |            // Therefore, we don't copy anything into the intermittent buffer.
  177|      6|            return std::nullopt;
  178|      6|         }
  179|       |
  180|       |         // Fill the buffer with as much input data as needed to reach alignment
  181|       |         // or until the input source is depleted.
  182|      3|         const auto elements_to_consume = std::min(m_buffer.size() - m_position, slicer.remaining());
  183|      3|         append(slicer.take(elements_to_consume));
  184|       |
  185|       |         // If we collected enough data, we push out one full block. When
  186|       |         // deferring the final block is enabled, we additionally check that
  187|       |         // more input data is available to continue processing a consecutive
  188|       |         // block.
  189|      3|         if(ready_to_consume() && (!defers_final_block() || !slicer.empty())) {
  ------------------
  |  Branch (189:13): [True: 0, False: 3]
  |  Branch (189:36): [True: 0, False: 0]
  |  Branch (189:61): [True: 0, False: 0]
  ------------------
  190|      0|            return consume();
  191|      3|         } else {
  192|      3|            return std::nullopt;
  193|      3|         }
  194|      3|      }
_ZNK5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE18defers_final_blockEv:
  234|     15|      constexpr bool defers_final_block() const {
  235|     15|         return FINAL_BLOCK_STRATEGY == AlignmentBufferFinalBlock::must_be_deferred;
  236|     15|      }
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE6appendENSt3__14spanIKhLm18446744073709551615EEE:
   91|      7|      void append(std::span<const T> elements) {
   92|      7|         BOTAN_ASSERT_NOMSG(elements.size() <= elements_until_alignment());
  ------------------
  |  |   60|      7|   do {                                                                     \
  |  |   61|      7|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 7]
  |  |  ------------------
  |  |   62|      7|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      7|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   93|      7|         std::copy(elements.begin(), elements.end(), m_buffer.begin() + m_position);
   94|      7|         m_position += elements.size();
   95|      7|      }
_ZNK5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE24elements_until_alignmentEv:
  222|     19|      size_t elements_until_alignment() const { return m_buffer.size() - m_position; }
_ZNK5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE16ready_to_consumeEv:
  232|     15|      bool ready_to_consume() const { return m_position == m_buffer.size(); }
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE7consumeEv:
  201|      4|      [[nodiscard]] std::span<const T> consume() {
  202|      4|         BOTAN_ASSERT_NOMSG(ready_to_consume());
  ------------------
  |  |   60|      4|   do {                                                                     \
  |  |   61|      4|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 4]
  |  |  ------------------
  |  |   62|      4|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      4|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  203|      4|         m_position = 0;
  204|      4|         return m_buffer;
  205|      4|      }
_ZNK5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE12in_alignmentEv:
  227|     24|      bool in_alignment() const { return m_position == 0; }
_ZNK5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE23aligned_data_to_processERNS_12BufferSlicerE:
  127|      6|      [[nodiscard]] std::tuple<std::span<const uint8_t>, size_t> aligned_data_to_process(BufferSlicer& slicer) const {
  128|      6|         BOTAN_ASSERT_NOMSG(in_alignment());
  ------------------
  |  |   60|      6|   do {                                                                     \
  |  |   61|      6|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 6]
  |  |  ------------------
  |  |   62|      6|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      6|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  129|       |
  130|       |         // When the final block is to be deferred, the last block must not be
  131|       |         // selected for processing if there is no (unaligned) extra input data.
  132|      6|         const size_t defer = (defers_final_block()) ? 1 : 0;
  ------------------
  |  Branch (132:31): [True: 0, False: 6]
  ------------------
  133|      6|         const size_t full_blocks_to_process = (slicer.remaining() - defer) / m_buffer.size();
  134|      6|         return {slicer.take(full_blocks_to_process * m_buffer.size()), full_blocks_to_process};
  135|      6|      }
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE18fill_up_with_zerosEv:
   80|      4|      void fill_up_with_zeros() {
   81|      4|         if(!ready_to_consume()) {
  ------------------
  |  Branch (81:13): [True: 4, False: 0]
  ------------------
   82|      4|            clear_mem(&m_buffer[m_position], elements_until_alignment());
   83|      4|            m_position = m_buffer.size();
   84|      4|         }
   85|      4|      }
_ZN5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE20directly_modify_lastEm:
  114|      4|      std::span<T> directly_modify_last(size_t elements) {
  115|      4|         BOTAN_ASSERT_NOMSG(size() >= elements);
  ------------------
  |  |   60|      4|   do {                                                                     \
  |  |   61|      4|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 4]
  |  |  ------------------
  |  |   62|      4|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      4|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  116|      4|         return std::span(m_buffer).last(elements);
  117|      4|      }
_ZNK5Botan15AlignmentBufferIhLm64ELNS_25AlignmentBufferFinalBlockE0EE4sizeEv:
  218|      4|      constexpr size_t size() const { return m_buffer.size(); }

_ZN5Botan14expand_top_bitImEET_S1_:
   25|  8.50M|{
   26|  8.50M|   return static_cast<T>(0) - (a >> (sizeof(T) * 8 - 1));
   27|  8.50M|}
_ZN5Botan10ct_is_zeroImEET_S1_:
   35|  6.71M|{
   36|  6.71M|   return expand_top_bit<T>(~x & (x - 1));
   37|  6.71M|}
_ZN5Botan8high_bitImEEmT_:
   60|  48.1k|{
   61|  48.1k|   size_t hb = 0;
   62|       |
   63|   337k|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (63:38): [True: 289k, False: 48.1k]
  ------------------
   64|   289k|      const size_t z = s * ((~ct_is_zero(n >> s)) & 1);
   65|   289k|      hb += z;
   66|   289k|      n >>= z;
   67|   289k|   }
   68|       |
   69|  48.1k|   hb += n;
   70|       |
   71|  48.1k|   return hb;
   72|  48.1k|}
_ZN5Botan6chooseImEET_S1_S1_S1_:
  180|  8.73M|inline constexpr T choose(T mask, T a, T b) {
  181|       |   //return (mask & a) | (~mask & b);
  182|  8.73M|   return (b ^ (mask & (a ^ b)));
  183|  8.73M|}
_ZN5Botan10ct_is_zeroIhEET_S1_:
   35|  20.9k|{
   36|  20.9k|   return expand_top_bit<T>(~x & (x - 1));
   37|  20.9k|}
_ZN5Botan14expand_top_bitIhEET_S1_:
   25|  20.9k|{
   26|  20.9k|   return static_cast<T>(0) - (a >> (sizeof(T) * 8 - 1));
   27|  20.9k|}
_ZN5Botan6chooseIhEET_S1_S1_S1_:
  180|  20.9k|inline constexpr T choose(T mask, T a, T b) {
  181|       |   //return (mask & a) | (~mask & b);
  182|  20.9k|   return (b ^ (mask & (a ^ b)));
  183|  20.9k|}
_ZN5Botan3ctzImEEmT_:
  104|   196k|{
  105|       |   /*
  106|       |   * If n == 0 then this function will compute 8*sizeof(T)-1, so
  107|       |   * initialize lb to 1 if n == 0 to produce the expected result.
  108|       |   */
  109|   196k|   size_t lb = ct_is_zero(n) & 1;
  110|       |
  111|  1.37M|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (111:38): [True: 1.18M, False: 196k]
  ------------------
  112|  1.18M|      const T mask = (static_cast<T>(1) << s) - 1;
  113|  1.18M|      const size_t z = s * (ct_is_zero(n & mask) & 1);
  114|  1.18M|      lb += z;
  115|  1.18M|      n >>= z;
  116|  1.18M|   }
  117|       |
  118|   196k|   return lb;
  119|   196k|}
_ZN5Botan6chooseIjEET_S1_S1_S1_:
  180|  1.28k|inline constexpr T choose(T mask, T a, T b) {
  181|       |   //return (mask & a) | (~mask & b);
  182|  1.28k|   return (b ^ (mask & (a ^ b)));
  183|  1.28k|}
_ZN5Botan8majorityIjEET_S1_S1_S1_:
  186|    640|inline constexpr T majority(T a, T b, T c) {
  187|       |   /*
  188|       |   Considering each bit of a, b, c individually
  189|       |
  190|       |   If a xor b is set, then c is the deciding vote.
  191|       |
  192|       |   If a xor b is not set then either a and b are both set or both unset.
  193|       |   In either case the value of c doesn't matter, and examining b (or a)
  194|       |   allows us to determine which case we are in.
  195|       |   */
  196|    640|   return choose(a ^ b, c, b);
  197|    640|}
_ZN5Botan13is_power_of_2ImEEbT_:
   47|  71.8k|{
   48|  71.8k|   return (arg != 0) && (arg != 1) && ((arg & static_cast<T>(arg - 1)) == 0);
  ------------------
  |  Branch (48:11): [True: 71.8k, False: 0]
  |  Branch (48:25): [True: 71.8k, False: 0]
  |  Branch (48:39): [True: 55.4k, False: 16.4k]
  ------------------
   49|  71.8k|}

_ZN5Botan13reverse_bytesEm:
   48|  1.19k|inline constexpr uint64_t reverse_bytes(uint64_t x) {
   49|  1.19k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_bswap64)
   50|  1.19k|   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|  1.19k|}
_ZN5Botan13reverse_bytesEj:
   33|    192|inline constexpr uint32_t reverse_bytes(uint32_t x) {
   34|    192|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_bswap32)
   35|    192|   return __builtin_bswap32(x);
   36|       |#else
   37|       |   // MSVC at least recognizes this as a bswap
   38|       |   return ((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | ((x & 0x00FF0000) >> 8) | ((x & 0xFF000000) >> 24);
   39|       |#endif
   40|    192|}

_ZN5Botan5CPUID13has_cpuid_bitENS0_10CPUID_bitsE:
  333|     49|      static bool has_cpuid_bit(CPUID_bits elem) {
  334|     49|         const uint32_t elem32 = static_cast<uint32_t>(elem);
  335|     49|         return state().has_bit(elem32);
  336|     49|      }
_ZN5Botan5CPUID5stateEv:
  362|     49|      static CPUID_Data& state() {
  363|     49|         static CPUID::CPUID_Data g_cpuid;
  364|     49|         return g_cpuid;
  365|     49|      }
_ZNK5Botan5CPUID10CPUID_Data7has_bitEj:
  350|     49|            bool has_bit(uint32_t bit) const { return (m_processor_features & bit) == bit; }
_ZN5Botan5CPUID8has_sse2Ev:
  208|     15|      static bool has_sse2() { return has_cpuid_bit(CPUID_SSE2_BIT); }
_ZN5Botan5CPUID8has_avx2Ev:
  218|      7|      static bool has_avx2() { return has_cpuid_bit(CPUID_AVX2_BIT); }
_ZN5Botan5CPUID10has_avx512Ev:
  225|      7|      static bool has_avx512() { return has_cpuid_bit(CPUID_AVX512_BIT); }
_ZN5Botan5CPUID8has_bmi2Ev:
  240|     10|      static bool has_bmi2() { return has_cpuid_bit(CPUID_BMI_BIT); }
_ZN5Botan5CPUID13has_intel_shaEv:
  255|     10|      static bool has_intel_sha() { return has_sse2() && has_cpuid_bit(CPUID_SHA_BIT); }
  ------------------
  |  Branch (255:44): [True: 10, False: 0]
  |  Branch (255:58): [True: 0, False: 10]
  ------------------

_ZN5Botan2CT4MaskImE8is_equalEmm:
  128|   532k|      static Mask<T> is_equal(T x, T y) { return Mask<T>::is_zero(static_cast<T>(x ^ y)); }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  133|  1.79M|      static Mask<T> is_lt(T x, T y) { return Mask<T>(expand_top_bit<T>(x ^ ((x ^ y) | ((x - y) ^ x)))); }
_ZN5Botan2CT4MaskImEC2Em:
  280|  11.4M|      Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskImE11select_maskES2_S2_:
  239|   124k|      Mask<T> select_mask(Mask<T> x, Mask<T> y) const { return Mask<T>(select(x.value(), y.value())); }
_ZNK5Botan2CT4MaskImE5valueEv:
  277|  19.0M|      T value() const { return m_mask; }
_ZN5Botan2CT4MaskImEoRES2_:
  190|   201k|      Mask<T>& operator|=(Mask<T> o) {
  191|   201k|         m_mask |= o.value();
  192|   201k|         return (*this);
  193|   201k|      }
_ZN5Botan2CT4MaskImEaNES2_:
  174|   514k|      Mask<T>& operator&=(Mask<T> o) {
  175|   514k|         m_mask &= o.value();
  176|   514k|         return (*this);
  177|   514k|      }
_ZNK5Botan2CT4MaskImE13if_set_returnEm:
  218|   737k|      T if_set_return(T x) const { return m_mask & x; }
_ZN5Botan2CT4MaskImE6expandEm:
  109|  2.80M|      static Mask<T> expand(T v) { return ~Mask<T>::is_zero(v); }
_ZNK5Botan2CT4MaskImEcoEv:
  213|  4.62M|      Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskImE6selectEmm:
  228|  8.73M|      T select(T x, T y) const { return choose(value(), x, y); }
_ZNK5Botan2CT4MaskImE8select_nEPmPKmS5_m:
  245|   242k|      void select_n(T output[], const T x[], const T y[], size_t len) const {
  246|  1.24M|         for(size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (246:28): [True: 1.00M, False: 242k]
  ------------------
  247|  1.00M|            output[i] = this->select(x[i], y[i]);
  248|  1.00M|         }
  249|   242k|      }
_ZN5Botan2CT4MaskImE7is_zeroEm:
  123|  3.35M|      static Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(x)); }
_ZN5Botan2CT8unpoisonImEEvRT_:
   64|  1.88M|inline void unpoison(T& p) {
   65|       |#if defined(BOTAN_HAS_VALGRIND)
   66|       |   VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T));
   67|       |#else
   68|  1.88M|   BOTAN_UNUSED(p);
  ------------------
  |  |  118|  1.88M|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   69|  1.88M|#endif
   70|  1.88M|}
_ZNK5Botan2CT4MaskImE7as_boolEv:
  272|  1.63M|      bool as_bool() const { return unpoisoned_value() != 0; }
_ZNK5Botan2CT4MaskImE16unpoisoned_valueEv:
  263|  1.63M|      T unpoisoned_value() const {
  264|  1.63M|         T r = value();
  265|  1.63M|         CT::unpoison(r);
  266|  1.63M|         return r;
  267|  1.63M|      }
_ZN5Botan2CT8unpoisonIKmEEvRT_:
   64|  48.1k|inline void unpoison(T& p) {
   65|       |#if defined(BOTAN_HAS_VALGRIND)
   66|       |   VALGRIND_MAKE_MEM_DEFINED(&p, sizeof(T));
   67|       |#else
   68|  48.1k|   BOTAN_UNUSED(p);
  ------------------
  |  |  118|  48.1k|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   69|  48.1k|#endif
   70|  48.1k|}
_ZN5Botan2CT4MaskIhE6expandEh:
  109|  20.9k|      static Mask<T> expand(T v) { return ~Mask<T>::is_zero(v); }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  123|  20.9k|      static Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(x)); }
_ZN5Botan2CT4MaskIhEC2Eh:
  280|  41.8k|      Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhEcoEv:
  213|  20.9k|      Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskIhE5valueEv:
  277|  41.8k|      T value() const { return m_mask; }
_ZNK5Botan2CT4MaskIhE6selectEhh:
  228|  20.9k|      T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT20conditional_swap_ptrIPKmEEvbRT_S5_:
  315|  21.7k|inline void conditional_swap_ptr(bool cnd, T& x, T& y) {
  316|  21.7k|   uintptr_t xp = reinterpret_cast<uintptr_t>(x);
  317|  21.7k|   uintptr_t yp = reinterpret_cast<uintptr_t>(y);
  318|       |
  319|  21.7k|   conditional_swap<uintptr_t>(cnd, xp, yp);
  320|       |
  321|  21.7k|   x = reinterpret_cast<T>(xp);
  322|  21.7k|   y = reinterpret_cast<T>(yp);
  323|  21.7k|}
_ZN5Botan2CT16conditional_swapImEEvbRT_S3_:
  305|  43.4k|inline void conditional_swap(bool cnd, T& x, T& y) {
  306|  43.4k|   const auto swap = CT::Mask<T>::expand(cnd);
  307|       |
  308|  43.4k|   T t0 = swap.select(y, x);
  309|  43.4k|   T t1 = swap.select(x, y);
  310|  43.4k|   x = t0;
  311|  43.4k|   y = t1;
  312|  43.4k|}
_ZN5Botan2CT4MaskImE3setEv:
   99|    999|      static Mask<T> set() { return Mask<T>(static_cast<T>(~0)); }
_ZN5Botan2CT4MaskImE7clearedEv:
  104|  24.6k|      static Mask<T> cleared() { return Mask<T>(0); }
_ZNK5Botan2CT4MaskImE17if_not_set_returnEm:
  223|   196k|      T if_not_set_return(T x) const { return ~m_mask & x; }
_ZN5Botan2CT4MaskImE6is_gteEmm:
  148|  1.56M|      static Mask<T> is_gte(T x, T y) { return ~Mask<T>::is_lt(x, y); }
_ZN5Botan2CTorENS0_4MaskImEES2_:
  208|  1.56M|      friend Mask<T> operator|(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() | y.value()); }
_ZN5Botan2CT4MaskImE6is_lteEmm:
  143|    128|      static Mask<T> is_lte(T x, T y) { return ~Mask<T>::is_gt(x, y); }
_ZN5Botan2CT4MaskImE5is_gtEmm:
  138|    128|      static Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT22conditional_assign_memImEENS0_4MaskIT_EES3_PS3_PKS3_m:
  298|   231k|inline Mask<T> conditional_assign_mem(T cnd, T* sink, const T* src, size_t elems) {
  299|   231k|   const auto mask = CT::Mask<T>::expand(cnd);
  300|   231k|   mask.select_n(sink, src, sink, elems);
  301|   231k|   return mask;
  302|   231k|}

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

_ZN5Botan10fmt_detail6do_fmtERNSt3__119basic_ostringstreamIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_17basic_string_viewIcS4_EE:
   20|      1|inline void do_fmt(std::ostringstream& oss, std::string_view format) {
   21|      1|   oss << format;
   22|      1|}
_ZN5Botan3fmtIJPKcS2_S2_EEENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS3_17basic_string_viewIcS6_EEDpRKT_:
   53|      1|std::string fmt(std::string_view format, const T&... args) {
   54|      1|   std::ostringstream oss;
   55|      1|   oss.imbue(std::locale::classic());
   56|      1|   fmt_detail::do_fmt(oss, format, args...);
   57|      1|   return oss.str();
   58|      1|}
_ZN5Botan10fmt_detail6do_fmtIPKcJS3_S3_EEEvRNSt3__119basic_ostringstreamIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS4_17basic_string_viewIcS7_EERKT_DpRKT0_:
   25|      1|void do_fmt(std::ostringstream& oss, std::string_view format, const T& val, const Ts&... rest) {
   26|      1|   size_t i = 0;
   27|       |
   28|      1|   while(i < format.size()) {
  ------------------
  |  Branch (28:10): [True: 1, False: 0]
  ------------------
   29|      1|      if(format[i] == '{' && (format.size() > (i + 1)) && format.at(i + 1) == '}') {
  ------------------
  |  Branch (29:10): [True: 1, False: 0]
  |  Branch (29:30): [True: 1, False: 0]
  |  Branch (29:59): [True: 1, False: 0]
  ------------------
   30|      1|         oss << val;
   31|      1|         return do_fmt(oss, format.substr(i + 2), rest...);
   32|      1|      } else {
   33|      0|         oss << format[i];
   34|      0|      }
   35|       |
   36|      0|      i += 1;
   37|      0|   }
   38|      1|}
_ZN5Botan10fmt_detail6do_fmtIPKcJS3_EEEvRNSt3__119basic_ostringstreamIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS4_17basic_string_viewIcS7_EERKT_DpRKT0_:
   25|      1|void do_fmt(std::ostringstream& oss, std::string_view format, const T& val, const Ts&... rest) {
   26|      1|   size_t i = 0;
   27|       |
   28|      5|   while(i < format.size()) {
  ------------------
  |  Branch (28:10): [True: 5, False: 0]
  ------------------
   29|      5|      if(format[i] == '{' && (format.size() > (i + 1)) && format.at(i + 1) == '}') {
  ------------------
  |  Branch (29:10): [True: 1, False: 4]
  |  Branch (29:30): [True: 1, False: 0]
  |  Branch (29:59): [True: 1, False: 0]
  ------------------
   30|      1|         oss << val;
   31|      1|         return do_fmt(oss, format.substr(i + 2), rest...);
   32|      4|      } else {
   33|      4|         oss << format[i];
   34|      4|      }
   35|       |
   36|      4|      i += 1;
   37|      4|   }
   38|      1|}
_ZN5Botan10fmt_detail6do_fmtIPKcJEEEvRNSt3__119basic_ostringstreamIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS4_17basic_string_viewIcS7_EERKT_DpRKT0_:
   25|      1|void do_fmt(std::ostringstream& oss, std::string_view format, const T& val, const Ts&... rest) {
   26|      1|   size_t i = 0;
   27|       |
   28|      2|   while(i < format.size()) {
  ------------------
  |  Branch (28:10): [True: 2, False: 0]
  ------------------
   29|      2|      if(format[i] == '{' && (format.size() > (i + 1)) && format.at(i + 1) == '}') {
  ------------------
  |  Branch (29:10): [True: 1, False: 1]
  |  Branch (29:30): [True: 1, False: 0]
  |  Branch (29:59): [True: 1, False: 0]
  ------------------
   30|      1|         oss << val;
   31|      1|         return do_fmt(oss, format.substr(i + 2), rest...);
   32|      1|      } else {
   33|      1|         oss << format[i];
   34|      1|      }
   35|       |
   36|      1|      i += 1;
   37|      1|   }
   38|      1|}

_ZN5Botan8store_beImEEvT_Ph:
  408|      4|inline constexpr void store_be(T in, uint8_t out[sizeof(T)]) {
  409|      4|   store_be(in, std::span<uint8_t, sizeof(T)>(out, sizeof(T)));
  410|      4|}
_ZN5Botan8store_beImNSt3__14spanIhLm8EEEEEvT_OT0_:
  358|      4|inline constexpr void store_be(T in, OutR&& out_range) {
  359|      4|   ranges::assert_exact_byte_length<sizeof(T)>(out_range);
  360|      4|   std::span out{out_range};
  361|      4|   if constexpr(sizeof(T) == 1) {
  ------------------
  |  Branch (361:17): [Folded - Ignored]
  ------------------
  362|      4|      out[0] = static_cast<uint8_t>(in);
  363|      4|   } else {
  364|       |#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
  365|       |      typecast_copy(out, in);
  366|       |#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
  367|      4|      typecast_copy(out, reverse_bytes(in));
  368|       |#else
  369|       |      [&]<size_t... i>(std::index_sequence<i...>) {
  370|       |         ((out[i] = get_byte<i>(in)), ...);
  371|       |      }
  372|       |      (std::make_index_sequence<sizeof(T)>());
  373|       |#endif
  374|      4|   }
  375|      4|}
_ZN5Botan7load_beImEET_PKhm:
  226|  1.19k|inline constexpr T load_be(const uint8_t in[], size_t off) {
  227|       |   // asserts that *in points to the correct amount of memory
  228|  1.19k|   return load_be<T>(std::span<const uint8_t, sizeof(T)>(in + off * sizeof(T), sizeof(T)));
  229|  1.19k|}
_ZN5Botan7load_beImNSt3__14spanIKhLm8EEEEET_OT0_:
   92|  1.19k|inline constexpr T load_be(InR&& in_range) {
   93|  1.19k|   ranges::assert_exact_byte_length<sizeof(T)>(in_range);
   94|  1.19k|   std::span in{in_range};
   95|  1.19k|   if constexpr(sizeof(T) == 1) {
  ------------------
  |  Branch (95:17): [Folded - Ignored]
  ------------------
   96|  1.19k|      return static_cast<T>(in[0]);
   97|  1.19k|   } 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|  1.19k|      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|  1.19k|   }
  109|  1.19k|}
_ZN5Botan7load_beIjNSt3__14spanIKhLm4EEEEET_OT0_:
   92|    160|inline constexpr T load_be(InR&& in_range) {
   93|    160|   ranges::assert_exact_byte_length<sizeof(T)>(in_range);
   94|    160|   std::span in{in_range};
   95|    160|   if constexpr(sizeof(T) == 1) {
  ------------------
  |  Branch (95:17): [Folded - Ignored]
  ------------------
   96|    160|      return static_cast<T>(in[0]);
   97|    160|   } 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|    160|      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|    160|   }
  109|    160|}
_ZN5Botan8store_beIjNSt3__14spanIhLm4EEEEEvT_OT0_:
  358|     32|inline constexpr void store_be(T in, OutR&& out_range) {
  359|     32|   ranges::assert_exact_byte_length<sizeof(T)>(out_range);
  360|     32|   std::span out{out_range};
  361|     32|   if constexpr(sizeof(T) == 1) {
  ------------------
  |  Branch (361:17): [Folded - Ignored]
  ------------------
  362|     32|      out[0] = static_cast<uint8_t>(in);
  363|     32|   } else {
  364|       |#if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
  365|       |      typecast_copy(out, in);
  366|       |#elif defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
  367|     32|      typecast_copy(out, reverse_bytes(in));
  368|       |#else
  369|       |      [&]<size_t... i>(std::index_sequence<i...>) {
  370|       |         ((out[i] = get_byte<i>(in)), ...);
  371|       |      }
  372|       |      (std::make_index_sequence<sizeof(T)>());
  373|       |#endif
  374|     32|   }
  375|     32|}
_ZN5Botan7load_beIjEET_PKhm:
  226|    160|inline constexpr T load_be(const uint8_t in[], size_t off) {
  227|       |   // asserts that *in points to the correct amount of memory
  228|    160|   return load_be<T>(std::span<const uint8_t, sizeof(T)>(in + off * sizeof(T), sizeof(T)));
  229|    160|}
_ZN5Botan7load_leIjEEvPT_PKhm:
  310|      2|inline constexpr void load_le(T out[], const uint8_t in[], size_t count) {
  311|      2|   if(count > 0) {
  ------------------
  |  Branch (311:7): [True: 2, False: 0]
  ------------------
  312|      2|#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
  313|      2|      typecast_copy(out, in, count);
  314|       |
  315|       |#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
  316|       |      typecast_copy(out, in, count);
  317|       |
  318|       |      for(size_t i = 0; i != count; ++i)
  319|       |         out[i] = reverse_bytes(out[i]);
  320|       |#else
  321|       |      for(size_t i = 0; i != count; ++i)
  322|       |         out[i] = load_le<T>(in, i);
  323|       |#endif
  324|      2|   }
  325|      2|}
_ZN5Botan15copy_out_vec_beIjNS_16secure_allocatorIjEEEEvPhmRKNSt3__16vectorIT_T0_EE:
  521|      4|void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector<T, Alloc>& in) {
  522|      4|   copy_out_be(out, out_bytes, in.data());
  523|      4|}
_ZN5Botan11copy_out_beIjEEvPhmPKT_:
  507|      4|void copy_out_be(uint8_t out[], size_t out_bytes, const T in[]) {
  508|     36|   while(out_bytes >= sizeof(T)) {
  ------------------
  |  Branch (508:10): [True: 32, False: 4]
  ------------------
  509|     32|      store_be(in[0], out);
  510|     32|      out += sizeof(T);
  511|     32|      out_bytes -= sizeof(T);
  512|     32|      in += 1;
  513|     32|   }
  514|       |
  515|      4|   for(size_t i = 0; i != out_bytes; ++i) {
  ------------------
  |  Branch (515:22): [True: 0, False: 4]
  ------------------
  516|      0|      out[i] = get_byte_var(i % 8, in[0]);
  517|      0|   }
  518|      4|}
_ZN5Botan8store_beIjEEvT_Ph:
  408|     32|inline constexpr void store_be(T in, uint8_t out[sizeof(T)]) {
  409|     32|   store_be(in, std::span<uint8_t, sizeof(T)>(out, sizeof(T)));
  410|     32|}

_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EEC2Ev:
   42|      1|      MerkleDamgard_Hash() { clear(); }
_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EE5clearEv:
   70|      7|      void clear() {
   71|      7|         MD::init(m_digest);
   72|      7|         m_buffer.clear();
   73|      7|         m_count = 0;
   74|      7|      }
_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EE6updateENSt3__14spanIKhLm18446744073709551615EEE:
   44|      9|      void update(std::span<const uint8_t> input) {
   45|      9|         BufferSlicer in(input);
   46|       |
   47|     18|         while(!in.empty()) {
  ------------------
  |  Branch (47:16): [True: 9, False: 9]
  ------------------
   48|      9|            if(const auto one_block = m_buffer.handle_unaligned_data(in)) {
  ------------------
  |  Branch (48:27): [True: 0, False: 9]
  ------------------
   49|      0|               MD::compress_n(m_digest, one_block.value(), 1);
   50|      0|            }
   51|       |
   52|      9|            if(m_buffer.in_alignment()) {
  ------------------
  |  Branch (52:16): [True: 6, False: 3]
  ------------------
   53|      6|               const auto [aligned_data, full_blocks] = m_buffer.aligned_data_to_process(in);
   54|      6|               if(full_blocks > 0) {
  ------------------
  |  Branch (54:19): [True: 6, False: 0]
  ------------------
   55|      6|                  MD::compress_n(m_digest, aligned_data, full_blocks);
   56|      6|               }
   57|      6|            }
   58|      9|         }
   59|       |
   60|      9|         m_count += input.size();
   61|      9|      }
_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EE5finalENSt3__14spanIhLm18446744073709551615EEE:
   63|      4|      void final(std::span<uint8_t> output) {
   64|      4|         append_padding_bit();
   65|      4|         append_counter_and_finalize();
   66|      4|         copy_output(output);
   67|      4|         clear();
   68|      4|      }
_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EE18append_padding_bitEv:
   77|      4|      void append_padding_bit() {
   78|      4|         BOTAN_ASSERT_NOMSG(!m_buffer.ready_to_consume());
  ------------------
  |  |   60|      4|   do {                                                                     \
  |  |   61|      4|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 4]
  |  |  ------------------
  |  |   62|      4|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      4|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   79|      4|         if constexpr(MD::bit_endianness == MD_Endian::Big) {
  ------------------
  |  Branch (79:23): [Folded - Ignored]
  ------------------
   80|      4|            const uint8_t final_byte = 0x80;
   81|      4|            m_buffer.append({&final_byte, 1});
   82|      4|         } else {
   83|      4|            const uint8_t final_byte = 0x01;
   84|      4|            m_buffer.append({&final_byte, 1});
   85|      4|         }
   86|      4|      }
_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EE27append_counter_and_finalizeEv:
   88|      4|      void append_counter_and_finalize() {
   89|       |         // Compress the remaining data if the final data block does not provide
   90|       |         // enough space for the counter bytes.
   91|      4|         if(m_buffer.elements_until_alignment() < MD::ctr_bytes) {
  ------------------
  |  Branch (91:13): [True: 0, False: 4]
  ------------------
   92|      0|            m_buffer.fill_up_with_zeros();
   93|      0|            MD::compress_n(m_digest, m_buffer.consume(), 1);
   94|      0|         }
   95|       |
   96|       |         // Make sure that any remaining bytes in the very last block are zero.
   97|      4|         BOTAN_ASSERT_NOMSG(m_buffer.elements_until_alignment() >= MD::ctr_bytes);
  ------------------
  |  |   60|      4|   do {                                                                     \
  |  |   61|      4|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 4]
  |  |  ------------------
  |  |   62|      4|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      4|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   98|      4|         m_buffer.fill_up_with_zeros();
   99|       |
  100|       |         // Replace a bunch of the right-most zero-padding with the counter bytes.
  101|      4|         const uint64_t bit_count = m_count * 8;
  102|      4|         auto last_bytes = m_buffer.directly_modify_last(sizeof(bit_count));
  103|      4|         if constexpr(MD::byte_endianness == MD_Endian::Big) {
  ------------------
  |  Branch (103:23): [Folded - Ignored]
  ------------------
  104|      4|            store_be(bit_count, last_bytes.data());
  105|      4|         } else {
  106|      4|            store_le(bit_count, last_bytes.data());
  107|      4|         }
  108|       |
  109|       |         // Compress the very last block.
  110|      4|         MD::compress_n(m_digest, m_buffer.consume(), 1);
  111|      4|      }
_ZN5Botan18MerkleDamgard_HashINS_7SHA_256EE11copy_outputENSt3__14spanIhLm18446744073709551615EEE:
  113|      4|      void copy_output(std::span<uint8_t> output) {
  114|      4|         BOTAN_ASSERT_NOMSG(output.size() >= MD::output_bytes);
  ------------------
  |  |   60|      4|   do {                                                                     \
  |  |   61|      4|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 4]
  |  |  ------------------
  |  |   62|      4|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|      4|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  115|       |
  116|      4|         if constexpr(MD::byte_endianness == MD_Endian::Big) {
  ------------------
  |  Branch (116:23): [Folded - Ignored]
  ------------------
  117|      4|            copy_out_vec_be(output.data(), MD::output_bytes, m_digest);
  118|      4|         } else {
  119|      4|            copy_out_vec_le(output.data(), MD::output_bytes, m_digest);
  120|      4|         }
  121|      4|      }

_ZNK5Botan14Montgomery_Int4reprEv:
   76|  44.0k|      const BigInt& repr() const { return m_v; }
_ZNK5Botan14Montgomery_Int17const_time_poisonEv:
  122|    688|      void const_time_poison() const { m_v.const_time_poison(); }
_ZNK5Botan14Montgomery_Int19const_time_unpoisonEv:
  124|    713|      void const_time_unpoison() const { return m_v.const_time_unpoison(); }
_ZNK5Botan17Montgomery_Params1pEv:
  148|  1.42k|      const BigInt& p() const { return m_p; }
_ZNK5Botan17Montgomery_Params2R1Ev:
  150|    713|      const BigInt& R1() const { return m_r1; }
_ZNK5Botan17Montgomery_Params2R2Ev:
  152|    713|      const BigInt& R2() const { return m_r2; }
_ZNK5Botan17Montgomery_Params7p_wordsEv:
  158|  11.4k|      size_t p_words() const { return m_p_words; }

_ZN5Botan17monty_exp_vartimeERKNSt3__110shared_ptrIKNS_17Montgomery_ParamsEEERKNS_6BigIntES9_:
   51|    670|                                const BigInt& k) {
   52|    670|   auto precomputed = monty_precompute(params_p, g, 4, false);
   53|    670|   return monty_execute_vartime(*precomputed, k);
   54|    670|}

_ZN5Botan8word_subEmmPm:
  326|  4.19M|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|  4.19M|   asm(ADD_OR_SUBTRACT(ASM("sbbq %[y],%[x]"))
  336|  4.19M|       : [x] "=r"(x), [carry] "=r"(*carry)
  337|  4.19M|       : "0"(x), [y] "rm"(y), "1"(*carry)
  338|  4.19M|       : "cc");
  339|  4.19M|   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|  4.19M|}
_ZN5Botan8word_addEmmPm:
  237|   111k|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|   111k|   asm(ADD_OR_SUBTRACT(ASM("adcq %[y],%[x]"))
  248|   111k|       : [x] "=r"(x), [carry] "=r"(*carry)
  249|   111k|       : "0"(x), [y] "rm"(y), "1"(*carry)
  250|   111k|       : "cc");
  251|   111k|   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|   111k|}
_ZN5Botan10word_madd2EmmPm:
   44|  64.4k|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|  64.4k|   asm(R"(
   59|  64.4k|      mulq %[b]
   60|  64.4k|      addq %[c],%[a]
   61|  64.4k|      adcq $0,%[carry]
   62|  64.4k|      )"
   63|  64.4k|       : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c)
   64|  64.4k|       : "0"(a), "1"(b), [c] "g"(*c)
   65|  64.4k|       : "cc");
   66|       |
   67|  64.4k|   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|  64.4k|}
_ZN5Botan10word_madd3EmmmPm:
   91|  81.9k|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|  81.9k|   asm(R"(
  110|  81.9k|      mulq %[b]
  111|  81.9k|
  112|  81.9k|      addq %[c],%[a]
  113|  81.9k|      adcq $0,%[carry]
  114|  81.9k|
  115|  81.9k|      addq %[d],%[a]
  116|  81.9k|      adcq $0,%[carry]
  117|  81.9k|      )"
  118|  81.9k|       : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d)
  119|  81.9k|       : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d)
  120|  81.9k|       : "cc");
  121|       |
  122|  81.9k|   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|  81.9k|}
_ZN5Botan13word8_linmul2EPmmm:
  443|   351k|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|   351k|   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|   351k|   return carry;
  462|   351k|}
_ZN5Botan12word3_muladdEPmS0_S0_mm:
  528|  5.32M|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|  5.32M|   word z0 = 0, z1 = 0;
  545|       |
  546|  5.32M|   asm("mulq %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc");
  547|       |
  548|  5.32M|   asm(R"(
  549|  5.32M|       addq %[z0],%[w0]
  550|  5.32M|       adcq %[z1],%[w1]
  551|  5.32M|       adcq $0,%[w2]
  552|  5.32M|       )"
  553|  5.32M|       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  554|  5.32M|       : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2)
  555|  5.32M|       : "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|  5.32M|}
_ZN5Botan9word3_addEPmS0_S0_m:
  569|  1.62M|inline void word3_add(word* w2, word* w1, word* w0, word x) {
  570|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
  571|       |   asm(R"(
  572|       |      addl %[x],%[w0]
  573|       |      adcl $0,%[w1]
  574|       |      adcl $0,%[w2]
  575|       |      )"
  576|       |       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  577|       |       : [x] "r"(x), "0"(*w0), "1"(*w1), "2"(*w2)
  578|       |       : "cc");
  579|       |
  580|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  581|  1.62M|   asm(R"(
  582|  1.62M|      addq %[x],%[w0]
  583|  1.62M|      adcq $0,%[w1]
  584|  1.62M|      adcq $0,%[w2]
  585|  1.62M|      )"
  586|  1.62M|       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  587|  1.62M|       : [x] "r"(x), "0"(*w0), "1"(*w1), "2"(*w2)
  588|  1.62M|       : "cc");
  589|       |
  590|       |#else
  591|       |   *w0 += x;
  592|       |   word c1 = (*w0 < x);
  593|       |   *w1 += c1;
  594|       |   word c2 = (*w1 < c1);
  595|       |   *w2 += c2;
  596|       |#endif
  597|  1.62M|}
_ZN5Botan14word3_muladd_2EPmS0_S0_mm:
  603|  1.08M|inline void word3_muladd_2(word* w2, word* w1, word* w0, word x, word y) {
  604|       |#if defined(BOTAN_MP_USE_X86_32_ASM)
  605|       |   word z0 = 0, z1 = 0;
  606|       |
  607|       |   asm("mull %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc");
  608|       |
  609|       |   asm(R"(
  610|       |      addl %[z0],%[w0]
  611|       |      adcl %[z1],%[w1]
  612|       |      adcl $0,%[w2]
  613|       |
  614|       |      addl %[z0],%[w0]
  615|       |      adcl %[z1],%[w1]
  616|       |      adcl $0,%[w2]
  617|       |      )"
  618|       |       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  619|       |       : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2)
  620|       |       : "cc");
  621|       |
  622|       |#elif defined(BOTAN_MP_USE_X86_64_ASM)
  623|  1.08M|   word z0 = 0, z1 = 0;
  624|       |
  625|  1.08M|   asm("mulq %[y]" : "=a"(z0), "=d"(z1) : "a"(x), [y] "rm"(y) : "cc");
  626|       |
  627|  1.08M|   asm(R"(
  628|  1.08M|      addq %[z0],%[w0]
  629|  1.08M|      adcq %[z1],%[w1]
  630|  1.08M|      adcq $0,%[w2]
  631|  1.08M|
  632|  1.08M|      addq %[z0],%[w0]
  633|  1.08M|      adcq %[z1],%[w1]
  634|  1.08M|      adcq $0,%[w2]
  635|  1.08M|      )"
  636|  1.08M|       : [w0] "=r"(*w0), [w1] "=r"(*w1), [w2] "=r"(*w2)
  637|  1.08M|       : [z0] "r"(z0), [z1] "r"(z1), "0"(*w0), "1"(*w1), "2"(*w2)
  638|  1.08M|       : "cc");
  639|       |
  640|       |#else
  641|       |   word carry = 0;
  642|       |   x = word_madd2(x, y, &carry);
  643|       |   y = carry;
  644|       |
  645|       |   word top = (y >> (BOTAN_MP_WORD_BITS - 1));
  646|       |   y <<= 1;
  647|       |   y |= (x >> (BOTAN_MP_WORD_BITS - 1));
  648|       |   x <<= 1;
  649|       |
  650|       |   carry = 0;
  651|       |   *w0 = word_add(*w0, x, &carry);
  652|       |   *w1 = word_add(*w1, y, &carry);
  653|       |   *w2 = word_add(*w2, top, &carry);
  654|       |#endif
  655|  1.08M|}

_ZN5Botan10bigint_cmpEPKmmS1_m:
  490|  48.5k|inline int32_t bigint_cmp(const word x[], size_t x_size, const word y[], size_t y_size) {
  491|  48.5k|   static_assert(sizeof(word) >= sizeof(uint32_t), "Size assumption");
  492|       |
  493|  48.5k|   const word LT = static_cast<word>(-1);
  494|  48.5k|   const word EQ = 0;
  495|  48.5k|   const word GT = 1;
  496|       |
  497|  48.5k|   const size_t common_elems = std::min(x_size, y_size);
  498|       |
  499|  48.5k|   word result = EQ;  // until found otherwise
  500|       |
  501|   148k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (501:22): [True: 100k, False: 48.5k]
  ------------------
  502|   100k|      const auto is_eq = CT::Mask<word>::is_equal(x[i], y[i]);
  503|   100k|      const auto is_lt = CT::Mask<word>::is_lt(x[i], y[i]);
  504|       |
  505|   100k|      result = is_eq.select(result, is_lt.select(LT, GT));
  506|   100k|   }
  507|       |
  508|  48.5k|   if(x_size < y_size) {
  ------------------
  |  Branch (508:7): [True: 7.80k, False: 40.7k]
  ------------------
  509|  7.80k|      word mask = 0;
  510|  37.5k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (510:30): [True: 29.7k, False: 7.80k]
  ------------------
  511|  29.7k|         mask |= y[i];
  512|  29.7k|      }
  513|       |
  514|       |      // If any bits were set in high part of y, then x < y
  515|  7.80k|      result = CT::Mask<word>::is_zero(mask).select(result, LT);
  516|  40.7k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (516:14): [True: 305, False: 40.3k]
  ------------------
  517|    305|      word mask = 0;
  518|  1.28k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (518:30): [True: 981, False: 305]
  ------------------
  519|    981|         mask |= x[i];
  520|    981|      }
  521|       |
  522|       |      // If any bits were set in high part of x, then x > y
  523|    305|      result = CT::Mask<word>::is_zero(mask).select(result, GT);
  524|    305|   }
  525|       |
  526|  48.5k|   CT::unpoison(result);
  527|  48.5k|   BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ);
  ------------------
  |  |   99|  48.5k|      do {                          \
  |  |  100|  48.5k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  528|  48.5k|   return static_cast<int32_t>(result);
  529|  48.5k|}
_ZN5Botan15bigint_ct_is_eqEPKmmS1_m:
  568|    715|inline CT::Mask<word> bigint_ct_is_eq(const word x[], size_t x_size, const word y[], size_t y_size) {
  569|    715|   const size_t common_elems = std::min(x_size, y_size);
  570|       |
  571|    715|   word diff = 0;
  572|       |
  573|  1.96k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (573:22): [True: 1.24k, False: 715]
  ------------------
  574|  1.24k|      diff |= (x[i] ^ y[i]);
  575|  1.24k|   }
  576|       |
  577|       |   // If any bits were set in high part of x/y, then they are not equal
  578|    715|   if(x_size < y_size) {
  ------------------
  |  Branch (578:7): [True: 0, False: 715]
  ------------------
  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|    715|   } else if(y_size < x_size) {
  ------------------
  |  Branch (582:14): [True: 0, False: 715]
  ------------------
  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|    715|   return CT::Mask<word>::is_zero(diff);
  589|    715|}
_ZN5Botan15bigint_ct_is_ltEPKmmS1_mb:
  537|  69.5k|   const word x[], size_t x_size, const word y[], size_t y_size, bool lt_or_equal = false) {
  538|  69.5k|   const size_t common_elems = std::min(x_size, y_size);
  539|       |
  540|  69.5k|   auto is_lt = CT::Mask<word>::expand(lt_or_equal);
  541|       |
  542|   193k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (542:22): [True: 124k, False: 69.5k]
  ------------------
  543|   124k|      const auto eq = CT::Mask<word>::is_equal(x[i], y[i]);
  544|   124k|      const auto lt = CT::Mask<word>::is_lt(x[i], y[i]);
  545|   124k|      is_lt = eq.select_mask(is_lt, lt);
  546|   124k|   }
  547|       |
  548|  69.5k|   if(x_size < y_size) {
  ------------------
  |  Branch (548:7): [True: 4.46k, False: 65.0k]
  ------------------
  549|  4.46k|      word mask = 0;
  550|  16.1k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (550:30): [True: 11.6k, False: 4.46k]
  ------------------
  551|  11.6k|         mask |= y[i];
  552|  11.6k|      }
  553|       |      // If any bits were set in high part of y, then is_lt should be forced true
  554|  4.46k|      is_lt |= CT::Mask<word>::expand(mask);
  555|  65.0k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (555:14): [True: 2.97k, False: 62.0k]
  ------------------
  556|  2.97k|      word mask = 0;
  557|  8.79k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (557:30): [True: 5.82k, False: 2.97k]
  ------------------
  558|  5.82k|         mask |= x[i];
  559|  5.82k|      }
  560|       |
  561|       |      // If any bits were set in high part of x, then is_lt should be false
  562|  2.97k|      is_lt &= CT::Mask<word>::is_zero(mask);
  563|  2.97k|   }
  564|       |
  565|  69.5k|   return is_lt;
  566|  69.5k|}
_ZN5Botan11bigint_sub3EPmPKmmS2_m:
  321|   623k|inline word bigint_sub3(word z[], const word x[], size_t x_size, const word y[], size_t y_size) {
  322|   623k|   word borrow = 0;
  323|       |
  324|   623k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|   623k|   do {                                                                                 \
  |  |   52|   623k|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 623k]
  |  |  ------------------
  |  |   53|   623k|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|   623k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  325|       |
  326|   623k|   const size_t blocks = y_size - (y_size % 8);
  327|       |
  328|   623k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (328:22): [True: 0, False: 623k]
  ------------------
  329|      0|      borrow = word8_sub3(z + i, x + i, y + i, borrow);
  330|      0|   }
  331|       |
  332|  3.08M|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (332:27): [True: 2.45M, False: 623k]
  ------------------
  333|  2.45M|      z[i] = word_sub(x[i], y[i], &borrow);
  334|  2.45M|   }
  335|       |
  336|  2.33M|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (336:27): [True: 1.71M, False: 623k]
  ------------------
  337|  1.71M|      z[i] = word_sub(x[i], 0, &borrow);
  338|  1.71M|   }
  339|       |
  340|   623k|   return borrow;
  341|   623k|}
_ZN5Botan14bigint_cnd_addEmPmmPKmm:
   40|    765|inline word bigint_cnd_add(word cnd, word x[], word x_size, const word y[], size_t y_size) {
   41|    765|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|    765|   do {                                                                                 \
  |  |   52|    765|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 765]
  |  |  ------------------
  |  |   53|    765|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|    765|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   42|       |
   43|    765|   const auto mask = CT::Mask<word>::expand(cnd);
   44|       |
   45|    765|   word carry = 0;
   46|       |
   47|    765|   const size_t blocks = y_size - (y_size % 8);
   48|    765|   word z[8] = {0};
   49|       |
   50|    765|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (50:22): [True: 0, False: 765]
  ------------------
   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|  3.82k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (55:27): [True: 3.06k, False: 765]
  ------------------
   56|  3.06k|      z[0] = word_add(x[i], y[i], &carry);
   57|  3.06k|      x[i] = mask.select(z[0], x[i]);
   58|  3.06k|   }
   59|       |
   60|  3.82k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (60:27): [True: 3.06k, False: 765]
  ------------------
   61|  3.06k|      z[0] = word_add(x[i], 0, &carry);
   62|  3.06k|      x[i] = mask.select(z[0], x[i]);
   63|  3.06k|   }
   64|       |
   65|    765|   return mask.if_set_return(carry);
   66|    765|}
_ZN5Botan11bigint_shl2EPmPKmmmm:
  417|  7.38k|inline void bigint_shl2(word y[], const word x[], size_t x_size, size_t word_shift, size_t bit_shift) {
  418|  7.38k|   copy_mem(y + word_shift, x, x_size);
  419|       |
  420|  7.38k|   const auto carry_mask = CT::Mask<word>::expand(bit_shift);
  421|  7.38k|   const word carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift);
  ------------------
  |  |   50|  7.38k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  422|       |
  423|  7.38k|   word carry = 0;
  424|  31.6k|   for(size_t i = word_shift; i != x_size + word_shift + 1; ++i) {
  ------------------
  |  Branch (424:31): [True: 24.2k, False: 7.38k]
  ------------------
  425|  24.2k|      const word w = y[i];
  426|  24.2k|      y[i] = (w << bit_shift) | carry;
  427|  24.2k|      carry = carry_mask.if_set_return(w >> carry_shift);
  428|  24.2k|   }
  429|  7.38k|}
_ZN5Botan15bigint_cnd_swapEmPmS0_m:
   29|   357k|inline void bigint_cnd_swap(word cnd, word x[], word y[], size_t size) {
   30|   357k|   const auto mask = CT::Mask<word>::expand(cnd);
   31|       |
   32|  3.21M|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (32:22): [True: 2.85M, False: 357k]
  ------------------
   33|  2.85M|      const word a = x[i];
   34|  2.85M|      const word b = y[i];
   35|  2.85M|      x[i] = mask.select(b, a);
   36|  2.85M|      y[i] = mask.select(a, b);
   37|  2.85M|   }
   38|   357k|}
_ZN5Botan14bigint_add2_ncEPmmPKmm:
  203|  14.8k|inline word bigint_add2_nc(word x[], size_t x_size, const word y[], size_t y_size) {
  204|  14.8k|   word carry = 0;
  205|       |
  206|  14.8k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|  14.8k|   do {                                                                                 \
  |  |   52|  14.8k|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 14.8k]
  |  |  ------------------
  |  |   53|  14.8k|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|  14.8k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  207|       |
  208|  14.8k|   const size_t blocks = y_size - (y_size % 8);
  209|       |
  210|  14.8k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (210:22): [True: 0, False: 14.8k]
  ------------------
  211|      0|      carry = word8_add2(x + i, y + i, carry);
  212|      0|   }
  213|       |
  214|  48.5k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (214:27): [True: 33.7k, False: 14.8k]
  ------------------
  215|  33.7k|      x[i] = word_add(x[i], y[i], &carry);
  216|  33.7k|   }
  217|       |
  218|  80.4k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (218:27): [True: 65.6k, False: 14.8k]
  ------------------
  219|  65.6k|      x[i] = word_add(x[i], 0, &carry);
  220|  65.6k|   }
  221|       |
  222|  14.8k|   return carry;
  223|  14.8k|}
_ZN5Botan14bigint_add3_ncEPmPKmmS2_m:
  228|  1.71k|inline word bigint_add3_nc(word z[], const word x[], size_t x_size, const word y[], size_t y_size) {
  229|  1.71k|   if(x_size < y_size) {
  ------------------
  |  Branch (229:7): [True: 233, False: 1.47k]
  ------------------
  230|    233|      return bigint_add3_nc(z, y, y_size, x, x_size);
  231|    233|   }
  232|       |
  233|  1.47k|   word carry = 0;
  234|       |
  235|  1.47k|   const size_t blocks = y_size - (y_size % 8);
  236|       |
  237|  1.47k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (237:22): [True: 0, False: 1.47k]
  ------------------
  238|      0|      carry = word8_add3(z + i, x + i, y + i, carry);
  239|      0|   }
  240|       |
  241|  5.17k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (241:27): [True: 3.69k, False: 1.47k]
  ------------------
  242|  3.69k|      z[i] = word_add(x[i], y[i], &carry);
  243|  3.69k|   }
  244|       |
  245|  3.83k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (245:27): [True: 2.35k, False: 1.47k]
  ------------------
  246|  2.35k|      z[i] = word_add(x[i], 0, &carry);
  247|  2.35k|   }
  248|       |
  249|  1.47k|   return carry;
  250|  1.71k|}
_ZN5Botan11bigint_add2EPmmPKmm:
  259|  14.8k|inline void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) {
  260|  14.8k|   x[x_size] += bigint_add2_nc(x, x_size, y, y_size);
  261|  14.8k|}
_ZN5Botan11bigint_add3EPmPKmmS2_m:
  266|  1.47k|inline void bigint_add3(word z[], const word x[], size_t x_size, const word y[], size_t y_size) {
  267|  1.47k|   z[x_size > y_size ? x_size : y_size] += bigint_add3_nc(z, x, x_size, y, y_size);
  ------------------
  |  Branch (267:6): [True: 673, False: 806]
  ------------------
  268|  1.47k|}
_ZN5Botan11bigint_sub2EPmmPKmm:
  273|  8.36k|inline word bigint_sub2(word x[], size_t x_size, const word y[], size_t y_size) {
  274|  8.36k|   word borrow = 0;
  275|       |
  276|  8.36k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   51|  8.36k|   do {                                                                                 \
  |  |   52|  8.36k|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 8.36k]
  |  |  ------------------
  |  |   53|  8.36k|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|  8.36k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  277|       |
  278|  8.36k|   const size_t blocks = y_size - (y_size % 8);
  279|       |
  280|  8.36k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (280:22): [True: 0, False: 8.36k]
  ------------------
  281|      0|      borrow = word8_sub2(x + i, y + i, borrow);
  282|      0|   }
  283|       |
  284|  36.6k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (284:27): [True: 28.2k, False: 8.36k]
  ------------------
  285|  28.2k|      x[i] = word_sub(x[i], y[i], &borrow);
  286|  28.2k|   }
  287|       |
  288|  8.67k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (288:27): [True: 313, False: 8.36k]
  ------------------
  289|    313|      x[i] = word_sub(x[i], 0, &borrow);
  290|    313|   }
  291|       |
  292|  8.36k|   return borrow;
  293|  8.36k|}
_ZN5Botan15bigint_sub2_revEPmPKmm:
  298|     26|inline void bigint_sub2_rev(word x[], const word y[], size_t y_size) {
  299|     26|   word borrow = 0;
  300|       |
  301|     26|   const size_t blocks = y_size - (y_size % 8);
  302|       |
  303|     26|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (303:22): [True: 0, False: 26]
  ------------------
  304|      0|      borrow = word8_sub2_rev(x + i, y + i, borrow);
  305|      0|   }
  306|       |
  307|    141|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (307:27): [True: 115, False: 26]
  ------------------
  308|    115|      x[i] = word_sub(y[i], x[i], &borrow);
  309|    115|   }
  310|       |
  311|     26|   BOTAN_ASSERT(borrow == 0, "y must be greater than x");
  ------------------
  |  |   51|     26|   do {                                                                                 \
  |  |   52|     26|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 26]
  |  |  ------------------
  |  |   53|     26|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|     26|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  312|     26|}
_ZN5Botan11bigint_shl1EPmmmmm:
  382|  14.7k|inline void bigint_shl1(word x[], size_t x_size, size_t x_words, size_t word_shift, size_t bit_shift) {
  383|  14.7k|   copy_mem(x + word_shift, x, x_words);
  384|  14.7k|   clear_mem(x, word_shift);
  385|       |
  386|  14.7k|   const auto carry_mask = CT::Mask<word>::expand(bit_shift);
  387|  14.7k|   const word carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift);
  ------------------
  |  |   50|  14.7k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  388|       |
  389|  14.7k|   word carry = 0;
  390|  56.8k|   for(size_t i = word_shift; i != x_size; ++i) {
  ------------------
  |  Branch (390:31): [True: 42.1k, False: 14.7k]
  ------------------
  391|  42.1k|      const word w = x[i];
  392|  42.1k|      x[i] = (w << bit_shift) | carry;
  393|  42.1k|      carry = carry_mask.if_set_return(w >> carry_shift);
  394|  42.1k|   }
  395|  14.7k|}
_ZN5Botan11bigint_shr1EPmmmm:
  397|  52.0k|inline void bigint_shr1(word x[], size_t x_size, size_t word_shift, size_t bit_shift) {
  398|  52.0k|   const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0;
  ------------------
  |  Branch (398:23): [True: 51.9k, False: 75]
  ------------------
  399|       |
  400|  52.0k|   if(top > 0) {
  ------------------
  |  Branch (400:7): [True: 51.9k, False: 75]
  ------------------
  401|  51.9k|      copy_mem(x, x + word_shift, top);
  402|  51.9k|   }
  403|  52.0k|   clear_mem(x + top, std::min(word_shift, x_size));
  404|       |
  405|  52.0k|   const auto carry_mask = CT::Mask<word>::expand(bit_shift);
  406|  52.0k|   const word carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift);
  ------------------
  |  |   50|  52.0k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  407|       |
  408|  52.0k|   word carry = 0;
  409|       |
  410|   443k|   for(size_t i = 0; i != top; ++i) {
  ------------------
  |  Branch (410:22): [True: 391k, False: 52.0k]
  ------------------
  411|   391k|      const word w = x[top - i - 1];
  412|   391k|      x[top - i - 1] = (w >> bit_shift) | carry;
  413|   391k|      carry = carry_mask.if_set_return(w << carry_shift);
  414|   391k|   }
  415|  52.0k|}
_ZN5Botan11bigint_shr2EPmPKmmmm:
  431|    713|inline void bigint_shr2(word y[], const word x[], size_t x_size, size_t word_shift, size_t bit_shift) {
  432|    713|   const size_t new_size = x_size < word_shift ? 0 : (x_size - word_shift);
  ------------------
  |  Branch (432:28): [True: 0, False: 713]
  ------------------
  433|       |
  434|    713|   if(new_size > 0) {
  ------------------
  |  Branch (434:7): [True: 713, False: 0]
  ------------------
  435|    713|      copy_mem(y, x + word_shift, new_size);
  436|    713|   }
  437|       |
  438|    713|   const auto carry_mask = CT::Mask<word>::expand(bit_shift);
  439|    713|   const word carry_shift = carry_mask.if_set_return(BOTAN_MP_WORD_BITS - bit_shift);
  ------------------
  |  |   50|    713|#define BOTAN_MP_WORD_BITS 64
  ------------------
  440|       |
  441|    713|   word carry = 0;
  442|  3.56k|   for(size_t i = new_size; i > 0; --i) {
  ------------------
  |  Branch (442:29): [True: 2.85k, False: 713]
  ------------------
  443|  2.85k|      word w = y[i - 1];
  444|  2.85k|      y[i - 1] = (w >> bit_shift) | carry;
  445|  2.85k|      carry = carry_mask.if_set_return(w << carry_shift);
  446|  2.85k|   }
  447|    713|}
_ZN5Botan14bigint_linmul2EPmmm:
  452|   351k|[[nodiscard]] inline word bigint_linmul2(word x[], size_t x_size, word y) {
  453|   351k|   const size_t blocks = x_size - (x_size % 8);
  454|       |
  455|   351k|   word carry = 0;
  456|       |
  457|   703k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (457:22): [True: 351k, False: 351k]
  ------------------
  458|   351k|      carry = word8_linmul2(x + i, y, carry);
  459|   351k|   }
  460|       |
  461|   351k|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (461:27): [True: 0, False: 351k]
  ------------------
  462|      0|      x[i] = word_madd2(x[i], y, &carry);
  463|      0|   }
  464|       |
  465|   351k|   return carry;
  466|   351k|}
_ZN5Botan14bigint_linmul3EPmPKmmm:
  468|  10.8k|inline void bigint_linmul3(word z[], const word x[], size_t x_size, word y) {
  469|  10.8k|   const size_t blocks = x_size - (x_size % 8);
  470|       |
  471|  10.8k|   word carry = 0;
  472|       |
  473|  10.8k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (473:22): [True: 0, False: 10.8k]
  ------------------
  474|      0|      carry = word8_linmul3(z + i, x + i, y, carry);
  475|      0|   }
  476|       |
  477|  41.7k|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (477:27): [True: 30.9k, False: 10.8k]
  ------------------
  478|  30.9k|      z[i] = word_madd2(x[i], y, &carry);
  479|  30.9k|   }
  480|       |
  481|  10.8k|   z[x_size] = carry;
  482|  10.8k|}
_ZN5Botan14bigint_sub_absEPmPKmmS2_m:
  604|  21.7k|inline int32_t bigint_sub_abs(word z[], const word x[], size_t x_size, const word y[], size_t y_size) {
  605|  21.7k|   const int32_t relative_size = bigint_cmp(x, x_size, y, y_size);
  606|       |
  607|       |   // Swap if relative_size == -1
  608|  21.7k|   const bool need_swap = relative_size < 0;
  609|  21.7k|   CT::conditional_swap_ptr(need_swap, x, y);
  610|  21.7k|   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|  21.7k|   y_size = std::min(x_size, y_size);
  618|       |
  619|  21.7k|   bigint_sub3(z, x, x_size, y, y_size);
  620|       |
  621|  21.7k|   return relative_size;
  622|  21.7k|}
_ZN5Botan20bigint_divop_vartimeEmmm:
  665|  8.37k|inline word bigint_divop_vartime(word n1, word n0, word d) {
  666|  8.37k|   if(d == 0) {
  ------------------
  |  Branch (666:7): [True: 0, False: 8.37k]
  ------------------
  667|      0|      throw Invalid_Argument("bigint_divop_vartime divide by zero");
  668|      0|   }
  669|       |
  670|  8.37k|#if defined(BOTAN_MP_DWORD)
  671|  8.37k|   return static_cast<word>(((static_cast<BOTAN_MP_DWORD>(n1) << BOTAN_MP_WORD_BITS) | n0) / d);
  ------------------
  |  |   50|  8.37k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  672|       |#else
  673|       |
  674|       |   word high = n1 % d;
  675|       |   word quotient = 0;
  676|       |
  677|       |   for(size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) {
  678|       |      const word high_top_bit = high >> (BOTAN_MP_WORD_BITS - 1);
  679|       |
  680|       |      high <<= 1;
  681|       |      high |= (n0 >> (BOTAN_MP_WORD_BITS - 1 - i)) & 1;
  682|       |      quotient <<= 1;
  683|       |
  684|       |      if(high_top_bit || high >= d) {
  685|       |         high -= d;
  686|       |         quotient |= 1;
  687|       |      }
  688|       |   }
  689|       |
  690|       |   return quotient;
  691|       |#endif
  692|  8.37k|}
_ZN5Botan20bigint_modop_vartimeEmmm:
  697|  19.0k|inline word bigint_modop_vartime(word n1, word n0, word d) {
  698|  19.0k|   if(d == 0) {
  ------------------
  |  Branch (698:7): [True: 0, False: 19.0k]
  ------------------
  699|      0|      throw Invalid_Argument("bigint_modop_vartime divide by zero");
  700|      0|   }
  701|       |
  702|  19.0k|#if defined(BOTAN_MP_DWORD)
  703|  19.0k|   return ((static_cast<BOTAN_MP_DWORD>(n1) << BOTAN_MP_WORD_BITS) | n0) % d;
  ------------------
  |  |   50|  19.0k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  704|       |#else
  705|       |   word z = bigint_divop_vartime(n1, n0, d);
  706|       |   word dummy = 0;
  707|       |   z = word_madd2(z, d, &dummy);
  708|       |   return (n0 - z);
  709|       |#endif
  710|  19.0k|}
_ZN5Botan17bigint_monty_redcEPmPKmmmS0_m:
  757|   231k|inline void bigint_monty_redc(word z[], const word p[], size_t p_size, word p_dash, word ws[], size_t ws_size) {
  758|   231k|   const size_t z_size = 2 * p_size;
  759|       |
  760|   231k|   BOTAN_ARG_CHECK(ws_size >= p_size + 1, "Montgomery workspace too small");
  ------------------
  |  |   30|   231k|   do {                                                          \
  |  |   31|   231k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 231k]
  |  |  ------------------
  |  |   32|   231k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|   231k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  761|       |
  762|   231k|   if(p_size == 4) {
  ------------------
  |  Branch (762:7): [True: 231k, False: 0]
  ------------------
  763|   231k|      bigint_monty_redc_4(z, p, p_dash, ws);
  764|   231k|   } else if(p_size == 6) {
  ------------------
  |  Branch (764:14): [True: 0, False: 0]
  ------------------
  765|      0|      bigint_monty_redc_6(z, p, p_dash, ws);
  766|      0|   } else if(p_size == 8) {
  ------------------
  |  Branch (766:14): [True: 0, False: 0]
  ------------------
  767|      0|      bigint_monty_redc_8(z, p, p_dash, ws);
  768|      0|   } else if(p_size == 16) {
  ------------------
  |  Branch (768:14): [True: 0, False: 0]
  ------------------
  769|      0|      bigint_monty_redc_16(z, p, p_dash, ws);
  770|      0|   } else if(p_size == 24) {
  ------------------
  |  Branch (770:14): [True: 0, False: 0]
  ------------------
  771|      0|      bigint_monty_redc_24(z, p, p_dash, ws);
  772|      0|   } else if(p_size == 32) {
  ------------------
  |  Branch (772:14): [True: 0, False: 0]
  ------------------
  773|      0|      bigint_monty_redc_32(z, p, p_dash, ws);
  774|      0|   } else {
  775|      0|      bigint_monty_redc_generic(z, z_size, p, p_size, p_dash, ws);
  776|      0|   }
  777|   231k|}

_ZN5Botan4rotrILm18EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm6EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm2EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm22EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm7EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm13EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan3rhoILm2ELm13ELm22EjEET2_S1_:
   51|    640|inline constexpr T rho(T x) {
   52|    640|   return rotr<R1>(x) ^ rotr<R2>(x) ^ rotr<R3>(x);
   53|    640|}
_ZN5Botan3rhoILm6ELm11ELm25EjEET2_S1_:
   51|    640|inline constexpr T rho(T x) {
   52|    640|   return rotr<R1>(x) ^ rotr<R2>(x) ^ rotr<R3>(x);
   53|    640|}
_ZN5Botan4rotrILm11EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm25EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan5sigmaILm7ELm18ELm3EjEET2_S1_:
   43|    640|inline constexpr T sigma(T x) {
   44|    640|   return rotr<R1>(x) ^ rotr<R2>(x) ^ (x >> S);
   45|    640|}
_ZN5Botan5sigmaILm17ELm19ELm10EjEET2_S1_:
   43|    640|inline constexpr T sigma(T x) {
   44|    640|   return rotr<R1>(x) ^ rotr<R2>(x) ^ (x >> S);
   45|    640|}
_ZN5Botan4rotrILm17EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}
_ZN5Botan4rotrILm19EjEET0_S1_:
   35|    640|{
   36|    640|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|    640|}

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

_ZN5Botan11checked_mulEmm:
   47|   220k|inline std::optional<size_t> checked_mul(size_t x, size_t y) {
   48|   220k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_add_overflow)
   49|   220k|   size_t z;
   50|   220k|   if(__builtin_mul_overflow(x, y, &z)) [[unlikely]]
  ------------------
  |  Branch (50:7): [True: 0, False: 220k]
  ------------------
   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|   220k|   return z;
   62|   220k|}

_ZNK5Botan9SCAN_Name9algo_nameEv:
   44|      7|      const std::string& algo_name() const { return m_alg_name; }
_ZNK5Botan9SCAN_Name9arg_countEv:
   49|      3|      size_t arg_count() const { return m_args.size(); }

_ZNK5Botan7SHA_25613output_lengthEv:
   75|      5|      size_t output_length() const override { return output_bytes; }
_ZNK5Botan7SHA_25615hash_block_sizeEv:
   77|      1|      size_t hash_block_size() const override { return block_bytes; }
_ZN5Botan7SHA_2565clearEv:
   83|      2|      void clear() override { m_md.clear(); }

_ZN5Botan9SHA2_32_FEjjjRjjjjS0_S0_jjjj:
   31|    640|                                  uint32_t magic) {
   32|    640|   uint32_t A_rho = rho<2, 13, 22>(A);
   33|    640|   uint32_t E_rho = rho<6, 11, 25>(E);
   34|    640|   uint32_t M2_sigma = sigma<17, 19, 10>(M2);
   35|    640|   uint32_t M4_sigma = sigma<7, 18, 3>(M4);
   36|    640|   H += magic + E_rho + choose(E, F, G) + M1;
   37|    640|   D += H;
   38|    640|   H += A_rho + majority(A, B, C);
   39|    640|   M1 += M2_sigma + M3 + M4_sigma;
   40|    640|}

_ZN5Botan9SIMD_4x32C2EDv2_x:
  597|      2|      explicit SIMD_4x32(native_simd_type x) noexcept : m_simd(x) {}
_ZN5Botan9SIMD_4x32C2Ejjjj:
  113|     96|      SIMD_4x32(uint32_t B0, uint32_t B1, uint32_t B2, uint32_t B3) noexcept {
  114|     96|#if defined(BOTAN_SIMD_USE_SSE2)
  115|     96|         m_simd = _mm_set_epi32(B3, B2, B1, B0);
  116|       |#elif defined(BOTAN_SIMD_USE_ALTIVEC)
  117|       |         __vector unsigned int val = {B0, B1, B2, B3};
  118|       |         m_simd = val;
  119|       |#elif defined(BOTAN_SIMD_USE_NEON)
  120|       |         // Better way to do this?
  121|       |         const uint32_t B[4] = {B0, B1, B2, B3};
  122|       |         m_simd = vld1q_u32(B);
  123|       |#endif
  124|     96|      }
_ZN5Botan9SIMD_4x328splat_u8Eh:
  142|      2|      static SIMD_4x32 splat_u8(uint8_t B) noexcept {
  143|      2|#if defined(BOTAN_SIMD_USE_SSE2)
  144|      2|         return SIMD_4x32(_mm_set1_epi8(B));
  145|       |#elif defined(BOTAN_SIMD_USE_NEON)
  146|       |         return SIMD_4x32(vreinterpretq_u32_u8(vdupq_n_u8(B)));
  147|       |#else
  148|       |         const uint32_t B4 = make_uint32(B, B, B, B);
  149|       |         return SIMD_4x32(B4, B4, B4, B4);
  150|       |#endif
  151|      2|      }

_ZN5Botan9SIMD_8x3215reset_registersEv:
  243|      5|      static void reset_registers() noexcept { _mm256_zeroupper(); }
_ZN5Botan9SIMD_8x32C2EDv4_x:
  251|  1.84k|      SIMD_8x32(__m256i x) noexcept : m_avx2(x) {}
_ZN5Botan9SIMD_8x329transposeERS0_S1_S1_S1_:
  194|     20|      static void transpose(SIMD_8x32& B0, SIMD_8x32& B1, SIMD_8x32& B2, SIMD_8x32& B3) noexcept {
  195|     20|         const __m256i T0 = _mm256_unpacklo_epi32(B0.m_avx2, B1.m_avx2);
  196|     20|         const __m256i T1 = _mm256_unpacklo_epi32(B2.m_avx2, B3.m_avx2);
  197|     20|         const __m256i T2 = _mm256_unpackhi_epi32(B0.m_avx2, B1.m_avx2);
  198|     20|         const __m256i T3 = _mm256_unpackhi_epi32(B2.m_avx2, B3.m_avx2);
  199|       |
  200|     20|         B0.m_avx2 = _mm256_unpacklo_epi64(T0, T1);
  201|     20|         B1.m_avx2 = _mm256_unpackhi_epi64(T0, T1);
  202|     20|         B2.m_avx2 = _mm256_unpacklo_epi64(T2, T3);
  203|     20|         B3.m_avx2 = _mm256_unpackhi_epi64(T2, T3);
  204|     20|      }
_ZNK5Botan9SIMD_8x328store_leEPh:
   59|     80|      void store_le(uint8_t out[]) const noexcept { _mm256_storeu_si256(reinterpret_cast<__m256i*>(out), m_avx2); }
_ZN5Botan9SIMD_8x3214zero_registersEv:
  246|      5|      static void zero_registers() noexcept { _mm256_zeroall(); }
_ZN5Botan9SIMD_8x325splatEj:
   48|    160|      static SIMD_8x32 splat(uint32_t B) noexcept { return SIMD_8x32(_mm256_set1_epi32(B)); }
_ZN5Botan9SIMD_8x32eOERKS0_:
  149|  1.60k|      void operator^=(const SIMD_8x32& other) { m_avx2 = _mm256_xor_si256(m_avx2, other.m_avx2); }
_ZNK5Botan9SIMD_8x324rotlILm7EEES0_v:
   67|    400|      {
   68|       |#if defined(__AVX512VL__)
   69|       |         return SIMD_8x32(_mm256_rol_epi32(m_avx2, ROT));
   70|       |#else
   71|    400|         if constexpr(ROT == 8) {
  ------------------
  |  Branch (71:23): [Folded - Ignored]
  ------------------
   72|    400|            const __m256i shuf_rotl_8 =
   73|    400|               _mm256_set_epi64x(0x0e0d0c0f'0a09080b, 0x06050407'02010003, 0x0e0d0c0f'0a09080b, 0x06050407'02010003);
   74|       |
   75|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_8));
   76|    400|         } else if constexpr(ROT == 16) {
  ------------------
  |  Branch (76:30): [Folded - Ignored]
  ------------------
   77|    400|            const __m256i shuf_rotl_16 =
   78|    400|               _mm256_set_epi64x(0x0d0c0f0e'09080b0a, 0x05040706'01000302, 0x0d0c0f0e'09080b0a, 0x05040706'01000302);
   79|       |
   80|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_16));
   81|    400|         } else {
   82|    400|            return SIMD_8x32(_mm256_or_si256(_mm256_slli_epi32(m_avx2, static_cast<int>(ROT)),
   83|    400|                                             _mm256_srli_epi32(m_avx2, static_cast<int>(32 - ROT))));
   84|    400|         }
   85|    400|#endif
   86|    400|      }
_ZN5Botan9SIMD_8x32C2Ejjjjjjjj:
   43|     10|                         uint32_t B7) noexcept {
   44|     10|         m_avx2 = _mm256_set_epi32(B7, B6, B5, B4, B3, B2, B1, B0);
   45|     10|      }
_ZNK5Botan9SIMD_8x32plERKS0_:
  108|     20|      SIMD_8x32 operator+(const SIMD_8x32& other) const noexcept {
  109|     20|         SIMD_8x32 retval(*this);
  110|     20|         retval += other;
  111|     20|         return retval;
  112|     20|      }
_ZN5Botan9SIMD_8x32pLERKS0_:
  143|  1.70k|      void operator+=(const SIMD_8x32& other) { m_avx2 = _mm256_add_epi32(m_avx2, other.m_avx2); }
_ZN5Botan9SIMD_8x329transposeERS0_S1_S1_S1_S1_S1_S1_S1_:
  214|     10|                            SIMD_8x32& B7) noexcept {
  215|     10|         transpose(B0, B1, B2, B3);
  216|     10|         transpose(B4, B5, B6, B7);
  217|       |
  218|     10|         swap_tops(B0, B4);
  219|     10|         swap_tops(B1, B5);
  220|     10|         swap_tops(B2, B6);
  221|     10|         swap_tops(B3, B7);
  222|     10|      }
_ZNK5Botan9SIMD_8x326handleEv:
  248|    160|      __m256i BOTAN_AVX2_FN handle() const noexcept { return m_avx2; }
_ZN5Botan9SIMD_8x329swap_topsERS0_S1_:
  255|     40|      static void swap_tops(SIMD_8x32& A, SIMD_8x32& B) {
  256|     40|         SIMD_8x32 T0 = _mm256_permute2x128_si256(A.handle(), B.handle(), 0 + (2 << 4));
  257|     40|         SIMD_8x32 T1 = _mm256_permute2x128_si256(A.handle(), B.handle(), 1 + (3 << 4));
  258|     40|         A = T0;
  259|     40|         B = T1;
  260|     40|      }
_ZNK5Botan9SIMD_8x324rotlILm16EEES0_v:
   67|    400|      {
   68|       |#if defined(__AVX512VL__)
   69|       |         return SIMD_8x32(_mm256_rol_epi32(m_avx2, ROT));
   70|       |#else
   71|    400|         if constexpr(ROT == 8) {
  ------------------
  |  Branch (71:23): [Folded - Ignored]
  ------------------
   72|    400|            const __m256i shuf_rotl_8 =
   73|    400|               _mm256_set_epi64x(0x0e0d0c0f'0a09080b, 0x06050407'02010003, 0x0e0d0c0f'0a09080b, 0x06050407'02010003);
   74|       |
   75|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_8));
   76|    400|         } else if constexpr(ROT == 16) {
  ------------------
  |  Branch (76:30): [Folded - Ignored]
  ------------------
   77|    400|            const __m256i shuf_rotl_16 =
   78|    400|               _mm256_set_epi64x(0x0d0c0f0e'09080b0a, 0x05040706'01000302, 0x0d0c0f0e'09080b0a, 0x05040706'01000302);
   79|       |
   80|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_16));
   81|    400|         } else {
   82|    400|            return SIMD_8x32(_mm256_or_si256(_mm256_slli_epi32(m_avx2, static_cast<int>(ROT)),
   83|    400|                                             _mm256_srli_epi32(m_avx2, static_cast<int>(32 - ROT))));
   84|    400|         }
   85|    400|#endif
   86|    400|      }
_ZNK5Botan9SIMD_8x324rotlILm12EEES0_v:
   67|    400|      {
   68|       |#if defined(__AVX512VL__)
   69|       |         return SIMD_8x32(_mm256_rol_epi32(m_avx2, ROT));
   70|       |#else
   71|    400|         if constexpr(ROT == 8) {
  ------------------
  |  Branch (71:23): [Folded - Ignored]
  ------------------
   72|    400|            const __m256i shuf_rotl_8 =
   73|    400|               _mm256_set_epi64x(0x0e0d0c0f'0a09080b, 0x06050407'02010003, 0x0e0d0c0f'0a09080b, 0x06050407'02010003);
   74|       |
   75|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_8));
   76|    400|         } else if constexpr(ROT == 16) {
  ------------------
  |  Branch (76:30): [Folded - Ignored]
  ------------------
   77|    400|            const __m256i shuf_rotl_16 =
   78|    400|               _mm256_set_epi64x(0x0d0c0f0e'09080b0a, 0x05040706'01000302, 0x0d0c0f0e'09080b0a, 0x05040706'01000302);
   79|       |
   80|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_16));
   81|    400|         } else {
   82|    400|            return SIMD_8x32(_mm256_or_si256(_mm256_slli_epi32(m_avx2, static_cast<int>(ROT)),
   83|    400|                                             _mm256_srli_epi32(m_avx2, static_cast<int>(32 - ROT))));
   84|    400|         }
   85|    400|#endif
   86|    400|      }
_ZNK5Botan9SIMD_8x324rotlILm8EEES0_v:
   67|    400|      {
   68|       |#if defined(__AVX512VL__)
   69|       |         return SIMD_8x32(_mm256_rol_epi32(m_avx2, ROT));
   70|       |#else
   71|    400|         if constexpr(ROT == 8) {
  ------------------
  |  Branch (71:23): [Folded - Ignored]
  ------------------
   72|    400|            const __m256i shuf_rotl_8 =
   73|    400|               _mm256_set_epi64x(0x0e0d0c0f'0a09080b, 0x06050407'02010003, 0x0e0d0c0f'0a09080b, 0x06050407'02010003);
   74|       |
   75|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_8));
   76|    400|         } else if constexpr(ROT == 16) {
   77|    400|            const __m256i shuf_rotl_16 =
   78|    400|               _mm256_set_epi64x(0x0d0c0f0e'09080b0a, 0x05040706'01000302, 0x0d0c0f0e'09080b0a, 0x05040706'01000302);
   79|       |
   80|    400|            return SIMD_8x32(_mm256_shuffle_epi8(m_avx2, shuf_rotl_16));
   81|    400|         } else {
   82|    400|            return SIMD_8x32(_mm256_or_si256(_mm256_slli_epi32(m_avx2, static_cast<int>(ROT)),
   83|    400|                                             _mm256_srli_epi32(m_avx2, static_cast<int>(32 - ROT))));
   84|    400|         }
   85|    400|#endif
   86|    400|      }

_ZN5Botan12BufferSlicerC2ENSt3__14spanIKhLm18446744073709551615EEE:
  143|     19|      BufferSlicer(std::span<const uint8_t> buffer) : m_remaining(buffer) {}
_ZN5Botan12BufferSlicer4takeEm:
  155|     19|      std::span<const uint8_t> take(const size_t count) {
  156|     19|         BOTAN_STATE_CHECK(remaining() >= count);
  ------------------
  |  |   42|     19|   do {                                                         \
  |  |   43|     19|      if(!(expr))                                               \
  |  |  ------------------
  |  |  |  Branch (43:10): [True: 0, False: 19]
  |  |  ------------------
  |  |   44|     19|         Botan::throw_invalid_state(#expr, __func__, __FILE__); \
  |  |   45|     19|   } while(0)
  |  |  ------------------
  |  |  |  Branch (45:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  157|     19|         auto result = m_remaining.first(count);
  158|     19|         m_remaining = m_remaining.subspan(count);
  159|     19|         return result;
  160|     19|      }
_ZNK5Botan12BufferSlicer9remainingEv:
  184|     37|      size_t remaining() const { return m_remaining.size(); }
_ZNK5Botan12BufferSlicer5emptyEv:
  186|     18|      bool empty() const { return m_remaining.empty(); }

_ZN5Botan13ignore_paramsIJRmEEEvDpOT_:
  114|  1.88M|void ignore_params(T&&... args) {
  115|  1.88M|   (ignore_param(args), ...);
  116|  1.88M|}
_ZN5Botan12ignore_paramIRmEEvOT_:
  111|  1.88M|void ignore_param(T&&) {}
_ZN5Botan13ignore_paramsIJRKmEEEvDpOT_:
  114|  48.1k|void ignore_params(T&&... args) {
  115|  48.1k|   (ignore_param(args), ...);
  116|  48.1k|}
_ZN5Botan12ignore_paramIRKmEEvOT_:
  111|  48.1k|void ignore_param(T&&) {}

_ZN5Botan6BigIntD2Ev:
  148|   229k|      ~BigInt() { const_time_unpoison(); }
_ZNK5Botan6BigInt19const_time_unpoisonEv:
  726|   229k|      void const_time_unpoison() const {}
_ZN5Botan6BigInt6decodeEPKhm:
  776|  1.05k|      static BigInt decode(const uint8_t buf[], size_t length) { return BigInt(buf, length); }
_ZN5BotangtERKNS_6BigIntEm:
 1039|  28.5k|inline bool operator>(const BigInt& a, word b) {
 1040|  28.5k|   return (a.cmp_word(b) > 0);
 1041|  28.5k|}
_ZN5BotanneERKNS_6BigIntES2_:
  999|    671|inline bool operator!=(const BigInt& a, const BigInt& b) {
 1000|    671|   return !a.is_equal(b);
 1001|    671|}
_ZN5Botan6BigInt4zeroEv:
   45|  7.42k|      static BigInt zero() { return BigInt(); }
_ZN5Botan6BigInt3oneEv:
   50|      2|      static BigInt one() { return BigInt::from_word(1); }
_ZN5Botan6BigIntC2EOS0_:
  146|  44.1k|      BigInt(BigInt&& other) { this->swap(other); }
_ZN5Botan6BigIntaSEOS0_:
  153|  89.2k|      BigInt& operator=(BigInt&& other) {
  154|  89.2k|         if(this != &other) {
  ------------------
  |  Branch (154:13): [True: 89.2k, False: 0]
  ------------------
  155|  89.2k|            this->swap(other);
  156|  89.2k|         }
  157|       |
  158|  89.2k|         return (*this);
  159|  89.2k|      }
_ZN5Botan6BigInt4swapERS0_:
  170|   133k|      void swap(BigInt& other) {
  171|   133k|         m_data.swap(other.m_data);
  172|   133k|         std::swap(m_signedness, other.m_signedness);
  173|   133k|      }
_ZN5Botan6BigInt8swap_regERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  177|  14.1k|      void swap_reg(secure_vector<word>& reg) {
  178|  14.1k|         m_data.swap(reg);
  179|       |         // sign left unchanged
  180|  14.1k|      }
_ZN5Botan6BigIntpLERKS0_:
  186|  8.37k|      BigInt& operator+=(const BigInt& y) { return add(y.data(), y.sig_words(), y.sign()); }
_ZN5Botan6BigIntpLEm:
  192|  1.00k|      BigInt& operator+=(word y) { return add(&y, 1, Positive); }
_ZN5Botan6BigIntmIERKS0_:
  198|  8.37k|      BigInt& operator-=(const BigInt& y) { return sub(y.data(), y.sig_words(), y.sign()); }
_ZN5Botan6BigInt3subEPKmmNS0_4SignE:
  292|  8.37k|      BigInt& sub(const word y[], size_t y_words, Sign sign) {
  293|  8.37k|         return add(y, y_words, sign == Positive ? Negative : Positive);
  ------------------
  |  Branch (293:33): [True: 8.37k, False: 0]
  ------------------
  294|  8.37k|      }
_ZN5Botan6BigInt5clearEv:
  370|  3.18k|      void clear() {
  371|  3.18k|         m_data.set_to_zero();
  372|  3.18k|         m_signedness = Positive;
  373|  3.18k|      }
_ZNK5Botan6BigInt7is_evenEv:
  410|  1.81k|      bool is_even() const { return (get_bit(0) == 0); }
_ZNK5Botan6BigInt6is_oddEv:
  416|  1.81k|      bool is_odd() const { return (get_bit(0) == 1); }
_ZNK5Botan6BigInt10is_nonzeroEv:
  422|  5.45k|      bool is_nonzero() const { return (!is_zero()); }
_ZNK5Botan6BigInt7is_zeroEv:
  428|  64.1k|      bool is_zero() const { return (sig_words() == 0); }
_ZN5Botan6BigInt7set_bitEm:
  434|  1.37k|      void set_bit(size_t n) { conditionally_set_bit(n, true); }
_ZN5Botan6BigInt21conditionally_set_bitEmb:
  444|  2.27M|      void conditionally_set_bit(size_t n, bool set_it) {
  445|  2.27M|         const size_t which = n / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  2.27M|#define BOTAN_MP_WORD_BITS 64
  ------------------
  446|  2.27M|         const word mask = static_cast<word>(set_it) << (n % BOTAN_MP_WORD_BITS);
  ------------------
  |  |   50|  2.27M|#define BOTAN_MP_WORD_BITS 64
  ------------------
  447|  2.27M|         m_data.set_word_at(which, word_at(which) | mask);
  448|  2.27M|      }
_ZN5Botan6BigInt9mask_bitsEm:
  460|  5.45k|      void mask_bits(size_t n) { m_data.mask_bits(n); }
_ZNK5Botan6BigInt7get_bitEm:
  467|  1.92M|      bool get_bit(size_t n) const { return ((word_at(n / BOTAN_MP_WORD_BITS) >> (n % BOTAN_MP_WORD_BITS)) & 1); }
  ------------------
  |  |   50|  1.92M|#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|  1.92M|#define BOTAN_MP_WORD_BITS 64
  ------------------
_ZNK5Botan6BigInt7word_atEm:
  518|  4.63M|      word word_at(size_t n) const { return m_data.get_word_at(n); }
_ZN5Botan6BigInt11set_word_atEmm:
  520|   372k|      void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
_ZN5Botan6BigInt9set_wordsEPKmm:
  522|     43|      void set_words(const word w[], size_t len) { m_data.set_words(w, len); }
_ZNK5Botan6BigInt11is_negativeEv:
  528|   359k|      bool is_negative() const { return (sign() == Negative); }
_ZNK5Botan6BigInt11is_positiveEv:
  534|   104k|      bool is_positive() const { return (sign() == Positive); }
_ZNK5Botan6BigInt4signEv:
  540|   703k|      Sign sign() const { return (m_signedness); }
_ZNK5Botan6BigInt12reverse_signEv:
  545|  11.1k|      Sign reverse_sign() const {
  546|  11.1k|         if(sign() == Positive) {
  ------------------
  |  Branch (546:13): [True: 11.1k, False: 0]
  ------------------
  547|  11.1k|            return Negative;
  548|  11.1k|         }
  549|      0|         return Positive;
  550|  11.1k|      }
_ZN5Botan6BigInt9flip_signEv:
  555|    382|      void flip_sign() { set_sign(reverse_sign()); }
_ZN5Botan6BigInt8set_signENS0_4SignE:
  561|  85.1k|      void set_sign(Sign sign) {
  562|  85.1k|         if(sign == Negative && is_zero()) {
  ------------------
  |  Branch (562:13): [True: 395, False: 84.7k]
  |  Branch (562:33): [True: 0, False: 395]
  ------------------
  563|      0|            sign = Positive;
  564|      0|         }
  565|       |
  566|  85.1k|         m_signedness = sign;
  567|  85.1k|      }
_ZNK5Botan6BigInt4sizeEv:
  578|  2.82M|      size_t size() const { return m_data.size(); }
_ZNK5Botan6BigInt9sig_wordsEv:
  584|   533k|      size_t sig_words() const { return m_data.sig_words(); }
_ZN5Botan6BigInt12mutable_dataEv:
  609|  1.73M|      word* mutable_data() { return m_data.mutable_data(); }
_ZNK5Botan6BigInt4dataEv:
  615|  1.49M|      const word* data() const { return m_data.const_data(); }
_ZNK5Botan6BigInt15get_word_vectorEv:
  625|  44.0k|      const secure_vector<word>& get_word_vector() const { return m_data.const_vector(); }
_ZNK5Botan6BigInt7grow_toEm:
  631|   836k|      void grow_to(size_t n) const { m_data.grow_to(n); }
_ZNK5Botan6BigInt17const_time_poisonEv:
  724|    688|      void const_time_poison() const {}
_ZN5Botan6BigInt10power_of_2Em:
  742|    685|      static BigInt power_of_2(size_t n) {
  743|    685|         BigInt b;
  744|    685|         b.set_bit(n);
  745|    685|         return b;
  746|    685|      }
_ZN5Botan6BigInt4Data12mutable_dataEv:
  834|  1.79M|            word* mutable_data() {
  835|  1.79M|               invalidate_sig_words();
  836|  1.79M|               return m_reg.data();
  837|  1.79M|            }
_ZNK5Botan6BigInt4Data10const_dataEv:
  839|  1.49M|            const word* const_data() const { return m_reg.data(); }
_ZNK5Botan6BigInt4Data12const_vectorEv:
  846|  44.0k|            const secure_vector<word>& const_vector() const { return m_reg; }
_ZNK5Botan6BigInt4Data11get_word_atEm:
  848|  4.63M|            word get_word_at(size_t n) const {
  849|  4.63M|               if(n < m_reg.size()) {
  ------------------
  |  Branch (849:19): [True: 4.63M, False: 1.37k]
  ------------------
  850|  4.63M|                  return m_reg[n];
  851|  4.63M|               }
  852|  1.37k|               return 0;
  853|  4.63M|            }
_ZN5Botan6BigInt4Data11set_word_atEmm:
  855|  2.64M|            void set_word_at(size_t i, word w) {
  856|  2.64M|               invalidate_sig_words();
  857|  2.64M|               if(i >= m_reg.size()) {
  ------------------
  |  Branch (857:19): [True: 369k, False: 2.27M]
  ------------------
  858|   369k|                  if(w == 0) {
  ------------------
  |  Branch (858:22): [True: 351k, False: 17.9k]
  ------------------
  859|   351k|                     return;
  860|   351k|                  }
  861|  17.9k|                  grow_to(i + 1);
  862|  17.9k|               }
  863|  2.29M|               m_reg[i] = w;
  864|  2.29M|            }
_ZN5Botan6BigInt4Data9set_wordsEPKmm:
  866|     43|            void set_words(const word w[], size_t len) {
  867|     43|               invalidate_sig_words();
  868|     43|               m_reg.assign(w, w + len);
  869|     43|            }
_ZN5Botan6BigInt4Data11set_to_zeroEv:
  871|  3.18k|            void set_to_zero() {
  872|  3.18k|               m_reg.resize(m_reg.capacity());
  873|  3.18k|               clear_mem(m_reg.data(), m_reg.size());
  874|  3.18k|               m_sig_words = 0;
  875|  3.18k|            }
_ZN5Botan6BigInt4Data9mask_bitsEm:
  883|  5.45k|            void mask_bits(size_t n) {
  884|  5.45k|               if(n == 0) {
  ------------------
  |  Branch (884:19): [True: 0, False: 5.45k]
  ------------------
  885|      0|                  return set_to_zero();
  886|      0|               }
  887|       |
  888|  5.45k|               const size_t top_word = n / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  5.45k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  889|       |
  890|       |               // if(top_word < sig_words()) ?
  891|  5.45k|               if(top_word < size()) {
  ------------------
  |  Branch (891:19): [True: 5.41k, False: 39]
  ------------------
  892|  5.41k|                  const word mask = (static_cast<word>(1) << (n % BOTAN_MP_WORD_BITS)) - 1;
  ------------------
  |  |   50|  5.41k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  893|  5.41k|                  const size_t len = size() - (top_word + 1);
  894|  5.41k|                  if(len > 0) {
  ------------------
  |  Branch (894:22): [True: 5.41k, False: 0]
  ------------------
  895|  5.41k|                     clear_mem(&m_reg[top_word + 1], len);
  896|  5.41k|                  }
  897|  5.41k|                  m_reg[top_word] &= mask;
  898|  5.41k|                  invalidate_sig_words();
  899|  5.41k|               }
  900|  5.45k|            }
_ZNK5Botan6BigInt4Data7grow_toEm:
  902|   868k|            void grow_to(size_t n) const {
  903|   868k|               if(n > size()) {
  ------------------
  |  Branch (903:19): [True: 110k, False: 758k]
  ------------------
  904|   110k|                  if(n <= m_reg.capacity()) {
  ------------------
  |  Branch (904:22): [True: 8.07k, False: 102k]
  ------------------
  905|  8.07k|                     m_reg.resize(n);
  906|   102k|                  } else {
  907|   102k|                     m_reg.resize(n + (8 - (n % 8)));
  908|   102k|                  }
  909|   110k|               }
  910|   868k|            }
_ZNK5Botan6BigInt4Data4sizeEv:
  912|  3.76M|            size_t size() const { return m_reg.size(); }
_ZN5Botan6BigInt4Data4swapERS1_:
  921|   133k|            void swap(Data& other) {
  922|   133k|               m_reg.swap(other.m_reg);
  923|   133k|               std::swap(m_sig_words, other.m_sig_words);
  924|   133k|            }
_ZN5Botan6BigInt4Data4swapERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  926|  15.2k|            void swap(secure_vector<word>& reg) {
  927|  15.2k|               m_reg.swap(reg);
  928|  15.2k|               invalidate_sig_words();
  929|  15.2k|            }
_ZNK5Botan6BigInt4Data20invalidate_sig_wordsEv:
  931|  4.46M|            void invalidate_sig_words() const { m_sig_words = sig_words_npos; }
_ZNK5Botan6BigInt4Data9sig_wordsEv:
  933|   533k|            size_t sig_words() const {
  934|   533k|               if(m_sig_words == sig_words_npos) {
  ------------------
  |  Branch (934:19): [True: 195k, False: 338k]
  ------------------
  935|   195k|                  m_sig_words = calc_sig_words();
  936|   338k|               } else {
  937|   338k|                  BOTAN_DEBUG_ASSERT(m_sig_words == calc_sig_words());
  ------------------
  |  |   99|   338k|      do {                          \
  |  |  100|   338k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  938|   338k|               }
  939|   533k|               return m_sig_words;
  940|   533k|            }
_ZN5BotanplERKNS_6BigIntES2_:
  958|    808|inline BigInt operator+(const BigInt& x, const BigInt& y) {
  959|    808|   return BigInt::add2(x, y.data(), y.sig_words(), y.sign());
  960|    808|}
_ZN5BotanplERKNS_6BigIntEm:
  962|    671|inline BigInt operator+(const BigInt& x, word y) {
  963|    671|   return BigInt::add2(x, &y, 1, BigInt::Positive);
  964|    671|}
_ZN5BotanmiERKNS_6BigIntES2_:
  970|  10.7k|inline BigInt operator-(const BigInt& x, const BigInt& y) {
  971|  10.7k|   return BigInt::add2(x, y.data(), y.sig_words(), y.reverse_sign());
  972|  10.7k|}
_ZN5BotanmiERKNS_6BigIntEm:
  974|     43|inline BigInt operator-(const BigInt& x, word y) {
  975|     43|   return BigInt::add2(x, &y, 1, BigInt::Negative);
  976|     43|}
_ZN5BotanmlEmRKNS_6BigIntE:
  981|  16.7k|inline BigInt operator*(word x, const BigInt& y) {
  982|  16.7k|   return y * x;
  983|  16.7k|}
_ZN5BotaneqERKNS_6BigIntES2_:
  995|     44|inline bool operator==(const BigInt& a, const BigInt& b) {
  996|     44|   return a.is_equal(b);
  997|     44|}
_ZN5BotanleERKNS_6BigIntES2_:
 1003|     86|inline bool operator<=(const BigInt& a, const BigInt& b) {
 1004|     86|   return (a.cmp(b) <= 0);
 1005|     86|}
_ZN5BotangeERKNS_6BigIntES2_:
 1007|     52|inline bool operator>=(const BigInt& a, const BigInt& b) {
 1008|     52|   return (a.cmp(b) >= 0);
 1009|     52|}
_ZN5BotanltERKNS_6BigIntES2_:
 1011|  28.1k|inline bool operator<(const BigInt& a, const BigInt& b) {
 1012|  28.1k|   return a.is_less_than(b);
 1013|  28.1k|}
_ZN5BotangtERKNS_6BigIntES2_:
 1015|  24.5k|inline bool operator>(const BigInt& a, const BigInt& b) {
 1016|  24.5k|   return b.is_less_than(a);
 1017|  24.5k|}
_ZN5BotaneqERKNS_6BigIntEm:
 1019|  1.11k|inline bool operator==(const BigInt& a, word b) {
 1020|  1.11k|   return (a.cmp_word(b) == 0);
 1021|  1.11k|}
_ZN5BotanleERKNS_6BigIntEm:
 1027|  1.05k|inline bool operator<=(const BigInt& a, word b) {
 1028|  1.05k|   return (a.cmp_word(b) <= 0);
 1029|  1.05k|}
_ZN5BotangeERKNS_6BigIntEm:
 1031|  1.05k|inline bool operator>=(const BigInt& a, word b) {
 1032|  1.05k|   return (a.cmp_word(b) >= 0);
 1033|  1.05k|}
_ZN5BotanltERKNS_6BigIntEm:
 1035|  2.48k|inline bool operator<(const BigInt& a, word b) {
 1036|  2.48k|   return (a.cmp_word(b) < 0);
 1037|  2.48k|}
_ZN5Botan6BigIntC2Ev:
   40|   162k|      BigInt() = default;
_ZN5Botan6BigIntC2ERKS0_:
   80|  21.5k|      BigInt(const BigInt& other) = default;
_ZN5Botan6BigIntaSERKS0_:
  164|  58.7k|      BigInt& operator=(const BigInt&) = default;
_ZN5Botan6BigInt13binary_decodeINS_16secure_allocatorIhEEEEvRKNSt3__16vectorIhT_EE:
  682|     53|      void binary_decode(const std::vector<uint8_t, Alloc>& buf) {
  683|     53|         binary_decode(buf.data(), buf.size());
  684|     53|      }

_ZN5Botan20Buffered_Computation6updateENSt3__14spanIKhLm18446744073709551615EEE:
   41|     10|      void update(std::span<const uint8_t> in) { add_data(in); }
_ZN5Botan20Buffered_Computation5finalENSt3__14spanIhLm18446744073709551615EEE:
   86|      4|      void final(std::span<uint8_t> out) {
   87|      4|         BOTAN_ARG_CHECK(out.size() >= output_length(), "provided output buffer has insufficient capacity");
  ------------------
  |  |   30|      4|   do {                                                          \
  |  |   31|      4|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 4]
  |  |  ------------------
  |  |   32|      4|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|      4|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   88|      4|         final_result(out);
   89|      4|      }
_ZN5Botan20Buffered_Computation5finalINSt3__16vectorIhNS_16secure_allocatorIhEEEEEET_v:
   78|      2|      T final() {
   79|      2|         T output(output_length());
   80|      2|         final_result(output);
   81|      2|         return output;
   82|      2|      }
_ZN5Botan20Buffered_ComputationD2Ev:
  134|      2|      virtual ~Buffered_Computation() = default;

_ZNK5Botan10ChaCha_RNG31max_number_of_bytes_per_requestEv:
  106|     53|      size_t max_number_of_bytes_per_request() const override { return 0; }

_ZN5Botan6ranges24assert_exact_byte_lengthILm8ERNSt3__14spanIhLm8EEEEEvOT0_:
   86|      4|inline constexpr void assert_exact_byte_length(R&& r) {
   87|      4|   const std::span s{r};
   88|      4|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|      4|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|      4|   } else {
   91|      4|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|      4|   }
   93|      4|}
_ZN5Botan6ranges25assert_equal_byte_lengthsIRNSt3__14spanIhLm8EEEJRNS3_IKmLm1EEEEEEvOT_DpOT0_:
  107|      4|{
  108|      4|   const std::span s0{r0};
  109|       |
  110|      4|   if constexpr(decltype(s0)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (110:17): [Folded - Ignored]
  ------------------
  111|      4|      constexpr size_t expected_size = s0.size_bytes();
  112|      4|      (assert_exact_byte_length<expected_size>(rs), ...);
  113|      4|   } else {
  114|      4|      const size_t expected_size = s0.size_bytes();
  115|      4|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  116|      4|                      "memory regions don't have equal lengths");
  117|      4|   }
  118|      4|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ERNSt3__14spanIKmLm1EEEEEvOT0_:
   86|      4|inline constexpr void assert_exact_byte_length(R&& r) {
   87|      4|   const std::span s{r};
   88|      4|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|      4|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|      4|   } else {
   91|      4|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|      4|   }
   93|      4|}
_ZN5Botan6ranges10size_bytesIRNSt3__14spanIhLm8EEEEEmOT_:
   73|      4|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   74|      4|   return std::span{r}.size_bytes();
   75|      4|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ERNSt3__14spanIKhLm8EEEEEvOT0_:
   86|  2.38k|inline constexpr void assert_exact_byte_length(R&& r) {
   87|  2.38k|   const std::span s{r};
   88|  2.38k|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|  2.38k|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|  2.38k|   } else {
   91|  2.38k|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|  2.38k|   }
   93|  2.38k|}
_ZN5Botan6ranges25assert_equal_byte_lengthsIRNSt3__14spanImLm1EEEJRNS3_IKhLm8EEEEEEvOT_DpOT0_:
  107|  1.19k|{
  108|  1.19k|   const std::span s0{r0};
  109|       |
  110|  1.19k|   if constexpr(decltype(s0)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (110:17): [Folded - Ignored]
  ------------------
  111|  1.19k|      constexpr size_t expected_size = s0.size_bytes();
  112|  1.19k|      (assert_exact_byte_length<expected_size>(rs), ...);
  113|  1.19k|   } else {
  114|  1.19k|      const size_t expected_size = s0.size_bytes();
  115|  1.19k|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  116|  1.19k|                      "memory regions don't have equal lengths");
  117|  1.19k|   }
  118|  1.19k|}
_ZN5Botan6ranges10size_bytesIRNSt3__14spanImLm1EEEEEmOT_:
   73|  1.19k|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   74|  1.19k|   return std::span{r}.size_bytes();
   75|  1.19k|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm4ERNSt3__14spanIKhLm4EEEEEvOT0_:
   86|    320|inline constexpr void assert_exact_byte_length(R&& r) {
   87|    320|   const std::span s{r};
   88|    320|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|    320|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|    320|   } else {
   91|    320|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|    320|   }
   93|    320|}
_ZN5Botan6ranges25assert_equal_byte_lengthsIRNSt3__14spanIjLm1EEEJRNS3_IKhLm4EEEEEEvOT_DpOT0_:
  107|    160|{
  108|    160|   const std::span s0{r0};
  109|       |
  110|    160|   if constexpr(decltype(s0)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (110:17): [Folded - Ignored]
  ------------------
  111|    160|      constexpr size_t expected_size = s0.size_bytes();
  112|    160|      (assert_exact_byte_length<expected_size>(rs), ...);
  113|    160|   } else {
  114|    160|      const size_t expected_size = s0.size_bytes();
  115|    160|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  116|    160|                      "memory regions don't have equal lengths");
  117|    160|   }
  118|    160|}
_ZN5Botan6ranges10size_bytesIRNSt3__14spanIjLm1EEEEEmOT_:
   73|    160|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   74|    160|   return std::span{r}.size_bytes();
   75|    160|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm4ERNSt3__14spanIhLm4EEEEEvOT0_:
   86|     32|inline constexpr void assert_exact_byte_length(R&& r) {
   87|     32|   const std::span s{r};
   88|     32|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|     32|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|     32|   } else {
   91|     32|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|     32|   }
   93|     32|}
_ZN5Botan6ranges25assert_equal_byte_lengthsIRNSt3__14spanIhLm4EEEJRNS3_IKjLm1EEEEEEvOT_DpOT0_:
  107|     32|{
  108|     32|   const std::span s0{r0};
  109|       |
  110|     32|   if constexpr(decltype(s0)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (110:17): [Folded - Ignored]
  ------------------
  111|     32|      constexpr size_t expected_size = s0.size_bytes();
  112|     32|      (assert_exact_byte_length<expected_size>(rs), ...);
  113|     32|   } else {
  114|     32|      const size_t expected_size = s0.size_bytes();
  115|     32|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  116|     32|                      "memory regions don't have equal lengths");
  117|     32|   }
  118|     32|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm4ERNSt3__14spanIKjLm1EEEEEvOT0_:
   86|     32|inline constexpr void assert_exact_byte_length(R&& r) {
   87|     32|   const std::span s{r};
   88|     32|   if constexpr(decltype(s)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (88:17): [Folded - Ignored]
  ------------------
   89|     32|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   90|     32|   } else {
   91|     32|      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   92|     32|   }
   93|     32|}
_ZN5Botan6ranges10size_bytesIRNSt3__14spanIhLm4EEEEEmOT_:
   73|     32|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   74|     32|   return std::span{r}.size_bytes();
   75|     32|}
_ZN5Botan6ranges25assert_equal_byte_lengthsIRNSt3__14spanIjLm18446744073709551615EEEJRNS3_IKhLm18446744073709551615EEEEEEvOT_DpOT0_:
  107|      2|{
  108|      2|   const std::span s0{r0};
  109|       |
  110|      2|   if constexpr(decltype(s0)::extent != std::dynamic_extent) {
  ------------------
  |  Branch (110:17): [Folded - Ignored]
  ------------------
  111|      2|      constexpr size_t expected_size = s0.size_bytes();
  112|      2|      (assert_exact_byte_length<expected_size>(rs), ...);
  113|      2|   } else {
  114|      2|      const size_t expected_size = s0.size_bytes();
  115|      2|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  ------------------
  |  |   30|      2|   do {                                                          \
  |  |   31|      2|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 2]
  |  |  ------------------
  |  |   32|      2|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|      2|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  116|      2|                      "memory regions don't have equal lengths");
  117|      2|   }
  118|      2|}
_ZN5Botan6ranges10size_bytesIRNSt3__14spanIjLm18446744073709551615EEEEEmOT_:
   73|      2|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   74|      2|   return std::span{r}.size_bytes();
   75|      2|}

_ZN5Botan25MessageAuthenticationCodeD2Ev:
   50|      1|      ~MessageAuthenticationCode() override = default;

_ZN5Botan11clear_bytesEPvm:
  103|   584k|inline constexpr void clear_bytes(void* ptr, size_t bytes) {
  104|   584k|   if(bytes > 0) {
  ------------------
  |  Branch (104:7): [True: 535k, False: 48.6k]
  ------------------
  105|   535k|      std::memset(ptr, 0, bytes);
  106|   535k|   }
  107|   584k|}
_ZN5Botan9clear_memImEEvPT_m:
  120|   584k|inline constexpr void clear_mem(T* ptr, size_t n) {
  121|   584k|   clear_bytes(ptr, sizeof(T) * n);
  122|   584k|}
_ZN5Botan8copy_memImEEvPT_PKS1_m:
  146|   295k|inline constexpr void copy_mem(T* out, const T* in, size_t n) {
  147|   295k|   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
  ------------------
  |  |   78|   295k|   do {                                                                                          \
  |  |   79|   590k|      if((expr1) && !(expr2))                                                                    \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 295k, False: 0]
  |  |  |  Branch (79:23): [True: 295k, False: 0]
  |  |  |  Branch (79:23): [True: 295k, False: 0]
  |  |  ------------------
  |  |   80|   295k|         Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, __LINE__); \
  |  |   81|   295k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (81:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  148|       |
  149|   295k|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (149:7): [True: 295k, False: 0]
  |  Branch (149:24): [True: 295k, False: 0]
  |  Branch (149:42): [True: 295k, False: 0]
  ------------------
  150|   295k|      std::memmove(out, in, sizeof(T) * n);
  151|   295k|   }
  152|   295k|}
_ZN5Botan13typecast_copyIRNSt3__14spanIhLm8EEEmEEvOT_RKT0_:
  199|      4|inline constexpr void typecast_copy(ToR&& out, const FromT& in) {
  200|      4|   typecast_copy(out, std::span<const FromT, 1>(&in, 1));
  201|      4|}
_ZN5Botan13typecast_copyIRNSt3__14spanIhLm8EEENS2_IKmLm1EEEEEvOT_OT0_:
  176|      4|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  177|      4|   ranges::assert_equal_byte_lengths(out, in);
  178|      4|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|      4|}
_ZN5Botan13typecast_copyImRNSt3__14spanIKhLm8EEEEET_OT0_:
  209|  1.19k|inline constexpr ToT typecast_copy(FromR&& src) noexcept {
  210|  1.19k|   ToT dst;
  211|  1.19k|   typecast_copy(dst, src);
  212|  1.19k|   return dst;
  213|  1.19k|}
_ZN5Botan13typecast_copyImRNSt3__14spanIKhLm8EEEEEvRT_OT0_:
  188|  1.19k|inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
  189|  1.19k|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|  1.19k|}
_ZN5Botan13typecast_copyINSt3__14spanImLm1EEERNS2_IKhLm8EEEEEvOT_OT0_:
  176|  1.19k|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  177|  1.19k|   ranges::assert_equal_byte_lengths(out, in);
  178|  1.19k|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|  1.19k|}
_ZN5Botan13typecast_copyIjRNSt3__14spanIKhLm4EEEEET_OT0_:
  209|    160|inline constexpr ToT typecast_copy(FromR&& src) noexcept {
  210|    160|   ToT dst;
  211|    160|   typecast_copy(dst, src);
  212|    160|   return dst;
  213|    160|}
_ZN5Botan13typecast_copyIjRNSt3__14spanIKhLm4EEEEEvRT_OT0_:
  188|    160|inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
  189|    160|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|    160|}
_ZN5Botan13typecast_copyINSt3__14spanIjLm1EEERNS2_IKhLm4EEEEEvOT_OT0_:
  176|    160|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  177|    160|   ranges::assert_equal_byte_lengths(out, in);
  178|    160|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|    160|}
_ZN5Botan9clear_memIhEEvPT_m:
  120|     15|inline constexpr void clear_mem(T* ptr, size_t n) {
  121|     15|   clear_bytes(ptr, sizeof(T) * n);
  122|     15|}
_ZN5Botan13typecast_copyIRNSt3__14spanIhLm4EEEjEEvOT_RKT0_:
  199|     32|inline constexpr void typecast_copy(ToR&& out, const FromT& in) {
  200|     32|   typecast_copy(out, std::span<const FromT, 1>(&in, 1));
  201|     32|}
_ZN5Botan13typecast_copyIRNSt3__14spanIhLm4EEENS2_IKjLm1EEEEEvOT_OT0_:
  176|     32|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  177|     32|   ranges::assert_equal_byte_lengths(out, in);
  178|     32|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|     32|}
_ZN5Botan8copy_memIhEEvPT_PKS1_m:
  146|     57|inline constexpr void copy_mem(T* out, const T* in, size_t n) {
  147|     57|   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
  ------------------
  |  |   78|     57|   do {                                                                                          \
  |  |   79|    108|      if((expr1) && !(expr2))                                                                    \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 54, False: 3]
  |  |  |  Branch (79:23): [True: 54, False: 0]
  |  |  |  Branch (79:23): [True: 54, False: 0]
  |  |  ------------------
  |  |   80|     57|         Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, __LINE__); \
  |  |   81|     57|   } while(0)
  |  |  ------------------
  |  |  |  Branch (81:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  148|       |
  149|     57|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (149:7): [True: 57, False: 0]
  |  Branch (149:24): [True: 57, False: 0]
  |  Branch (149:42): [True: 54, False: 3]
  ------------------
  150|     54|      std::memmove(out, in, sizeof(T) * n);
  151|     54|   }
  152|     57|}
_ZN5Botan9clear_memIjEEvPT_m:
  120|      1|inline constexpr void clear_mem(T* ptr, size_t n) {
  121|      1|   clear_bytes(ptr, sizeof(T) * n);
  122|      1|}
_ZN5Botan13typecast_copyIjEEvPT_PKhm:
  228|      2|{
  229|       |   // asserts that *in and *out point to the correct amount of memory
  230|      2|   typecast_copy(std::span<T>(out, N), std::span<const uint8_t>(in, N * sizeof(T)));
  231|      2|}
_ZN5Botan13typecast_copyINSt3__14spanIjLm18446744073709551615EEENS2_IKhLm18446744073709551615EEEEEvOT_OT0_:
  176|      2|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  177|      2|   ranges::assert_equal_byte_lengths(out, in);
  178|      2|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|      2|}

_ZNK5Botan15Modular_Reducer6squareERKNS_6BigIntE:
   43|  1.88k|      BigInt square(const BigInt& x) const { return reduce(Botan::square(x)); }
_ZNK5Botan15Modular_Reducer8multiplyERKNS_6BigIntES3_:
   30|  1.19k|      BigInt multiply(const BigInt& x, const BigInt& y) const { return reduce(x * y); }

_ZN5Botan21RandomNumberGeneratorD2Ev:
   32|      1|      virtual ~RandomNumberGenerator() = default;
_ZN5Botan21RandomNumberGenerator9randomizeENSt3__14spanIhLm18446744073709551615EEE:
   52|     53|      void randomize(std::span<uint8_t> output) { this->fill_bytes_with_input(output, {}); }
_ZN5Botan21RandomNumberGenerator11add_entropyENSt3__14spanIKhLm18446744073709551615EEE:
   75|      1|      void add_entropy(std::span<const uint8_t> input) { this->fill_bytes_with_input({}, input); }
_ZN5Botan21RandomNumberGenerator10random_vecENSt3__14spanIhLm18446744073709551615EEE:
  179|     53|      void random_vec(std::span<uint8_t> v) { this->randomize(v); }
_ZN5Botan21RandomNumberGeneratorC2Ev:
   34|      1|      RandomNumberGenerator() = default;
_ZN5Botan21RandomNumberGenerator10random_vecINSt3__16vectorIhNS_16secure_allocatorIhEEEEEET_m:
  205|     53|      T random_vec(size_t bytes) {
  206|     53|         T result;
  207|     53|         random_vec(result, bytes);
  208|     53|         return result;
  209|     53|      }
_ZN5Botan21RandomNumberGenerator10random_vecINSt3__16vectorIhNS_16secure_allocatorIhEEEEEEvRT_m:
  190|     53|      void random_vec(T& v, size_t bytes) {
  191|     53|         v.resize(bytes);
  192|     53|         random_vec(v);
  193|     53|      }

_ZN5Botan16secure_allocatorIhE8allocateEm:
   45|     60|      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
_ZN5Botan16secure_allocatorIhE10deallocateEPhm:
   47|     60|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorImE10deallocateEPmm:
   47|   220k|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorImE8allocateEm:
   45|   220k|      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }
_ZN5Botan16secure_allocatorIjE10deallocateEPjm:
   47|      3|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorIjE8allocateEm:
   45|      3|      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }

_ZN5Botan12Stateful_RNGC2Ev:
   58|      1|      Stateful_RNG() : m_reseed_interval(0) {}

_ZN5Botan12StreamCipher15write_keystreamENSt3__14spanIhLm18446744073709551615EEE:
   87|     54|      void write_keystream(std::span<uint8_t> out) { generate_keystream(out.data(), out.size()); }
_ZN5Botan12StreamCipher6set_ivEPKhm:
  157|      2|      void set_iv(const uint8_t iv[], size_t iv_len) { set_iv_bytes(iv, iv_len); }
_ZN5Botan12StreamCipher15keystream_bytesINSt3__16vectorIhNS_16secure_allocatorIhEEEEEET_m:
   95|      1|      T keystream_bytes(size_t bytes) {
   96|      1|         T out(bytes);
   97|      1|         write_keystream(out);
   98|      1|         return out;
   99|      1|      }

_ZN5Botan24Key_Length_SpecificationC2Emmm:
   36|      4|            m_min_keylen(min_k), m_max_keylen(max_k ? max_k : min_k), m_keylen_mod(k_mod) {}
_ZNK5Botan24Key_Length_Specification15valid_keylengthEm:
   42|      4|      bool valid_keylength(size_t length) const {
   43|      4|         return ((length >= m_min_keylen) && (length <= m_max_keylen) && (length % m_keylen_mod == 0));
  ------------------
  |  Branch (43:18): [True: 4, False: 0]
  |  Branch (43:46): [True: 4, False: 0]
  |  Branch (43:74): [True: 4, False: 0]
  ------------------
   44|      4|      }
_ZNK5Botan18SymmetricAlgorithm15valid_keylengthEm:
  107|      4|      bool valid_keylength(size_t length) const { return key_spec().valid_keylength(length); }
_ZNK5Botan18SymmetricAlgorithm23assert_key_material_setEv:
  139|     59|      void assert_key_material_set() const { assert_key_material_set(has_keying_material()); }
_ZNK5Botan18SymmetricAlgorithm23assert_key_material_setEb:
  141|     59|      void assert_key_material_set(bool predicate) const {
  142|     59|         if(!predicate) {
  ------------------
  |  Branch (142:13): [True: 0, False: 59]
  ------------------
  143|      0|            throw_key_not_set_error();
  144|      0|         }
  145|     59|      }
_ZN5Botan18SymmetricAlgorithmD2Ev:
   79|      2|      virtual ~SymmetricAlgorithm() = default;

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|  1.09k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) {
   35|  1.09k|   if(len <= max_fuzzer_input_size) {
  ------------------
  |  Branch (35:7): [True: 1.08k, False: 10]
  ------------------
   36|  1.08k|      fuzz(in, len);
   37|  1.08k|   }
   38|  1.09k|   return 0;
   39|  1.09k|}
_Z10fuzzer_rngv:
   49|      1|inline Botan::RandomNumberGenerator& fuzzer_rng() {
   50|      1|   return *fuzzer_rng_as_shared();
   51|      1|}
_Z20fuzzer_rng_as_sharedv:
   43|      1|inline std::shared_ptr<Botan::RandomNumberGenerator> fuzzer_rng_as_shared() {
   44|      1|   static std::shared_ptr<Botan::ChaCha_RNG> rng =
   45|      1|      std::make_shared<Botan::ChaCha_RNG>(Botan::secure_vector<uint8_t>(32));
   46|      1|   return rng;
   47|      1|}

_Z4fuzzPKhm:
   12|  1.08k|void fuzz(const uint8_t in[], size_t len) {
   13|       |   // Ressol is mostly used for ECC point decompression so best to test smaller sizes
   14|  1.08k|   static const size_t p_bits = 256;
   15|  1.08k|   static const Botan::BigInt p = random_prime(fuzzer_rng(), p_bits);
   16|  1.08k|   static const Botan::Modular_Reducer mod_p(p);
   17|       |
   18|  1.08k|   if(len > p_bits / 8) {
  ------------------
  |  Branch (18:7): [True: 26, False: 1.05k]
  ------------------
   19|     26|      return;
   20|     26|   }
   21|       |
   22|  1.05k|   try {
   23|  1.05k|      const Botan::BigInt a = Botan::BigInt::decode(in, len);
   24|  1.05k|      Botan::BigInt a_sqrt = Botan::sqrt_modulo_prime(a, p);
   25|       |
   26|  1.05k|      if(a_sqrt > 0) {
  ------------------
  |  Branch (26:10): [True: 671, False: 384]
  ------------------
   27|    671|         const Botan::BigInt a_redc = mod_p.reduce(a);
   28|    671|         const Botan::BigInt z = mod_p.square(a_sqrt);
   29|       |
   30|    671|         if(z != a_redc) {
  ------------------
  |  Branch (30:13): [True: 0, False: 671]
  ------------------
   31|      0|            FUZZER_WRITE_AND_CRASH("A = " << a << "\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]
  |  |  ------------------
  ------------------
   32|      0|                                          << "P = " << p << "\n"
   33|      0|                                          << "R = " << a_sqrt << "\n"
   34|      0|                                          << "Z = " << z << "\n");
   35|      0|         }
   36|    671|      }
   37|  1.05k|   } catch(Botan::Exception& e) {}
   38|  1.05k|}

_ZN5Botan18SymmetricAlgorithm7set_keyENSt3__14spanIKhLm18446744073709551615EEE:
   17|      4|void SymmetricAlgorithm::set_key(std::span<const uint8_t> key) {
   18|      4|   if(!valid_keylength(key.size())) {
  ------------------
  |  Branch (18:7): [True: 0, False: 4]
  ------------------
   19|      0|      throw Invalid_Key_Length(name(), key.size());
   20|      0|   }
   21|      4|   key_schedule(key);
   22|      4|}

_ZN5Botan12HashFunction6createENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_:
  107|      1|std::unique_ptr<HashFunction> HashFunction::create(std::string_view algo_spec, std::string_view provider) {
  108|       |#if defined(BOTAN_HAS_COMMONCRYPTO)
  109|       |   if(provider.empty() || provider == "commoncrypto") {
  110|       |      if(auto hash = make_commoncrypto_hash(algo_spec))
  111|       |         return hash;
  112|       |
  113|       |      if(!provider.empty())
  114|       |         return nullptr;
  115|       |   }
  116|       |#endif
  117|       |
  118|      1|   if(provider.empty() == false && provider != "base") {
  ------------------
  |  Branch (118:7): [True: 0, False: 1]
  |  Branch (118:36): [True: 0, False: 0]
  ------------------
  119|      0|      return nullptr;  // unknown provider
  120|      0|   }
  121|       |
  122|      1|#if defined(BOTAN_HAS_SHA1)
  123|      1|   if(algo_spec == "SHA-1") {
  ------------------
  |  Branch (123:7): [True: 0, False: 1]
  ------------------
  124|      0|      return std::make_unique<SHA_1>();
  125|      0|   }
  126|      1|#endif
  127|       |
  128|      1|#if defined(BOTAN_HAS_SHA2_32)
  129|      1|   if(algo_spec == "SHA-224") {
  ------------------
  |  Branch (129:7): [True: 0, False: 1]
  ------------------
  130|      0|      return std::make_unique<SHA_224>();
  131|      0|   }
  132|       |
  133|      1|   if(algo_spec == "SHA-256") {
  ------------------
  |  Branch (133:7): [True: 1, False: 0]
  ------------------
  134|      1|      return std::make_unique<SHA_256>();
  135|      1|   }
  136|      0|#endif
  137|       |
  138|      0|#if defined(BOTAN_HAS_SHA2_64)
  139|      0|   if(algo_spec == "SHA-384") {
  ------------------
  |  Branch (139:7): [True: 0, False: 0]
  ------------------
  140|      0|      return std::make_unique<SHA_384>();
  141|      0|   }
  142|       |
  143|      0|   if(algo_spec == "SHA-512") {
  ------------------
  |  Branch (143:7): [True: 0, False: 0]
  ------------------
  144|      0|      return std::make_unique<SHA_512>();
  145|      0|   }
  146|       |
  147|      0|   if(algo_spec == "SHA-512-256") {
  ------------------
  |  Branch (147:7): [True: 0, False: 0]
  ------------------
  148|      0|      return std::make_unique<SHA_512_256>();
  149|      0|   }
  150|      0|#endif
  151|       |
  152|      0|#if defined(BOTAN_HAS_RIPEMD_160)
  153|      0|   if(algo_spec == "RIPEMD-160") {
  ------------------
  |  Branch (153:7): [True: 0, False: 0]
  ------------------
  154|      0|      return std::make_unique<RIPEMD_160>();
  155|      0|   }
  156|      0|#endif
  157|       |
  158|      0|#if defined(BOTAN_HAS_WHIRLPOOL)
  159|      0|   if(algo_spec == "Whirlpool") {
  ------------------
  |  Branch (159:7): [True: 0, False: 0]
  ------------------
  160|      0|      return std::make_unique<Whirlpool>();
  161|      0|   }
  162|      0|#endif
  163|       |
  164|      0|#if defined(BOTAN_HAS_MD5)
  165|      0|   if(algo_spec == "MD5") {
  ------------------
  |  Branch (165:7): [True: 0, False: 0]
  ------------------
  166|      0|      return std::make_unique<MD5>();
  167|      0|   }
  168|      0|#endif
  169|       |
  170|      0|#if defined(BOTAN_HAS_MD4)
  171|      0|   if(algo_spec == "MD4") {
  ------------------
  |  Branch (171:7): [True: 0, False: 0]
  ------------------
  172|      0|      return std::make_unique<MD4>();
  173|      0|   }
  174|      0|#endif
  175|       |
  176|      0|#if defined(BOTAN_HAS_GOST_34_11)
  177|      0|   if(algo_spec == "GOST-R-34.11-94" || algo_spec == "GOST-34.11") {
  ------------------
  |  Branch (177:7): [True: 0, False: 0]
  |  Branch (177:41): [True: 0, False: 0]
  ------------------
  178|      0|      return std::make_unique<GOST_34_11>();
  179|      0|   }
  180|      0|#endif
  181|       |
  182|      0|#if defined(BOTAN_HAS_ADLER32)
  183|      0|   if(algo_spec == "Adler32") {
  ------------------
  |  Branch (183:7): [True: 0, False: 0]
  ------------------
  184|      0|      return std::make_unique<Adler32>();
  185|      0|   }
  186|      0|#endif
  187|       |
  188|      0|#if defined(BOTAN_HAS_CRC24)
  189|      0|   if(algo_spec == "CRC24") {
  ------------------
  |  Branch (189:7): [True: 0, False: 0]
  ------------------
  190|      0|      return std::make_unique<CRC24>();
  191|      0|   }
  192|      0|#endif
  193|       |
  194|      0|#if defined(BOTAN_HAS_CRC32)
  195|      0|   if(algo_spec == "CRC32") {
  ------------------
  |  Branch (195:7): [True: 0, False: 0]
  ------------------
  196|      0|      return std::make_unique<CRC32>();
  197|      0|   }
  198|      0|#endif
  199|       |
  200|      0|#if defined(BOTAN_HAS_STREEBOG)
  201|      0|   if(algo_spec == "Streebog-256") {
  ------------------
  |  Branch (201:7): [True: 0, False: 0]
  ------------------
  202|      0|      return std::make_unique<Streebog>(256);
  203|      0|   }
  204|      0|   if(algo_spec == "Streebog-512") {
  ------------------
  |  Branch (204:7): [True: 0, False: 0]
  ------------------
  205|      0|      return std::make_unique<Streebog>(512);
  206|      0|   }
  207|      0|#endif
  208|       |
  209|      0|#if defined(BOTAN_HAS_SM3)
  210|      0|   if(algo_spec == "SM3") {
  ------------------
  |  Branch (210:7): [True: 0, False: 0]
  ------------------
  211|      0|      return std::make_unique<SM3>();
  212|      0|   }
  213|      0|#endif
  214|       |
  215|      0|   const SCAN_Name req(algo_spec);
  216|       |
  217|      0|#if defined(BOTAN_HAS_SKEIN_512)
  218|      0|   if(req.algo_name() == "Skein-512") {
  ------------------
  |  Branch (218:7): [True: 0, False: 0]
  ------------------
  219|      0|      return std::make_unique<Skein_512>(req.arg_as_integer(0, 512), req.arg(1, ""));
  220|      0|   }
  221|      0|#endif
  222|       |
  223|      0|#if defined(BOTAN_HAS_BLAKE2B)
  224|      0|   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") {
  ------------------
  |  Branch (224:7): [True: 0, False: 0]
  |  Branch (224:39): [True: 0, False: 0]
  ------------------
  225|      0|      return std::make_unique<BLAKE2b>(req.arg_as_integer(0, 512));
  226|      0|   }
  227|      0|#endif
  228|       |
  229|      0|#if defined(BOTAN_HAS_BLAKE2S)
  230|      0|   if(req.algo_name() == "Blake2s" || req.algo_name() == "BLAKE2s") {
  ------------------
  |  Branch (230:7): [True: 0, False: 0]
  |  Branch (230:39): [True: 0, False: 0]
  ------------------
  231|      0|      return std::make_unique<BLAKE2s>(req.arg_as_integer(0, 256));
  232|      0|   }
  233|      0|#endif
  234|       |
  235|      0|#if defined(BOTAN_HAS_KECCAK)
  236|      0|   if(req.algo_name() == "Keccak-1600") {
  ------------------
  |  Branch (236:7): [True: 0, False: 0]
  ------------------
  237|      0|      return std::make_unique<Keccak_1600>(req.arg_as_integer(0, 512));
  238|      0|   }
  239|      0|#endif
  240|       |
  241|      0|#if defined(BOTAN_HAS_SHA3)
  242|      0|   if(req.algo_name() == "SHA-3") {
  ------------------
  |  Branch (242:7): [True: 0, False: 0]
  ------------------
  243|      0|      return std::make_unique<SHA_3>(req.arg_as_integer(0, 512));
  244|      0|   }
  245|      0|#endif
  246|       |
  247|      0|#if defined(BOTAN_HAS_SHAKE)
  248|      0|   if(req.algo_name() == "SHAKE-128" && req.arg_count() == 1) {
  ------------------
  |  Branch (248:7): [True: 0, False: 0]
  |  Branch (248:41): [True: 0, False: 0]
  ------------------
  249|      0|      return std::make_unique<SHAKE_128>(req.arg_as_integer(0));
  250|      0|   }
  251|      0|   if(req.algo_name() == "SHAKE-256" && req.arg_count() == 1) {
  ------------------
  |  Branch (251:7): [True: 0, False: 0]
  |  Branch (251:41): [True: 0, False: 0]
  ------------------
  252|      0|      return std::make_unique<SHAKE_256>(req.arg_as_integer(0));
  253|      0|   }
  254|      0|#endif
  255|       |
  256|      0|#if defined(BOTAN_HAS_PARALLEL_HASH)
  257|      0|   if(req.algo_name() == "Parallel") {
  ------------------
  |  Branch (257:7): [True: 0, False: 0]
  ------------------
  258|      0|      std::vector<std::unique_ptr<HashFunction>> hashes;
  259|       |
  260|      0|      for(size_t i = 0; i != req.arg_count(); ++i) {
  ------------------
  |  Branch (260:25): [True: 0, False: 0]
  ------------------
  261|      0|         auto h = HashFunction::create(req.arg(i));
  262|      0|         if(!h) {
  ------------------
  |  Branch (262:13): [True: 0, False: 0]
  ------------------
  263|      0|            return nullptr;
  264|      0|         }
  265|      0|         hashes.push_back(std::move(h));
  266|      0|      }
  267|       |
  268|      0|      return std::make_unique<Parallel>(hashes);
  269|      0|   }
  270|      0|#endif
  271|       |
  272|      0|#if defined(BOTAN_HAS_TRUNCATED_HASH)
  273|      0|   if(req.algo_name() == "Truncated" && req.arg_count() == 2) {
  ------------------
  |  Branch (273:7): [True: 0, False: 0]
  |  Branch (273:41): [True: 0, False: 0]
  ------------------
  274|      0|      auto hash = HashFunction::create(req.arg(0));
  275|      0|      if(!hash) {
  ------------------
  |  Branch (275:10): [True: 0, False: 0]
  ------------------
  276|      0|         return nullptr;
  277|      0|      }
  278|       |
  279|      0|      return std::make_unique<Truncated_Hash>(std::move(hash), req.arg_as_integer(1));
  280|      0|   }
  281|      0|#endif
  282|       |
  283|      0|#if defined(BOTAN_HAS_COMB4P)
  284|      0|   if(req.algo_name() == "Comb4P" && req.arg_count() == 2) {
  ------------------
  |  Branch (284:7): [True: 0, False: 0]
  |  Branch (284:38): [True: 0, False: 0]
  ------------------
  285|      0|      auto h1 = HashFunction::create(req.arg(0));
  286|      0|      auto h2 = HashFunction::create(req.arg(1));
  287|       |
  288|      0|      if(h1 && h2) {
  ------------------
  |  Branch (288:10): [True: 0, False: 0]
  |  Branch (288:16): [True: 0, False: 0]
  ------------------
  289|      0|         return std::make_unique<Comb4P>(std::move(h1), std::move(h2));
  290|      0|      }
  291|      0|   }
  292|      0|#endif
  293|       |
  294|      0|   return nullptr;
  295|      0|}

_ZN5Botan7SHA_25615compress_digestERNSt3__16vectorIjNS_16secure_allocatorIjEEEENS1_4spanIKhLm18446744073709551615EEEm:
   49|     10|void SHA_256::compress_digest(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
   50|     10|#if defined(BOTAN_HAS_SHA2_32_X86)
   51|     10|   if(CPUID::has_intel_sha()) {
  ------------------
  |  Branch (51:7): [True: 0, False: 10]
  ------------------
   52|      0|      return SHA_256::compress_digest_x86(digest, input, blocks);
   53|      0|   }
   54|     10|#endif
   55|       |
   56|     10|#if defined(BOTAN_HAS_SHA2_32_X86_BMI2)
   57|     10|   if(CPUID::has_bmi2()) {
  ------------------
  |  Branch (57:7): [True: 10, False: 0]
  ------------------
   58|     10|      return SHA_256::compress_digest_x86_bmi2(digest, input, blocks);
   59|     10|   }
   60|      0|#endif
   61|       |
   62|       |#if defined(BOTAN_HAS_SHA2_32_ARMV8)
   63|       |   if(CPUID::has_arm_sha2()) {
   64|       |      return SHA_256::compress_digest_armv8(digest, input, blocks);
   65|       |   }
   66|       |#endif
   67|       |
   68|      0|   uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], G = digest[6],
   69|      0|            H = digest[7];
   70|       |
   71|      0|   BufferSlicer in(input);
   72|       |
   73|      0|   for(size_t i = 0; i != blocks; ++i) {
  ------------------
  |  Branch (73:22): [True: 0, False: 0]
  ------------------
   74|      0|      const auto block = in.take(block_bytes);
   75|       |
   76|      0|      uint32_t W00 = load_be<uint32_t>(block.data(), 0);
   77|      0|      uint32_t W01 = load_be<uint32_t>(block.data(), 1);
   78|      0|      uint32_t W02 = load_be<uint32_t>(block.data(), 2);
   79|      0|      uint32_t W03 = load_be<uint32_t>(block.data(), 3);
   80|      0|      uint32_t W04 = load_be<uint32_t>(block.data(), 4);
   81|      0|      uint32_t W05 = load_be<uint32_t>(block.data(), 5);
   82|      0|      uint32_t W06 = load_be<uint32_t>(block.data(), 6);
   83|      0|      uint32_t W07 = load_be<uint32_t>(block.data(), 7);
   84|      0|      uint32_t W08 = load_be<uint32_t>(block.data(), 8);
   85|      0|      uint32_t W09 = load_be<uint32_t>(block.data(), 9);
   86|      0|      uint32_t W10 = load_be<uint32_t>(block.data(), 10);
   87|      0|      uint32_t W11 = load_be<uint32_t>(block.data(), 11);
   88|      0|      uint32_t W12 = load_be<uint32_t>(block.data(), 12);
   89|      0|      uint32_t W13 = load_be<uint32_t>(block.data(), 13);
   90|      0|      uint32_t W14 = load_be<uint32_t>(block.data(), 14);
   91|      0|      uint32_t W15 = load_be<uint32_t>(block.data(), 15);
   92|       |
   93|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98);
   94|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491);
   95|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF);
   96|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5);
   97|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B);
   98|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1);
   99|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4);
  100|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5);
  101|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98);
  102|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01);
  103|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE);
  104|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3);
  105|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74);
  106|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE);
  107|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7);
  108|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174);
  109|       |
  110|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1);
  111|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786);
  112|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6);
  113|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC);
  114|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F);
  115|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA);
  116|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC);
  117|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA);
  118|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152);
  119|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D);
  120|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8);
  121|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7);
  122|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3);
  123|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147);
  124|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351);
  125|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967);
  126|       |
  127|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85);
  128|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138);
  129|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC);
  130|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13);
  131|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354);
  132|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB);
  133|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E);
  134|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85);
  135|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1);
  136|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B);
  137|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70);
  138|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3);
  139|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819);
  140|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624);
  141|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585);
  142|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070);
  143|       |
  144|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116);
  145|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08);
  146|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C);
  147|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5);
  148|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3);
  149|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A);
  150|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F);
  151|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3);
  152|      0|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE);
  153|      0|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F);
  154|      0|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814);
  155|      0|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208);
  156|      0|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA);
  157|      0|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB);
  158|      0|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7);
  159|      0|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2);
  160|       |
  161|      0|      A = (digest[0] += A);
  162|      0|      B = (digest[1] += B);
  163|      0|      C = (digest[2] += C);
  164|      0|      D = (digest[3] += D);
  165|      0|      E = (digest[4] += E);
  166|      0|      F = (digest[5] += F);
  167|      0|      G = (digest[6] += G);
  168|      0|      H = (digest[7] += H);
  169|      0|   }
  170|      0|}
_ZN5Botan7SHA_25610compress_nERNSt3__16vectorIjNS_16secure_allocatorIjEEEENS1_4spanIKhLm18446744073709551615EEEm:
  204|     10|void SHA_256::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
  205|     10|   SHA_256::compress_digest(digest, input, blocks);
  206|     10|}
_ZN5Botan7SHA_2564initERNSt3__16vectorIjNS_16secure_allocatorIjEEEE:
  208|      7|void SHA_256::init(digest_type& digest) {
  209|      7|   digest.assign({0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19});
  210|      7|}
_ZN5Botan7SHA_2568add_dataENSt3__14spanIKhLm18446744073709551615EEE:
  220|      9|void SHA_256::add_data(std::span<const uint8_t> input) {
  221|      9|   m_md.update(input);
  222|      9|}
_ZN5Botan7SHA_25612final_resultENSt3__14spanIhLm18446744073709551615EEE:
  224|      4|void SHA_256::final_result(std::span<uint8_t> output) {
  225|      4|   m_md.final(output);
  226|      4|}

_ZN5Botan7SHA_25624compress_digest_x86_bmi2ERNSt3__16vectorIjNS_16secure_allocatorIjEEEENS1_4spanIKhLm18446744073709551615EEEm:
   24|     10|void SHA_256::compress_digest_x86_bmi2(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
   25|     10|   uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], G = digest[6],
   26|     10|            H = digest[7];
   27|       |
   28|     10|   BufferSlicer in(input);
   29|       |
   30|     20|   for(size_t i = 0; i != blocks; ++i) {
  ------------------
  |  Branch (30:22): [True: 10, False: 10]
  ------------------
   31|     10|      const auto block = in.take(block_bytes);
   32|       |
   33|     10|      uint32_t W00 = load_be<uint32_t>(block.data(), 0);
   34|     10|      uint32_t W01 = load_be<uint32_t>(block.data(), 1);
   35|     10|      uint32_t W02 = load_be<uint32_t>(block.data(), 2);
   36|     10|      uint32_t W03 = load_be<uint32_t>(block.data(), 3);
   37|     10|      uint32_t W04 = load_be<uint32_t>(block.data(), 4);
   38|     10|      uint32_t W05 = load_be<uint32_t>(block.data(), 5);
   39|     10|      uint32_t W06 = load_be<uint32_t>(block.data(), 6);
   40|     10|      uint32_t W07 = load_be<uint32_t>(block.data(), 7);
   41|     10|      uint32_t W08 = load_be<uint32_t>(block.data(), 8);
   42|     10|      uint32_t W09 = load_be<uint32_t>(block.data(), 9);
   43|     10|      uint32_t W10 = load_be<uint32_t>(block.data(), 10);
   44|     10|      uint32_t W11 = load_be<uint32_t>(block.data(), 11);
   45|     10|      uint32_t W12 = load_be<uint32_t>(block.data(), 12);
   46|     10|      uint32_t W13 = load_be<uint32_t>(block.data(), 13);
   47|     10|      uint32_t W14 = load_be<uint32_t>(block.data(), 14);
   48|     10|      uint32_t W15 = load_be<uint32_t>(block.data(), 15);
   49|       |
   50|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98);
   51|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491);
   52|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF);
   53|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5);
   54|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B);
   55|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1);
   56|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4);
   57|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5);
   58|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98);
   59|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01);
   60|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE);
   61|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3);
   62|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74);
   63|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE);
   64|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7);
   65|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174);
   66|       |
   67|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1);
   68|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786);
   69|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6);
   70|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC);
   71|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F);
   72|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA);
   73|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC);
   74|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA);
   75|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152);
   76|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D);
   77|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8);
   78|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7);
   79|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3);
   80|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147);
   81|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351);
   82|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967);
   83|       |
   84|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85);
   85|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138);
   86|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC);
   87|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13);
   88|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354);
   89|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB);
   90|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E);
   91|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85);
   92|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1);
   93|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B);
   94|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70);
   95|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3);
   96|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819);
   97|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624);
   98|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585);
   99|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070);
  100|       |
  101|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116);
  102|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08);
  103|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C);
  104|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5);
  105|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3);
  106|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A);
  107|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F);
  108|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3);
  109|     10|      SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE);
  110|     10|      SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F);
  111|     10|      SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814);
  112|     10|      SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208);
  113|     10|      SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA);
  114|     10|      SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB);
  115|     10|      SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7);
  116|     10|      SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2);
  117|       |
  118|     10|      A = (digest[0] += A);
  119|     10|      B = (digest[1] += B);
  120|     10|      C = (digest[2] += C);
  121|     10|      D = (digest[3] += D);
  122|     10|      E = (digest[4] += E);
  123|     10|      F = (digest[5] += F);
  124|     10|      G = (digest[6] += G);
  125|     10|      H = (digest[7] += H);
  126|     10|   }
  127|     10|}

_ZN5Botan4HMAC8add_dataENSt3__14spanIKhLm18446744073709551615EEE:
   19|      1|void HMAC::add_data(std::span<const uint8_t> input) {
   20|      1|   assert_key_material_set();
   21|      1|   m_hash->update(input);
   22|      1|}
_ZN5Botan4HMAC12final_resultENSt3__14spanIhLm18446744073709551615EEE:
   27|      2|void HMAC::final_result(std::span<uint8_t> mac) {
   28|      2|   assert_key_material_set();
   29|      2|   m_hash->final(mac);
   30|      2|   m_hash->update(m_okey);
   31|      2|   m_hash->update(mac.first(m_hash_output_length));
   32|      2|   m_hash->final(mac);
   33|      2|   m_hash->update(m_ikey);
   34|      2|}
_ZNK5Botan4HMAC8key_specEv:
   36|      2|Key_Length_Specification HMAC::key_spec() const {
   37|       |   // Support very long lengths for things like PBKDF2 and the TLS PRF
   38|      2|   return Key_Length_Specification(0, 4096);
   39|      2|}
_ZNK5Botan4HMAC13output_lengthEv:
   41|      4|size_t HMAC::output_length() const {
   42|      4|   return m_hash_output_length;
   43|      4|}
_ZNK5Botan4HMAC19has_keying_materialEv:
   45|      3|bool HMAC::has_keying_material() const {
   46|      3|   return !m_okey.empty();
   47|      3|}
_ZN5Botan4HMAC12key_scheduleENSt3__14spanIKhLm18446744073709551615EEE:
   52|      2|void HMAC::key_schedule(std::span<const uint8_t> key) {
   53|      2|   const uint8_t ipad = 0x36;
   54|      2|   const uint8_t opad = 0x5C;
   55|       |
   56|      2|   m_hash->clear();
   57|       |
   58|      2|   m_ikey.resize(m_hash_block_size);
   59|      2|   m_okey.resize(m_hash_block_size);
   60|       |
   61|      2|   clear_mem(m_ikey.data(), m_ikey.size());
   62|      2|   clear_mem(m_okey.data(), m_okey.size());
   63|       |
   64|       |   /*
   65|       |   * Sometimes the HMAC key length itself is sensitive, as with PBKDF2 where it
   66|       |   * reveals the length of the passphrase. Make some attempt to hide this to
   67|       |   * side channels. Clearly if the secret is longer than the block size then the
   68|       |   * branch to hash first reveals that. In addition, counting the number of
   69|       |   * compression functions executed reveals the size at the granularity of the
   70|       |   * hash function's block size.
   71|       |   *
   72|       |   * The greater concern is for smaller keys; being able to detect when a
   73|       |   * passphrase is say 4 bytes may assist choosing weaker targets. Even though
   74|       |   * the loop bounds are constant, we can only actually read key[0..length] so
   75|       |   * it doesn't seem possible to make this computation truly constant time.
   76|       |   *
   77|       |   * We don't mind leaking if the length is exactly zero since that's
   78|       |   * trivial to simply check.
   79|       |   */
   80|       |
   81|      2|   if(key.size() > m_hash_block_size) {
  ------------------
  |  Branch (81:7): [True: 0, False: 2]
  ------------------
   82|      0|      m_hash->update(key);
   83|      0|      m_hash->final(m_ikey.data());
   84|      2|   } else if(!key.empty()) {
  ------------------
  |  Branch (84:14): [True: 2, False: 0]
  ------------------
   85|    130|      for(size_t i = 0, i_mod_length = 0; i != m_hash_block_size; ++i) {
  ------------------
  |  Branch (85:43): [True: 128, False: 2]
  ------------------
   86|       |         /*
   87|       |         access key[i % length] but avoiding division due to variable
   88|       |         time computation on some processors.
   89|       |         */
   90|    128|         auto needs_reduction = CT::Mask<size_t>::is_lte(key.size(), i_mod_length);
   91|    128|         i_mod_length = needs_reduction.select(0, i_mod_length);
   92|    128|         const uint8_t kb = key[i_mod_length];
   93|       |
   94|    128|         auto in_range = CT::Mask<size_t>::is_lt(i, key.size());
   95|    128|         m_ikey[i] = static_cast<uint8_t>(in_range.if_set_return(kb));
   96|    128|         i_mod_length += 1;
   97|    128|      }
   98|      2|   }
   99|       |
  100|    130|   for(size_t i = 0; i != m_hash_block_size; ++i) {
  ------------------
  |  Branch (100:22): [True: 128, False: 2]
  ------------------
  101|    128|      m_ikey[i] ^= ipad;
  102|    128|      m_okey[i] = m_ikey[i] ^ ipad ^ opad;
  103|    128|   }
  104|       |
  105|      2|   m_hash->update(m_ikey);
  106|      2|}
_ZN5Botan4HMACC2ENSt3__110unique_ptrINS_12HashFunctionENS1_14default_deleteIS3_EEEE:
  137|      1|      m_hash_block_size(m_hash->hash_block_size()) {
  138|      1|   BOTAN_ARG_CHECK(m_hash_block_size >= m_hash_output_length, "HMAC is not compatible with this hash function");
  ------------------
  |  |   30|      1|   do {                                                          \
  |  |   31|      1|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 1]
  |  |  ------------------
  |  |   32|      1|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|      1|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  139|      1|}

_ZN5Botan25MessageAuthenticationCode6createENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_:
   52|      1|                                                                             std::string_view provider) {
   53|      1|   const SCAN_Name req(algo_spec);
   54|       |
   55|      1|#if defined(BOTAN_HAS_BLAKE2BMAC)
   56|      1|   if(req.algo_name() == "Blake2b" || req.algo_name() == "BLAKE2b") {
  ------------------
  |  Branch (56:7): [True: 0, False: 1]
  |  Branch (56:39): [True: 0, False: 1]
  ------------------
   57|      0|      return std::make_unique<BLAKE2bMAC>(req.arg_as_integer(0, 512));
   58|      0|   }
   59|      1|#endif
   60|       |
   61|      1|#if defined(BOTAN_HAS_GMAC)
   62|      1|   if(req.algo_name() == "GMAC" && req.arg_count() == 1) {
  ------------------
  |  Branch (62:7): [True: 0, False: 1]
  |  Branch (62:36): [True: 0, False: 0]
  ------------------
   63|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (63:10): [True: 0, False: 0]
  |  Branch (63:30): [True: 0, False: 0]
  ------------------
   64|      0|         if(auto bc = BlockCipher::create(req.arg(0))) {
  ------------------
  |  Branch (64:18): [True: 0, False: 0]
  ------------------
   65|      0|            return std::make_unique<GMAC>(std::move(bc));
   66|      0|         }
   67|      0|      }
   68|      0|   }
   69|      1|#endif
   70|       |
   71|      1|#if defined(BOTAN_HAS_HMAC)
   72|      1|   if(req.algo_name() == "HMAC" && req.arg_count() == 1) {
  ------------------
  |  Branch (72:7): [True: 1, False: 0]
  |  Branch (72:36): [True: 1, False: 0]
  ------------------
   73|      1|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (73:10): [True: 1, False: 0]
  |  Branch (73:30): [True: 0, False: 0]
  ------------------
   74|      1|         if(auto hash = HashFunction::create(req.arg(0))) {
  ------------------
  |  Branch (74:18): [True: 1, False: 0]
  ------------------
   75|      1|            return std::make_unique<HMAC>(std::move(hash));
   76|      1|         }
   77|      1|      }
   78|      1|   }
   79|      0|#endif
   80|       |
   81|      0|#if defined(BOTAN_HAS_POLY1305)
   82|      0|   if(req.algo_name() == "Poly1305" && req.arg_count() == 0) {
  ------------------
  |  Branch (82:7): [True: 0, False: 0]
  |  Branch (82:40): [True: 0, False: 0]
  ------------------
   83|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (83:10): [True: 0, False: 0]
  |  Branch (83:30): [True: 0, False: 0]
  ------------------
   84|      0|         return std::make_unique<Poly1305>();
   85|      0|      }
   86|      0|   }
   87|      0|#endif
   88|       |
   89|      0|#if defined(BOTAN_HAS_SIPHASH)
   90|      0|   if(req.algo_name() == "SipHash") {
  ------------------
  |  Branch (90:7): [True: 0, False: 0]
  ------------------
   91|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (91:10): [True: 0, False: 0]
  |  Branch (91:30): [True: 0, False: 0]
  ------------------
   92|      0|         return std::make_unique<SipHash>(req.arg_as_integer(0, 2), req.arg_as_integer(1, 4));
   93|      0|      }
   94|      0|   }
   95|      0|#endif
   96|       |
   97|      0|#if defined(BOTAN_HAS_CMAC)
   98|      0|   if((req.algo_name() == "CMAC" || req.algo_name() == "OMAC") && req.arg_count() == 1) {
  ------------------
  |  Branch (98:8): [True: 0, False: 0]
  |  Branch (98:37): [True: 0, False: 0]
  |  Branch (98:67): [True: 0, False: 0]
  ------------------
   99|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (99:10): [True: 0, False: 0]
  |  Branch (99:30): [True: 0, False: 0]
  ------------------
  100|      0|         if(auto bc = BlockCipher::create(req.arg(0))) {
  ------------------
  |  Branch (100:18): [True: 0, False: 0]
  ------------------
  101|      0|            return std::make_unique<CMAC>(std::move(bc));
  102|      0|         }
  103|      0|      }
  104|      0|   }
  105|      0|#endif
  106|       |
  107|      0|#if defined(BOTAN_HAS_ANSI_X919_MAC)
  108|      0|   if(req.algo_name() == "X9.19-MAC") {
  ------------------
  |  Branch (108:7): [True: 0, False: 0]
  ------------------
  109|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (109:10): [True: 0, False: 0]
  |  Branch (109:30): [True: 0, False: 0]
  ------------------
  110|      0|         return std::make_unique<ANSI_X919_MAC>();
  111|      0|      }
  112|      0|   }
  113|      0|#endif
  114|       |
  115|      0|#if defined(BOTAN_HAS_KMAC)
  116|      0|   if(req.algo_name() == "KMAC-128") {
  ------------------
  |  Branch (116:7): [True: 0, False: 0]
  ------------------
  117|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (117:10): [True: 0, False: 0]
  |  Branch (117:30): [True: 0, False: 0]
  ------------------
  118|      0|         if(req.arg_count() != 1) {
  ------------------
  |  Branch (118:13): [True: 0, False: 0]
  ------------------
  119|      0|            throw Invalid_Argument(
  120|      0|               "invalid algorithm specification for KMAC-128: need exactly one argument for output bit length");
  121|      0|         }
  122|      0|         return std::make_unique<KMAC128>(req.arg_as_integer(0));
  123|      0|      }
  124|      0|   }
  125|       |
  126|      0|   if(req.algo_name() == "KMAC-256") {
  ------------------
  |  Branch (126:7): [True: 0, False: 0]
  ------------------
  127|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (127:10): [True: 0, False: 0]
  |  Branch (127:30): [True: 0, False: 0]
  ------------------
  128|      0|         if(req.arg_count() != 1) {
  ------------------
  |  Branch (128:13): [True: 0, False: 0]
  ------------------
  129|      0|            throw Invalid_Argument(
  130|      0|               "invalid algorithm specification for KMAC-256: need exactly one argument for output bit length");
  131|      0|         }
  132|      0|         return std::make_unique<KMAC256>(req.arg_as_integer(0));
  133|      0|      }
  134|      0|   }
  135|      0|#endif
  136|       |
  137|      0|   BOTAN_UNUSED(req);
  ------------------
  |  |  118|      0|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
  138|      0|   BOTAN_UNUSED(provider);
  ------------------
  |  |  118|      0|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
  139|       |
  140|      0|   return nullptr;
  141|      0|}
_ZN5Botan25MessageAuthenticationCode15create_or_throwENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_:
  149|      1|                                                                                      std::string_view provider) {
  150|      1|   if(auto mac = MessageAuthenticationCode::create(algo, provider)) {
  ------------------
  |  Branch (150:12): [True: 1, False: 0]
  ------------------
  151|      1|      return mac;
  152|      1|   }
  153|      0|   throw Lookup_Error("MAC", algo, provider);
  154|      1|}

_ZN5Botan6BigInt3addEPKmmNS0_4SignE:
   16|  23.2k|BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) {
   17|  23.2k|   const size_t x_sw = sig_words();
   18|       |
   19|  23.2k|   grow_to(std::max(x_sw, y_words) + 1);
   20|       |
   21|  23.2k|   if(sign() == y_sign) {
  ------------------
  |  Branch (21:7): [True: 14.8k, False: 8.39k]
  ------------------
   22|  14.8k|      bigint_add2(mutable_data(), size() - 1, y, y_words);
   23|  14.8k|   } else {
   24|  8.39k|      const int32_t relative_size = bigint_cmp(data(), x_sw, y, y_words);
   25|       |
   26|  8.39k|      if(relative_size >= 0) {
  ------------------
  |  Branch (26:10): [True: 8.36k, False: 26]
  ------------------
   27|       |         // *this >= y
   28|  8.36k|         bigint_sub2(mutable_data(), x_sw, y, y_words);
   29|  8.36k|      } else {
   30|       |         // *this < y
   31|     26|         bigint_sub2_rev(mutable_data(), y, y_words);
   32|     26|      }
   33|       |
   34|       |      //this->sign_fixup(relative_size, y_sign);
   35|  8.39k|      if(relative_size < 0) {
  ------------------
  |  Branch (35:10): [True: 26, False: 8.36k]
  ------------------
   36|     26|         set_sign(y_sign);
   37|  8.36k|      } else if(relative_size == 0) {
  ------------------
  |  Branch (37:17): [True: 0, False: 8.36k]
  ------------------
   38|      0|         set_sign(Positive);
   39|      0|      }
   40|  8.39k|   }
   41|       |
   42|  23.2k|   return (*this);
   43|  23.2k|}
_ZN5Botan6BigInt7rev_subEPKmmRNSt3__16vectorImNS_16secure_allocatorImEEEE:
  130|  5.45k|BigInt& BigInt::rev_sub(const word y[], size_t y_sw, secure_vector<word>& ws) {
  131|  5.45k|   if(this->sign() != BigInt::Positive) {
  ------------------
  |  Branch (131:7): [True: 0, False: 5.45k]
  ------------------
  132|      0|      throw Invalid_State("BigInt::sub_rev requires this is positive");
  133|      0|   }
  134|       |
  135|  5.45k|   const size_t x_sw = this->sig_words();
  136|       |
  137|  5.45k|   ws.resize(std::max(x_sw, y_sw));
  138|  5.45k|   clear_mem(ws.data(), ws.size());
  139|       |
  140|  5.45k|   const int32_t relative_size = bigint_sub_abs(ws.data(), data(), x_sw, y, y_sw);
  141|       |
  142|  5.45k|   this->cond_flip_sign(relative_size > 0);
  143|  5.45k|   this->swap_reg(ws);
  144|       |
  145|  5.45k|   return (*this);
  146|  5.45k|}
_ZN5Botan6BigInt3mulERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  156|  10.9k|BigInt& BigInt::mul(const BigInt& y, secure_vector<word>& ws) {
  157|  10.9k|   const size_t x_sw = sig_words();
  158|  10.9k|   const size_t y_sw = y.sig_words();
  159|  10.9k|   set_sign((sign() == y.sign()) ? Positive : Negative);
  ------------------
  |  Branch (159:13): [True: 10.9k, False: 0]
  ------------------
  160|       |
  161|  10.9k|   if(x_sw == 0 || y_sw == 0) {
  ------------------
  |  Branch (161:7): [True: 2.07k, False: 8.82k]
  |  Branch (161:20): [True: 0, False: 8.82k]
  ------------------
  162|  2.07k|      clear();
  163|  2.07k|      set_sign(Positive);
  164|  8.82k|   } else if(x_sw == 1 && y_sw) {
  ------------------
  |  Branch (164:14): [True: 2.01k, False: 6.80k]
  |  Branch (164:27): [True: 2.01k, False: 0]
  ------------------
  165|  2.01k|      grow_to(y_sw + 1);
  166|  2.01k|      bigint_linmul3(mutable_data(), y.data(), y_sw, word_at(0));
  167|  6.80k|   } else if(y_sw == 1 && x_sw) {
  ------------------
  |  Branch (167:14): [True: 0, False: 6.80k]
  |  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|  6.80k|   } else {
  171|  6.80k|      const size_t new_size = x_sw + y_sw + 1;
  172|  6.80k|      ws.resize(new_size);
  173|  6.80k|      secure_vector<word> z_reg(new_size);
  174|       |
  175|  6.80k|      bigint_mul(z_reg.data(), z_reg.size(), data(), size(), x_sw, y.data(), y.size(), y_sw, ws.data(), ws.size());
  176|       |
  177|  6.80k|      this->swap_reg(z_reg);
  178|  6.80k|   }
  179|       |
  180|  10.9k|   return (*this);
  181|  10.9k|}
_ZN5Botan6BigInt6squareERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  183|  1.88k|BigInt& BigInt::square(secure_vector<word>& ws) {
  184|  1.88k|   const size_t sw = sig_words();
  185|       |
  186|  1.88k|   secure_vector<word> z(2 * sw);
  187|  1.88k|   ws.resize(z.size());
  188|       |
  189|  1.88k|   bigint_sqr(z.data(), z.size(), data(), size(), sw, ws.data(), ws.size());
  190|       |
  191|  1.88k|   swap_reg(z);
  192|  1.88k|   set_sign(BigInt::Positive);
  193|       |
  194|  1.88k|   return (*this);
  195|  1.88k|}
_ZN5Botan6BigIntmLEm:
  197|   351k|BigInt& BigInt::operator*=(word y) {
  198|   351k|   if(y == 0) {
  ------------------
  |  Branch (198:7): [True: 0, False: 351k]
  ------------------
  199|      0|      clear();
  200|      0|      set_sign(Positive);
  201|      0|   }
  202|       |
  203|   351k|   const word carry = bigint_linmul2(mutable_data(), size(), y);
  204|   351k|   set_word_at(size(), carry);
  205|       |
  206|   351k|   return (*this);
  207|   351k|}
_ZN5Botan6BigIntrMERKS0_:
  224|  24.5k|BigInt& BigInt::operator%=(const BigInt& mod) {
  225|  24.5k|   return (*this = (*this) % mod);
  226|  24.5k|}
_ZN5Botan6BigIntlSEm:
  260|  14.7k|BigInt& BigInt::operator<<=(size_t shift) {
  261|  14.7k|   const size_t shift_words = shift / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  14.7k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  262|  14.7k|   const size_t shift_bits = shift % BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  14.7k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  263|  14.7k|   const size_t size = sig_words();
  264|       |
  265|  14.7k|   const size_t bits_free = top_bits_free();
  266|       |
  267|  14.7k|   const size_t new_size = size + shift_words + (bits_free < shift_bits);
  268|       |
  269|  14.7k|   m_data.grow_to(new_size);
  270|       |
  271|  14.7k|   bigint_shl1(m_data.mutable_data(), new_size, size, shift_words, shift_bits);
  272|       |
  273|  14.7k|   return (*this);
  274|  14.7k|}
_ZN5Botan6BigIntrSEm:
  279|  52.0k|BigInt& BigInt::operator>>=(size_t shift) {
  280|  52.0k|   const size_t shift_words = shift / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  52.0k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  281|  52.0k|   const size_t shift_bits = shift % BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  52.0k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  282|       |
  283|  52.0k|   bigint_shr1(m_data.mutable_data(), m_data.size(), shift_words, shift_bits);
  284|       |
  285|  52.0k|   if(is_negative() && is_zero()) {
  ------------------
  |  Branch (285:7): [True: 0, False: 52.0k]
  |  Branch (285:24): [True: 0, False: 0]
  ------------------
  286|      0|      set_sign(Positive);
  287|      0|   }
  288|       |
  289|  52.0k|   return (*this);
  290|  52.0k|}

_ZN5Botan6BigInt4add2ERKS0_PKmmNS0_4SignE:
   19|  12.2k|BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_words, BigInt::Sign y_sign) {
   20|  12.2k|   const size_t x_sw = x.sig_words();
   21|       |
   22|  12.2k|   BigInt z = BigInt::with_capacity(std::max(x_sw, y_words) + 1);
   23|       |
   24|  12.2k|   if(x.sign() == y_sign) {
  ------------------
  |  Branch (24:7): [True: 1.47k, False: 10.8k]
  ------------------
   25|  1.47k|      bigint_add3(z.mutable_data(), x.data(), x_sw, y, y_words);
   26|  1.47k|      z.set_sign(x.sign());
   27|  10.8k|   } else {
   28|  10.8k|      const int32_t relative_size = bigint_sub_abs(z.mutable_data(), x.data(), x_sw, y, y_words);
   29|       |
   30|       |      //z.sign_fixup(relative_size, y_sign);
   31|  10.8k|      if(relative_size < 0) {
  ------------------
  |  Branch (31:10): [True: 0, False: 10.8k]
  ------------------
   32|      0|         z.set_sign(y_sign);
   33|  10.8k|      } else if(relative_size == 0) {
  ------------------
  |  Branch (33:17): [True: 0, False: 10.8k]
  ------------------
   34|      0|         z.set_sign(BigInt::Positive);
   35|  10.8k|      } else {
   36|  10.8k|         z.set_sign(x.sign());
   37|  10.8k|      }
   38|  10.8k|   }
   39|       |
   40|  12.2k|   return z;
   41|  12.2k|}
_ZN5BotanmlERKNS_6BigIntES2_:
   46|  1.45k|BigInt operator*(const BigInt& x, const BigInt& y) {
   47|  1.45k|   const size_t x_sw = x.sig_words();
   48|  1.45k|   const size_t y_sw = y.sig_words();
   49|       |
   50|  1.45k|   BigInt z = BigInt::with_capacity(x.size() + y.size());
   51|       |
   52|  1.45k|   if(x_sw == 1 && y_sw) {
  ------------------
  |  Branch (52:7): [True: 266, False: 1.18k]
  |  Branch (52:20): [True: 266, False: 0]
  ------------------
   53|    266|      bigint_linmul3(z.mutable_data(), y.data(), y_sw, x.word_at(0));
   54|  1.18k|   } else if(y_sw == 1 && x_sw) {
  ------------------
  |  Branch (54:14): [True: 250, False: 934]
  |  Branch (54:27): [True: 249, False: 1]
  ------------------
   55|    249|      bigint_linmul3(z.mutable_data(), x.data(), x_sw, y.word_at(0));
   56|    935|   } else if(x_sw && y_sw) {
  ------------------
  |  Branch (56:14): [True: 934, False: 1]
  |  Branch (56:22): [True: 933, False: 1]
  ------------------
   57|    933|      secure_vector<word> workspace(z.size());
   58|       |
   59|    933|      bigint_mul(z.mutable_data(),
   60|    933|                 z.size(),
   61|    933|                 x.data(),
   62|    933|                 x.size(),
   63|    933|                 x_sw,
   64|    933|                 y.data(),
   65|    933|                 y.size(),
   66|    933|                 y_sw,
   67|    933|                 workspace.data(),
   68|    933|                 workspace.size());
   69|    933|   }
   70|       |
   71|  1.45k|   z.cond_flip_sign(x_sw > 0 && y_sw > 0 && x.sign() != y.sign());
  ------------------
  |  Branch (71:21): [True: 1.44k, False: 1]
  |  Branch (71:33): [True: 1.44k, False: 1]
  |  Branch (71:45): [True: 0, False: 1.44k]
  ------------------
   72|       |
   73|  1.45k|   return z;
   74|  1.45k|}
_ZN5BotanmlERKNS_6BigIntEm:
   79|  16.7k|BigInt operator*(const BigInt& x, word y) {
   80|  16.7k|   const size_t x_sw = x.sig_words();
   81|       |
   82|  16.7k|   BigInt z = BigInt::with_capacity(x_sw + 1);
   83|       |
   84|  16.7k|   if(x_sw && y) {
  ------------------
  |  Branch (84:7): [True: 16.7k, False: 0]
  |  Branch (84:15): [True: 8.28k, False: 8.47k]
  ------------------
   85|  8.28k|      bigint_linmul3(z.mutable_data(), x.data(), x_sw, y);
   86|  8.28k|      z.set_sign(x.sign());
   87|  8.28k|   }
   88|       |
   89|  16.7k|   return z;
   90|  16.7k|}
_ZN5BotandvERKNS_6BigIntEm:
  108|  24.5k|BigInt operator/(const BigInt& x, word y) {
  109|  24.5k|   if(y == 0) {
  ------------------
  |  Branch (109:7): [True: 0, False: 24.5k]
  ------------------
  110|      0|      throw Invalid_Argument("BigInt::operator/ divide by zero");
  111|      0|   }
  112|       |
  113|  24.5k|   BigInt q;
  114|  24.5k|   word r;
  115|  24.5k|   ct_divide_word(x, y, q, r);
  116|  24.5k|   return q;
  117|  24.5k|}
_ZN5BotanrmERKNS_6BigIntES2_:
  122|  25.6k|BigInt operator%(const BigInt& n, const BigInt& mod) {
  123|  25.6k|   if(mod.is_zero()) {
  ------------------
  |  Branch (123:7): [True: 0, False: 25.6k]
  ------------------
  124|      0|      throw Invalid_Argument("BigInt::operator% divide by zero");
  125|      0|   }
  126|  25.6k|   if(mod.is_negative()) {
  ------------------
  |  Branch (126:7): [True: 0, False: 25.6k]
  ------------------
  127|      0|      throw Invalid_Argument("BigInt::operator% modulus must be > 0");
  128|      0|   }
  129|  25.6k|   if(n.is_positive() && mod.is_positive() && n < mod) {
  ------------------
  |  Branch (129:7): [True: 25.6k, False: 0]
  |  Branch (129:26): [True: 25.6k, False: 0]
  |  Branch (129:47): [True: 2.10k, False: 23.5k]
  ------------------
  130|  2.10k|      return n;
  131|  2.10k|   }
  132|       |
  133|  23.5k|   if(mod.sig_words() == 1) {
  ------------------
  |  Branch (133:7): [True: 16.1k, False: 7.38k]
  ------------------
  134|  16.1k|      return BigInt::from_word(n % mod.word_at(0));
  135|  16.1k|   }
  136|       |
  137|  7.38k|   BigInt q, r;
  138|  7.38k|   vartime_divide(n, mod, q, r);
  139|  7.38k|   return r;
  140|  23.5k|}
_ZN5BotanrmERKNS_6BigIntEm:
  145|  71.8k|word operator%(const BigInt& n, word mod) {
  146|  71.8k|   if(mod == 0) {
  ------------------
  |  Branch (146:7): [True: 0, False: 71.8k]
  ------------------
  147|      0|      throw Invalid_Argument("BigInt::operator% divide by zero");
  148|      0|   }
  149|       |
  150|  71.8k|   if(mod == 1) {
  ------------------
  |  Branch (150:7): [True: 0, False: 71.8k]
  ------------------
  151|      0|      return 0;
  152|      0|   }
  153|       |
  154|  71.8k|   word remainder = 0;
  155|       |
  156|  71.8k|   if(is_power_of_2(mod)) {
  ------------------
  |  Branch (156:7): [True: 55.4k, False: 16.4k]
  ------------------
  157|  55.4k|      remainder = (n.word_at(0) & (mod - 1));
  158|  55.4k|   } else {
  159|  16.4k|      const size_t sw = n.sig_words();
  160|  35.4k|      for(size_t i = sw; i > 0; --i) {
  ------------------
  |  Branch (160:26): [True: 19.0k, False: 16.4k]
  ------------------
  161|  19.0k|         remainder = bigint_modop_vartime(remainder, n.word_at(i - 1), mod);
  162|  19.0k|      }
  163|  16.4k|   }
  164|       |
  165|  71.8k|   if(remainder && n.sign() == BigInt::Negative) {
  ------------------
  |  Branch (165:7): [True: 71.8k, False: 1]
  |  Branch (165:20): [True: 0, False: 71.8k]
  ------------------
  166|      0|      return mod - remainder;
  167|      0|   }
  168|  71.8k|   return remainder;
  169|  71.8k|}
_ZN5BotanlsERKNS_6BigIntEm:
  174|  7.38k|BigInt operator<<(const BigInt& x, size_t shift) {
  175|  7.38k|   const size_t shift_words = shift / BOTAN_MP_WORD_BITS, shift_bits = shift % BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  7.38k|#define BOTAN_MP_WORD_BITS 64
  ------------------
                 const size_t shift_words = shift / BOTAN_MP_WORD_BITS, shift_bits = shift % BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  7.38k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  176|       |
  177|  7.38k|   const size_t x_sw = x.sig_words();
  178|       |
  179|  7.38k|   BigInt y = BigInt::with_capacity(x_sw + shift_words + (shift_bits ? 1 : 0));
  ------------------
  |  Branch (179:59): [True: 0, False: 7.38k]
  ------------------
  180|  7.38k|   bigint_shl2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits);
  181|  7.38k|   y.set_sign(x.sign());
  182|  7.38k|   return y;
  183|  7.38k|}
_ZN5BotanrsERKNS_6BigIntEm:
  188|    713|BigInt operator>>(const BigInt& x, size_t shift) {
  189|    713|   const size_t shift_words = shift / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|    713|#define BOTAN_MP_WORD_BITS 64
  ------------------
  190|    713|   const size_t shift_bits = shift % BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|    713|#define BOTAN_MP_WORD_BITS 64
  ------------------
  191|    713|   const size_t x_sw = x.sig_words();
  192|       |
  193|    713|   if(shift_words >= x_sw) {
  ------------------
  |  Branch (193:7): [True: 0, False: 713]
  ------------------
  194|      0|      return BigInt::zero();
  195|      0|   }
  196|       |
  197|    713|   BigInt y = BigInt::with_capacity(x_sw - shift_words);
  198|    713|   bigint_shr2(y.mutable_data(), x.data(), x_sw, shift_words, shift_bits);
  199|       |
  200|    713|   if(x.is_negative() && y.is_zero()) {
  ------------------
  |  Branch (200:7): [True: 0, False: 713]
  |  Branch (200:26): [True: 0, False: 0]
  ------------------
  201|      0|      y.set_sign(BigInt::Positive);
  202|    713|   } else {
  203|    713|      y.set_sign(x.sign());
  204|    713|   }
  205|       |
  206|    713|   return y;
  207|    713|}

_ZN5Botan6BigInt9randomizeERNS_21RandomNumberGeneratorEmb:
   18|     53|void BigInt::randomize(RandomNumberGenerator& rng, size_t bitsize, bool set_high_bit) {
   19|     53|   set_sign(Positive);
   20|       |
   21|     53|   if(bitsize == 0) {
  ------------------
  |  Branch (21:7): [True: 0, False: 53]
  ------------------
   22|      0|      clear();
   23|     53|   } else {
   24|     53|      secure_vector<uint8_t> array = rng.random_vec(round_up(bitsize, 8) / 8);
   25|       |
   26|       |      // Always cut unwanted bits
   27|     53|      if(bitsize % 8) {
  ------------------
  |  Branch (27:10): [True: 0, False: 53]
  ------------------
   28|      0|         array[0] &= 0xFF >> (8 - (bitsize % 8));
   29|      0|      }
   30|       |
   31|       |      // Set the highest bit if wanted
   32|     53|      if(set_high_bit) {
  ------------------
  |  Branch (32:10): [True: 1, False: 52]
  ------------------
   33|      1|         array[0] |= 0x80 >> ((bitsize % 8) ? (8 - bitsize % 8) : 0);
  ------------------
  |  Branch (33:31): [True: 0, False: 1]
  ------------------
   34|      1|      }
   35|       |
   36|     53|      binary_decode(array);
   37|     53|   }
   38|     53|}
_ZN5Botan6BigInt14random_integerERNS_21RandomNumberGeneratorERKS0_S4_:
   43|     86|BigInt BigInt::random_integer(RandomNumberGenerator& rng, const BigInt& min, const BigInt& max) {
   44|     86|   if(min.is_negative() || max.is_negative() || max <= min) {
  ------------------
  |  Branch (44:7): [True: 0, False: 86]
  |  Branch (44:28): [True: 0, False: 86]
  |  Branch (44:49): [True: 0, False: 86]
  ------------------
   45|      0|      throw Invalid_Argument("BigInt::random_integer invalid range");
   46|      0|   }
   47|       |
   48|       |   /*
   49|       |   If min is > 1 then we generate a random number `r` in [0,max-min)
   50|       |   and return min + r.
   51|       |
   52|       |   This same logic could also be reasonbly chosen for min == 1, but
   53|       |   that breaks certain tests which expect stability of this function
   54|       |   when generating within [1,n)
   55|       |   */
   56|     86|   if(min > 1) {
  ------------------
  |  Branch (56:7): [True: 43, False: 43]
  ------------------
   57|     43|      const BigInt diff = max - min;
   58|       |      // This call is recursive, but will not recurse further
   59|     43|      return min + BigInt::random_integer(rng, BigInt::zero(), diff);
   60|     43|   }
   61|       |
   62|     43|   BOTAN_DEBUG_ASSERT(min <= 1);
  ------------------
  |  |   99|     43|      do {                          \
  |  |  100|     43|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
   63|       |
   64|     43|   const size_t bits = max.bits();
   65|       |
   66|     43|   BigInt r;
   67|       |
   68|     52|   do {
   69|     52|      r.randomize(rng, bits, false);
   70|     52|   } while(r < min || r >= max);
  ------------------
  |  Branch (70:12): [True: 0, False: 52]
  |  Branch (70:23): [True: 9, False: 43]
  ------------------
   71|       |
   72|     43|   return r;
   73|     86|}

_ZN5Botan6BigInt8from_u64Em:
   28|    383|BigInt BigInt::from_u64(uint64_t n) {
   29|    383|   BigInt bn;
   30|       |
   31|    383|#if BOTAN_MP_WORD_BITS == 64
   32|    383|   bn.set_word_at(0, n);
   33|       |#else
   34|       |   bn.set_word_at(1, static_cast<word>(n >> 32));
   35|       |   bn.set_word_at(0, static_cast<word>(n));
   36|       |#endif
   37|       |
   38|    383|   return bn;
   39|    383|}
_ZN5Botan6BigInt9from_wordEm:
   42|  16.2k|BigInt BigInt::from_word(word n) {
   43|  16.2k|   BigInt bn;
   44|  16.2k|   bn.set_word_at(0, n);
   45|  16.2k|   return bn;
   46|  16.2k|}
_ZN5Botan6BigInt8from_s32Ei:
   49|    382|BigInt BigInt::from_s32(int32_t n) {
   50|    382|   if(n >= 0) {
  ------------------
  |  Branch (50:7): [True: 0, False: 382]
  ------------------
   51|      0|      return BigInt::from_u64(static_cast<uint64_t>(n));
   52|    382|   } else {
   53|    382|      return -BigInt::from_u64(static_cast<uint64_t>(-n));
   54|    382|   }
   55|    382|}
_ZN5Botan6BigInt13with_capacityEm:
   58|  75.9k|BigInt BigInt::with_capacity(size_t size) {
   59|  75.9k|   BigInt bn;
   60|  75.9k|   bn.grow_to(size);
   61|  75.9k|   return bn;
   62|  75.9k|}
_ZN5Botan6BigIntC2EPKhm:
   91|  1.05k|BigInt::BigInt(const uint8_t input[], size_t length) {
   92|  1.05k|   binary_decode(input, length);
   93|  1.05k|}
_ZN5Botan6BigIntC2ERNS_21RandomNumberGeneratorEmb:
  121|      1|BigInt::BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit) {
  122|      1|   randomize(rng, bits, set_high_bit);
  123|      1|}
_ZNK5Botan6BigInt8cmp_wordEm:
  129|  34.2k|int32_t BigInt::cmp_word(word other) const {
  130|  34.2k|   if(is_negative()) {
  ------------------
  |  Branch (130:7): [True: 382, False: 33.9k]
  ------------------
  131|    382|      return -1;  // other is positive ...
  132|    382|   }
  133|       |
  134|  33.9k|   const size_t sw = this->sig_words();
  135|  33.9k|   if(sw > 1) {
  ------------------
  |  Branch (135:7): [True: 15.6k, False: 18.2k]
  ------------------
  136|  15.6k|      return 1;  // must be larger since other is just one word ...
  137|  15.6k|   }
  138|       |
  139|  18.2k|   return bigint_cmp(this->data(), sw, &other, 1);
  140|  33.9k|}
_ZNK5Botan6BigInt3cmpERKS0_b:
  145|    138|int32_t BigInt::cmp(const BigInt& other, bool check_signs) const {
  146|    138|   if(check_signs) {
  ------------------
  |  Branch (146:7): [True: 138, False: 0]
  ------------------
  147|    138|      if(other.is_positive() && this->is_negative()) {
  ------------------
  |  Branch (147:10): [True: 138, False: 0]
  |  Branch (147:33): [True: 0, False: 138]
  ------------------
  148|      0|         return -1;
  149|      0|      }
  150|       |
  151|    138|      if(other.is_negative() && this->is_positive()) {
  ------------------
  |  Branch (151:10): [True: 0, False: 138]
  |  Branch (151:33): [True: 0, False: 0]
  ------------------
  152|      0|         return 1;
  153|      0|      }
  154|       |
  155|    138|      if(other.is_negative() && this->is_negative()) {
  ------------------
  |  Branch (155:10): [True: 0, False: 138]
  |  Branch (155:33): [True: 0, False: 0]
  ------------------
  156|      0|         return (-bigint_cmp(this->data(), this->size(), other.data(), other.size()));
  157|      0|      }
  158|    138|   }
  159|       |
  160|    138|   return bigint_cmp(this->data(), this->size(), other.data(), other.size());
  161|    138|}
_ZNK5Botan6BigInt8is_equalERKS0_:
  163|    715|bool BigInt::is_equal(const BigInt& other) const {
  164|    715|   if(this->sign() != other.sign()) {
  ------------------
  |  Branch (164:7): [True: 0, False: 715]
  ------------------
  165|      0|      return false;
  166|      0|   }
  167|       |
  168|    715|   return bigint_ct_is_eq(this->data(), this->sig_words(), other.data(), other.sig_words()).as_bool();
  169|    715|}
_ZNK5Botan6BigInt12is_less_thanERKS0_:
  171|  52.7k|bool BigInt::is_less_than(const BigInt& other) const {
  172|  52.7k|   if(this->is_negative() && other.is_positive()) {
  ------------------
  |  Branch (172:7): [True: 0, False: 52.7k]
  |  Branch (172:30): [True: 0, False: 0]
  ------------------
  173|      0|      return true;
  174|      0|   }
  175|       |
  176|  52.7k|   if(this->is_positive() && other.is_negative()) {
  ------------------
  |  Branch (176:7): [True: 52.7k, False: 0]
  |  Branch (176:30): [True: 0, False: 52.7k]
  ------------------
  177|      0|      return false;
  178|      0|   }
  179|       |
  180|  52.7k|   if(other.is_negative() && this->is_negative()) {
  ------------------
  |  Branch (180:7): [True: 0, False: 52.7k]
  |  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|  52.7k|   return bigint_ct_is_lt(this->data(), this->sig_words(), other.data(), other.sig_words()).as_bool();
  185|  52.7k|}
_ZNK5Botan6BigInt4Data14calc_sig_wordsEv:
  198|   195k|size_t BigInt::Data::calc_sig_words() const {
  199|   195k|   const size_t sz = m_reg.size();
  200|   195k|   size_t sig = sz;
  201|       |
  202|   195k|   word sub = 1;
  203|       |
  204|  1.88M|   for(size_t i = 0; i != sz; ++i) {
  ------------------
  |  Branch (204:22): [True: 1.68M, False: 195k]
  ------------------
  205|  1.68M|      const word w = m_reg[sz - i - 1];
  206|  1.68M|      sub &= ct_is_zero(w);
  207|  1.68M|      sig -= sub;
  208|  1.68M|   }
  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|   195k|   CT::unpoison(sig);
  215|       |
  216|   195k|   return sig;
  217|   195k|}
_ZNK5Botan6BigInt13get_substringEmm:
  222|  45.6k|uint32_t BigInt::get_substring(size_t offset, size_t length) const {
  223|  45.6k|   if(length == 0 || length > 32) {
  ------------------
  |  Branch (223:7): [True: 0, False: 45.6k]
  |  Branch (223:22): [True: 0, False: 45.6k]
  ------------------
  224|      0|      throw Invalid_Argument("BigInt::get_substring invalid substring length");
  225|      0|   }
  226|       |
  227|  45.6k|   const uint32_t mask = 0xFFFFFFFF >> (32 - length);
  228|       |
  229|  45.6k|   const size_t word_offset = offset / BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  45.6k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  230|  45.6k|   const size_t wshift = (offset % BOTAN_MP_WORD_BITS);
  ------------------
  |  |   50|  45.6k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  231|       |
  232|       |   /*
  233|       |   * The substring is contained within one or at most two words. The
  234|       |   * offset and length are not secret, so we can perform conditional
  235|       |   * operations on those values.
  236|       |   */
  237|  45.6k|   const word w0 = word_at(word_offset);
  238|       |
  239|  45.6k|   if(wshift == 0 || (offset + length) / BOTAN_MP_WORD_BITS == word_offset) {
  ------------------
  |  |   50|  42.7k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  |  Branch (239:7): [True: 2.85k, False: 42.7k]
  |  Branch (239:22): [True: 39.9k, False: 2.85k]
  ------------------
  240|  42.7k|      return static_cast<uint32_t>(w0 >> wshift) & mask;
  241|  42.7k|   } else {
  242|  2.85k|      const word w1 = word_at(word_offset + 1);
  243|  2.85k|      return static_cast<uint32_t>((w0 >> wshift) | (w1 << (BOTAN_MP_WORD_BITS - wshift))) & mask;
  ------------------
  |  |   50|  2.85k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  244|  2.85k|   }
  245|  45.6k|}
_ZNK5Botan6BigInt13top_bits_freeEv:
  281|  48.1k|size_t BigInt::top_bits_free() const {
  282|  48.1k|   const size_t words = sig_words();
  283|       |
  284|  48.1k|   const word top_word = word_at(words - 1);
  285|  48.1k|   const size_t bits_used = high_bit(top_word);
  286|  48.1k|   CT::unpoison(bits_used);
  287|  48.1k|   return BOTAN_MP_WORD_BITS - bits_used;
  ------------------
  |  |   50|  48.1k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  288|  48.1k|}
_ZNK5Botan6BigInt4bitsEv:
  290|  26.0k|size_t BigInt::bits() const {
  291|  26.0k|   const size_t words = sig_words();
  292|       |
  293|  26.0k|   if(words == 0) {
  ------------------
  |  Branch (293:7): [True: 1, False: 26.0k]
  ------------------
  294|      1|      return 0;
  295|      1|   }
  296|       |
  297|  26.0k|   const size_t full_words = (words - 1) * BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  26.0k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  298|  26.0k|   const size_t top_bits = BOTAN_MP_WORD_BITS - top_bits_free();
  ------------------
  |  |   50|  26.0k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  299|       |
  300|  26.0k|   return full_words + top_bits;
  301|  26.0k|}
_ZNK5Botan6BigIntngEv:
  306|    382|BigInt BigInt::operator-() const {
  307|    382|   BigInt x = (*this);
  308|    382|   x.flip_sign();
  309|    382|   return x;
  310|    382|}
_ZN5Botan6BigInt12reduce_belowERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  312|  7.38k|size_t BigInt::reduce_below(const BigInt& p, secure_vector<word>& ws) {
  313|  7.38k|   if(p.is_negative() || this->is_negative()) {
  ------------------
  |  Branch (313:7): [True: 0, False: 7.38k]
  |  Branch (313:26): [True: 0, False: 7.38k]
  ------------------
  314|      0|      throw Invalid_Argument("BigInt::reduce_below both values must be positive");
  315|      0|   }
  316|       |
  317|  7.38k|   const size_t p_words = p.sig_words();
  318|       |
  319|  7.38k|   if(size() < p_words + 1) {
  ------------------
  |  Branch (319:7): [True: 0, False: 7.38k]
  ------------------
  320|      0|      grow_to(p_words + 1);
  321|      0|   }
  322|       |
  323|  7.38k|   if(ws.size() < p_words + 1) {
  ------------------
  |  Branch (323:7): [True: 7.38k, False: 0]
  ------------------
  324|  7.38k|      ws.resize(p_words + 1);
  325|  7.38k|   }
  326|       |
  327|  7.38k|   clear_mem(ws.data(), ws.size());
  328|       |
  329|  7.38k|   size_t reductions = 0;
  330|       |
  331|  7.41k|   for(;;) {
  332|  7.41k|      word borrow = bigint_sub3(ws.data(), data(), p_words + 1, p.data(), p_words);
  333|  7.41k|      if(borrow) {
  ------------------
  |  Branch (333:10): [True: 7.38k, False: 29]
  ------------------
  334|  7.38k|         break;
  335|  7.38k|      }
  336|       |
  337|     29|      ++reductions;
  338|     29|      swap_reg(ws);
  339|     29|   }
  340|       |
  341|  7.38k|   return reductions;
  342|  7.38k|}
_ZN5Botan6BigInt15ct_reduce_belowERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEEm:
  344|  5.45k|void BigInt::ct_reduce_below(const BigInt& mod, secure_vector<word>& ws, size_t bound) {
  345|  5.45k|   if(mod.is_negative() || this->is_negative()) {
  ------------------
  |  Branch (345:7): [True: 0, False: 5.45k]
  |  Branch (345:28): [True: 0, False: 5.45k]
  ------------------
  346|      0|      throw Invalid_Argument("BigInt::ct_reduce_below both values must be positive");
  347|      0|   }
  348|       |
  349|  5.45k|   const size_t mod_words = mod.sig_words();
  350|       |
  351|  5.45k|   grow_to(mod_words);
  352|       |
  353|  5.45k|   const size_t sz = size();
  354|       |
  355|  5.45k|   ws.resize(sz);
  356|       |
  357|  5.45k|   clear_mem(ws.data(), sz);
  358|       |
  359|  16.3k|   for(size_t i = 0; i != bound; ++i) {
  ------------------
  |  Branch (359:22): [True: 10.9k, False: 5.45k]
  ------------------
  360|  10.9k|      word borrow = bigint_sub3(ws.data(), data(), sz, mod.data(), mod_words);
  361|       |
  362|  10.9k|      CT::Mask<word>::is_zero(borrow).select_n(mutable_data(), ws.data(), data(), sz);
  363|  10.9k|   }
  364|  5.45k|}
_ZN5Botan6BigInt13binary_decodeEPKhm:
  403|  1.10k|void BigInt::binary_decode(const uint8_t buf[], size_t length) {
  404|  1.10k|   clear();
  405|       |
  406|  1.10k|   const size_t full_words = length / sizeof(word);
  407|  1.10k|   const size_t extra_bytes = length % sizeof(word);
  408|       |
  409|  1.10k|   secure_vector<word> reg((round_up(full_words + (extra_bytes > 0 ? 1 : 0), 8)));
  ------------------
  |  Branch (409:52): [True: 843, False: 265]
  ------------------
  410|       |
  411|  2.30k|   for(size_t i = 0; i != full_words; ++i) {
  ------------------
  |  Branch (411:22): [True: 1.19k, False: 1.10k]
  ------------------
  412|  1.19k|      reg[i] = load_be<word>(buf + length - sizeof(word) * (i + 1), 0);
  413|  1.19k|   }
  414|       |
  415|  1.10k|   if(extra_bytes > 0) {
  ------------------
  |  Branch (415:7): [True: 843, False: 265]
  ------------------
  416|  3.47k|      for(size_t i = 0; i != extra_bytes; ++i) {
  ------------------
  |  Branch (416:25): [True: 2.63k, False: 843]
  ------------------
  417|  2.63k|         reg[full_words] = (reg[full_words] << 8) | buf[i];
  418|  2.63k|      }
  419|    843|   }
  420|       |
  421|  1.10k|   m_data.swap(reg);
  422|  1.10k|}
_ZN5Botan6BigInt11ct_cond_addEbRKS0_:
  424|    765|void BigInt::ct_cond_add(bool predicate, const BigInt& value) {
  425|    765|   if(this->is_negative() || value.is_negative()) {
  ------------------
  |  Branch (425:7): [True: 0, False: 765]
  |  Branch (425:30): [True: 0, False: 765]
  ------------------
  426|      0|      throw Invalid_Argument("BigInt::ct_cond_add requires both values to be positive");
  427|      0|   }
  428|    765|   this->grow_to(1 + value.sig_words());
  429|       |
  430|    765|   bigint_cnd_add(static_cast<word>(predicate), this->mutable_data(), this->size(), value.data(), value.sig_words());
  431|    765|}
_ZN5Botan6BigInt12ct_cond_swapEbRS0_:
  467|   351k|void BigInt::ct_cond_swap(bool predicate, BigInt& other) {
  468|   351k|   const size_t max_words = std::max(size(), other.size());
  469|   351k|   grow_to(max_words);
  470|   351k|   other.grow_to(max_words);
  471|       |
  472|   351k|   bigint_cnd_swap(predicate, this->mutable_data(), other.mutable_data(), max_words);
  473|   351k|}
_ZN5Botan6BigInt14cond_flip_signEb:
  475|  20.9k|void BigInt::cond_flip_sign(bool predicate) {
  476|       |   // This code is assuming Negative == 0, Positive == 1
  477|       |
  478|  20.9k|   const auto mask = CT::Mask<uint8_t>::expand(predicate);
  479|       |
  480|  20.9k|   const uint8_t current_sign = static_cast<uint8_t>(sign());
  481|       |
  482|  20.9k|   const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign);
  483|       |
  484|  20.9k|   set_sign(static_cast<Sign>(new_sign));
  485|  20.9k|}
_ZN5Botan6BigInt14ct_cond_assignEbRKS0_:
  487|    510|void BigInt::ct_cond_assign(bool predicate, const BigInt& other) {
  488|    510|   const size_t t_words = size();
  489|    510|   const size_t o_words = other.size();
  490|       |
  491|    510|   if(o_words < t_words) {
  ------------------
  |  Branch (491:7): [True: 0, False: 510]
  ------------------
  492|      0|      grow_to(o_words);
  493|      0|   }
  494|       |
  495|    510|   const size_t r_words = std::max(t_words, o_words);
  496|       |
  497|    510|   const auto mask = CT::Mask<word>::expand(predicate);
  498|       |
  499|  4.59k|   for(size_t i = 0; i != r_words; ++i) {
  ------------------
  |  Branch (499:22): [True: 4.08k, False: 510]
  ------------------
  500|  4.08k|      const word o_word = other.word_at(i);
  501|  4.08k|      const word t_word = this->word_at(i);
  502|  4.08k|      this->set_word_at(i, mask.select(o_word, t_word));
  503|  4.08k|   }
  504|       |
  505|    510|   const bool different_sign = sign() != other.sign();
  506|    510|   cond_flip_sign(predicate && different_sign);
  ------------------
  |  Branch (506:19): [True: 246, False: 264]
  |  Branch (506:32): [True: 0, False: 246]
  ------------------
  507|    510|}

_ZN5Botan9ct_divideERKNS_6BigIntES2_RS0_S3_:
   48|    686|void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) {
   49|    686|   if(y.is_zero()) {
  ------------------
  |  Branch (49:7): [True: 0, False: 686]
  ------------------
   50|      0|      throw Invalid_Argument("ct_divide: cannot divide by zero");
   51|      0|   }
   52|       |
   53|    686|   const size_t x_words = x.sig_words();
   54|    686|   const size_t y_words = y.sig_words();
   55|       |
   56|    686|   const size_t x_bits = x.bits();
   57|       |
   58|    686|   BigInt q = BigInt::with_capacity(x_words);
   59|    686|   BigInt r = BigInt::with_capacity(y_words);
   60|    686|   BigInt t = BigInt::with_capacity(y_words);  // a temporary
   61|       |
   62|   352k|   for(size_t i = 0; i != x_bits; ++i) {
  ------------------
  |  Branch (62:22): [True: 351k, False: 686]
  ------------------
   63|   351k|      const size_t b = x_bits - 1 - i;
   64|   351k|      const bool x_b = x.get_bit(b);
   65|       |
   66|   351k|      r *= 2;
   67|   351k|      r.conditionally_set_bit(0, x_b);
   68|       |
   69|   351k|      const bool r_gte_y = bigint_sub3(t.mutable_data(), r.data(), r.size(), y.data(), y_words) == 0;
   70|       |
   71|   351k|      q.conditionally_set_bit(b, r_gte_y);
   72|   351k|      r.ct_cond_swap(r_gte_y, t);
   73|   351k|   }
   74|       |
   75|    686|   sign_fixup(x, y, q, r);
   76|    686|   r_out = r;
   77|    686|   q_out = q;
   78|    686|}
_ZN5Botan14ct_divide_wordERKNS_6BigIntEmRS0_Rm:
   80|  24.5k|void ct_divide_word(const BigInt& x, word y, BigInt& q_out, word& r_out) {
   81|  24.5k|   if(y == 0) {
  ------------------
  |  Branch (81:7): [True: 0, False: 24.5k]
  ------------------
   82|      0|      throw Invalid_Argument("ct_divide_word: cannot divide by zero");
   83|      0|   }
   84|       |
   85|  24.5k|   const size_t x_words = x.sig_words();
   86|  24.5k|   const size_t x_bits = x.bits();
   87|       |
   88|  24.5k|   BigInt q = BigInt::with_capacity(x_words);
   89|  24.5k|   word r = 0;
   90|       |
   91|  1.59M|   for(size_t i = 0; i != x_bits; ++i) {
  ------------------
  |  Branch (91:22): [True: 1.56M, False: 24.5k]
  ------------------
   92|  1.56M|      const size_t b = x_bits - 1 - i;
   93|  1.56M|      const bool x_b = x.get_bit(b);
   94|       |
   95|  1.56M|      const auto r_carry = CT::Mask<word>::expand(r >> (BOTAN_MP_WORD_BITS - 1));
  ------------------
  |  |   50|  1.56M|#define BOTAN_MP_WORD_BITS 64
  ------------------
   96|       |
   97|  1.56M|      r *= 2;
   98|  1.56M|      r += x_b;
   99|       |
  100|  1.56M|      const auto r_gte_y = CT::Mask<word>::is_gte(r, y) | r_carry;
  101|  1.56M|      q.conditionally_set_bit(b, r_gte_y.as_bool());
  102|  1.56M|      r = r_gte_y.select(r - y, r);
  103|  1.56M|   }
  104|       |
  105|  24.5k|   if(x.is_negative()) {
  ------------------
  |  Branch (105:7): [True: 0, False: 24.5k]
  ------------------
  106|      0|      q.flip_sign();
  107|      0|      if(r != 0) {
  ------------------
  |  Branch (107:10): [True: 0, False: 0]
  ------------------
  108|      0|         --q;
  109|      0|         r = y - r;
  110|      0|      }
  111|      0|   }
  112|       |
  113|  24.5k|   r_out = r;
  114|  24.5k|   q_out = q;
  115|  24.5k|}
_ZN5Botan14vartime_divideERKNS_6BigIntES2_RS0_S3_:
  155|  7.38k|void vartime_divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out) {
  156|  7.38k|   if(y_arg.is_zero()) {
  ------------------
  |  Branch (156:7): [True: 0, False: 7.38k]
  ------------------
  157|      0|      throw Invalid_Argument("vartime_divide: cannot divide by zero");
  158|      0|   }
  159|       |
  160|  7.38k|   const size_t y_words = y_arg.sig_words();
  161|       |
  162|  7.38k|   BOTAN_ASSERT_NOMSG(y_words > 0);
  ------------------
  |  |   60|  7.38k|   do {                                                                     \
  |  |   61|  7.38k|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 7.38k]
  |  |  ------------------
  |  |   62|  7.38k|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|  7.38k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  163|       |
  164|  7.38k|   BigInt y = y_arg;
  165|       |
  166|  7.38k|   BigInt r = x;
  167|  7.38k|   BigInt q = BigInt::zero();
  168|  7.38k|   secure_vector<word> ws;
  169|       |
  170|  7.38k|   r.set_sign(BigInt::Positive);
  171|  7.38k|   y.set_sign(BigInt::Positive);
  172|       |
  173|       |   // Calculate shifts needed to normalize y with high bit set
  174|  7.38k|   const size_t shifts = y.top_bits_free();
  175|       |
  176|  7.38k|   y <<= shifts;
  177|  7.38k|   r <<= shifts;
  178|       |
  179|       |   // we know y has not changed size, since we only shifted up to set high bit
  180|  7.38k|   const size_t t = y_words - 1;
  181|  7.38k|   const size_t n = std::max(y_words, r.sig_words()) - 1;  // r may have changed size however
  182|       |
  183|  7.38k|   BOTAN_ASSERT_NOMSG(n >= t);
  ------------------
  |  |   60|  7.38k|   do {                                                                     \
  |  |   61|  7.38k|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 7.38k]
  |  |  ------------------
  |  |   62|  7.38k|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|  7.38k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  184|       |
  185|  7.38k|   q.grow_to(n - t + 1);
  186|       |
  187|  7.38k|   word* q_words = q.mutable_data();
  188|       |
  189|  7.38k|   BigInt shifted_y = y << (BOTAN_MP_WORD_BITS * (n - t));
  ------------------
  |  |   50|  7.38k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  190|       |
  191|       |   // Set q_{n-t} to number of times r > shifted_y
  192|  7.38k|   q_words[n - t] = r.reduce_below(shifted_y, ws);
  193|       |
  194|  7.38k|   const word y_t0 = y.word_at(t);
  195|  7.38k|   const word y_t1 = y.word_at(t - 1);
  196|  7.38k|   BOTAN_DEBUG_ASSERT((y_t0 >> (BOTAN_MP_WORD_BITS - 1)) == 1);
  ------------------
  |  |   99|  7.38k|      do {                          \
  |  |  100|  7.38k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  197|       |
  198|  15.7k|   for(size_t j = n; j != t; --j) {
  ------------------
  |  Branch (198:22): [True: 8.37k, False: 7.38k]
  ------------------
  199|  8.37k|      const word x_j0 = r.word_at(j);
  200|  8.37k|      const word x_j1 = r.word_at(j - 1);
  201|  8.37k|      const word x_j2 = r.word_at(j - 2);
  202|       |
  203|  8.37k|      word qjt = bigint_divop_vartime(x_j0, x_j1, y_t0);
  204|       |
  205|  8.37k|      qjt = CT::Mask<word>::is_equal(x_j0, y_t0).select(MP_WORD_MAX, qjt);
  206|       |
  207|       |      // Per HAC 14.23, this operation is required at most twice
  208|  8.37k|      qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2);
  209|  8.37k|      qjt -= division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2);
  210|  8.37k|      BOTAN_DEBUG_ASSERT(division_check(qjt, y_t0, y_t1, x_j0, x_j1, x_j2) == false);
  ------------------
  |  |   99|  8.37k|      do {                          \
  |  |  100|  8.37k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  211|       |
  212|  8.37k|      shifted_y >>= BOTAN_MP_WORD_BITS;
  ------------------
  |  |   50|  8.37k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  213|       |      // Now shifted_y == y << (BOTAN_MP_WORD_BITS * (j-t-1))
  214|       |
  215|       |      // TODO this sequence could be better
  216|  8.37k|      r -= qjt * shifted_y;
  217|  8.37k|      qjt -= r.is_negative();
  218|  8.37k|      r += static_cast<word>(r.is_negative()) * shifted_y;
  219|       |
  220|  8.37k|      q_words[j - t - 1] = qjt;
  221|  8.37k|   }
  222|       |
  223|  7.38k|   r >>= shifts;
  224|       |
  225|  7.38k|   sign_fixup(x, y_arg, q, r);
  226|       |
  227|  7.38k|   r_out = r;
  228|  7.38k|   q_out = q;
  229|  7.38k|}
divide.cpp:_ZN5Botan12_GLOBAL__N_110sign_fixupERKNS_6BigIntES3_RS1_S4_:
   21|  8.06k|void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) {
   22|  8.06k|   q.cond_flip_sign(x.sign() != y.sign());
   23|       |
   24|  8.06k|   if(x.is_negative() && r.is_nonzero()) {
  ------------------
  |  Branch (24:7): [True: 0, False: 8.06k]
  |  Branch (24:26): [True: 0, False: 0]
  ------------------
   25|      0|      q -= 1;
   26|      0|      r = y.abs() - r;
   27|      0|   }
   28|  8.06k|}
divide.cpp:_ZN5Botan12_GLOBAL__N_114division_checkEmmmmmm:
   30|  16.7k|inline bool division_check(word q, word y2, word y1, word x3, word x2, word x1) {
   31|       |   /*
   32|       |   Compute (y3,y2,y1) = (y2,y1) * q
   33|       |   and return true if (y3,y2,y1) > (x3,x2,x1)
   34|       |   */
   35|       |
   36|  16.7k|   word y3 = 0;
   37|  16.7k|   y1 = word_madd2(q, y1, &y3);
   38|  16.7k|   y2 = word_madd2(q, y2, &y3);
   39|       |
   40|  16.7k|   const word x[3] = {x1, x2, x3};
   41|  16.7k|   const word y[3] = {y1, y2, y3};
   42|       |
   43|  16.7k|   return bigint_ct_is_lt(x, 3, y, 3).as_bool();
   44|  16.7k|}

_ZN5Botan17bigint_comba_sqr4EPmPKm:
   16|   181k|void bigint_comba_sqr4(word z[8], const word x[4]) {
   17|   181k|   word w2 = 0, w1 = 0, w0 = 0;
   18|       |
   19|   181k|   word3_muladd(&w2, &w1, &w0, x[0], x[0]);
   20|   181k|   z[0] = w0;
   21|   181k|   w0 = 0;
   22|       |
   23|   181k|   word3_muladd_2(&w0, &w2, &w1, x[0], x[1]);
   24|   181k|   z[1] = w1;
   25|   181k|   w1 = 0;
   26|       |
   27|   181k|   word3_muladd_2(&w1, &w0, &w2, x[0], x[2]);
   28|   181k|   word3_muladd(&w1, &w0, &w2, x[1], x[1]);
   29|   181k|   z[2] = w2;
   30|   181k|   w2 = 0;
   31|       |
   32|   181k|   word3_muladd_2(&w2, &w1, &w0, x[0], x[3]);
   33|   181k|   word3_muladd_2(&w2, &w1, &w0, x[1], x[2]);
   34|   181k|   z[3] = w0;
   35|   181k|   w0 = 0;
   36|       |
   37|   181k|   word3_muladd_2(&w0, &w2, &w1, x[1], x[3]);
   38|   181k|   word3_muladd(&w0, &w2, &w1, x[2], x[2]);
   39|   181k|   z[4] = w1;
   40|   181k|   w1 = 0;
   41|       |
   42|   181k|   word3_muladd_2(&w1, &w0, &w2, x[2], x[3]);
   43|   181k|   z[5] = w2;
   44|   181k|   w2 = 0;
   45|       |
   46|   181k|   word3_muladd(&w2, &w1, &w0, x[3], x[3]);
   47|   181k|   z[6] = w0;
   48|   181k|   z[7] = w1;
   49|   181k|}
_ZN5Botan17bigint_comba_mul4EPmPKmS2_:
   54|  55.2k|void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) {
   55|  55.2k|   word w2 = 0, w1 = 0, w0 = 0;
   56|       |
   57|  55.2k|   word3_muladd(&w2, &w1, &w0, x[0], y[0]);
   58|  55.2k|   z[0] = w0;
   59|  55.2k|   w0 = 0;
   60|       |
   61|  55.2k|   word3_muladd(&w0, &w2, &w1, x[0], y[1]);
   62|  55.2k|   word3_muladd(&w0, &w2, &w1, x[1], y[0]);
   63|  55.2k|   z[1] = w1;
   64|  55.2k|   w1 = 0;
   65|       |
   66|  55.2k|   word3_muladd(&w1, &w0, &w2, x[0], y[2]);
   67|  55.2k|   word3_muladd(&w1, &w0, &w2, x[1], y[1]);
   68|  55.2k|   word3_muladd(&w1, &w0, &w2, x[2], y[0]);
   69|  55.2k|   z[2] = w2;
   70|  55.2k|   w2 = 0;
   71|       |
   72|  55.2k|   word3_muladd(&w2, &w1, &w0, x[0], y[3]);
   73|  55.2k|   word3_muladd(&w2, &w1, &w0, x[1], y[2]);
   74|  55.2k|   word3_muladd(&w2, &w1, &w0, x[2], y[1]);
   75|  55.2k|   word3_muladd(&w2, &w1, &w0, x[3], y[0]);
   76|  55.2k|   z[3] = w0;
   77|  55.2k|   w0 = 0;
   78|       |
   79|  55.2k|   word3_muladd(&w0, &w2, &w1, x[1], y[3]);
   80|  55.2k|   word3_muladd(&w0, &w2, &w1, x[2], y[2]);
   81|  55.2k|   word3_muladd(&w0, &w2, &w1, x[3], y[1]);
   82|  55.2k|   z[4] = w1;
   83|  55.2k|   w1 = 0;
   84|       |
   85|  55.2k|   word3_muladd(&w1, &w0, &w2, x[2], y[3]);
   86|  55.2k|   word3_muladd(&w1, &w0, &w2, x[3], y[2]);
   87|  55.2k|   z[5] = w2;
   88|  55.2k|   w2 = 0;
   89|       |
   90|  55.2k|   word3_muladd(&w2, &w1, &w0, x[3], y[3]);
   91|  55.2k|   z[6] = w0;
   92|  55.2k|   z[7] = w1;
   93|  55.2k|}

_ZN5Botan12basecase_mulEPmmPKmmS2_m:
   20|  4.03k|void basecase_mul(word z[], size_t z_size, const word x[], size_t x_size, const word y[], size_t y_size) {
   21|  4.03k|   if(z_size < x_size + y_size) {
  ------------------
  |  Branch (21:7): [True: 0, False: 4.03k]
  ------------------
   22|      0|      throw Invalid_Argument("basecase_mul z_size too small");
   23|      0|   }
   24|       |
   25|  4.03k|   const size_t x_size_8 = x_size - (x_size % 8);
   26|       |
   27|  4.03k|   clear_mem(z, z_size);
   28|       |
   29|  24.2k|   for(size_t i = 0; i != y_size; ++i) {
  ------------------
  |  Branch (29:22): [True: 20.1k, False: 4.03k]
  ------------------
   30|  20.1k|      const word y_i = y[i];
   31|       |
   32|  20.1k|      word carry = 0;
   33|       |
   34|  20.1k|      for(size_t j = 0; j != x_size_8; j += 8) {
  ------------------
  |  Branch (34:25): [True: 0, False: 20.1k]
  ------------------
   35|      0|         carry = word8_madd3(z + i + j, x + j, y_i, carry);
   36|      0|      }
   37|       |
   38|   102k|      for(size_t j = x_size_8; j != x_size; ++j) {
  ------------------
  |  Branch (38:32): [True: 81.9k, False: 20.1k]
  ------------------
   39|  81.9k|         z[i + j] = word_madd3(x[j], y_i, z[i + j], &carry);
   40|  81.9k|      }
   41|       |
   42|  20.1k|      z[x_size + i] = carry;
   43|  20.1k|   }
   44|  4.03k|}
_ZN5Botan12basecase_sqrEPmmPKmm:
   46|      7|void basecase_sqr(word z[], size_t z_size, const word x[], size_t x_size) {
   47|      7|   if(z_size < 2 * x_size) {
  ------------------
  |  Branch (47:7): [True: 0, False: 7]
  ------------------
   48|      0|      throw Invalid_Argument("basecase_sqr z_size too small");
   49|      0|   }
   50|       |
   51|      7|   const size_t x_size_8 = x_size - (x_size % 8);
   52|       |
   53|      7|   clear_mem(z, z_size);
   54|       |
   55|     21|   for(size_t i = 0; i != x_size; ++i) {
  ------------------
  |  Branch (55:22): [True: 14, False: 7]
  ------------------
   56|     14|      const word x_i = x[i];
   57|       |
   58|     14|      word carry = 0;
   59|       |
   60|     14|      for(size_t j = 0; j != x_size_8; j += 8) {
  ------------------
  |  Branch (60:25): [True: 0, False: 14]
  ------------------
   61|      0|         carry = word8_madd3(z + i + j, x + j, x_i, carry);
   62|      0|      }
   63|       |
   64|     48|      for(size_t j = x_size_8; j != x_size; ++j) {
  ------------------
  |  Branch (64:32): [True: 34, False: 14]
  ------------------
   65|     34|         z[i + j] = word_madd3(x[j], x_i, z[i + j], &carry);
   66|     34|      }
   67|       |
   68|     14|      z[x_size + i] = carry;
   69|     14|   }
   70|      7|}
_ZN5Botan10bigint_mulEPmmPKmmmS2_mmS0_m:
  291|  59.3k|                size_t ws_size) {
  292|  59.3k|   clear_mem(z, z_size);
  293|       |
  294|  59.3k|   if(x_sw == 1) {
  ------------------
  |  Branch (294:7): [True: 0, False: 59.3k]
  ------------------
  295|      0|      bigint_linmul3(z, y, y_sw, x[0]);
  296|  59.3k|   } else if(y_sw == 1) {
  ------------------
  |  Branch (296:14): [True: 0, False: 59.3k]
  ------------------
  297|      0|      bigint_linmul3(z, x, x_sw, y[0]);
  298|  59.3k|   } else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (298:14): [True: 55.2k, False: 4.03k]
  ------------------
  299|  55.2k|      bigint_comba_mul4(z, x, y);
  300|  55.2k|   } else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (300:14): [True: 0, False: 4.03k]
  ------------------
  301|      0|      bigint_comba_mul6(z, x, y);
  302|  4.03k|   } else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (302:14): [True: 0, False: 4.03k]
  ------------------
  303|      0|      bigint_comba_mul8(z, x, y);
  304|  4.03k|   } else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (304:14): [True: 0, False: 4.03k]
  ------------------
  305|      0|      bigint_comba_mul9(z, x, y);
  306|  4.03k|   } else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (306:14): [True: 0, False: 4.03k]
  ------------------
  307|      0|      bigint_comba_mul16(z, x, y);
  308|  4.03k|   } else if(sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (308:14): [True: 0, False: 4.03k]
  ------------------
  309|      0|      bigint_comba_mul24(z, x, y);
  310|  4.03k|   } else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || y_sw < KARATSUBA_MULTIPLY_THRESHOLD || !workspace) {
  ------------------
  |  Branch (310:14): [True: 4.03k, False: 0]
  |  Branch (310:53): [True: 0, False: 0]
  |  Branch (310:92): [True: 0, False: 0]
  ------------------
  311|  4.03k|      basecase_mul(z, z_size, x, x_sw, y, y_sw);
  312|  4.03k|   } 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|  59.3k|}
_ZN5Botan10bigint_sqrEPmmPKmmmS0_m:
  326|   181k|void bigint_sqr(word z[], size_t z_size, const word x[], size_t x_size, size_t x_sw, word workspace[], size_t ws_size) {
  327|   181k|   clear_mem(z, z_size);
  328|       |
  329|   181k|   BOTAN_ASSERT(z_size / 2 >= x_sw, "Output size is sufficient");
  ------------------
  |  |   51|   181k|   do {                                                                                 \
  |  |   52|   181k|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 181k]
  |  |  ------------------
  |  |   53|   181k|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|   181k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  330|       |
  331|   181k|   if(x_sw == 1) {
  ------------------
  |  Branch (331:7): [True: 35, False: 181k]
  ------------------
  332|     35|      bigint_linmul3(z, x, x_sw, x[0]);
  333|   181k|   } else if(sized_for_comba_sqr<4>(x_sw, x_size, z_size)) {
  ------------------
  |  Branch (333:14): [True: 181k, False: 7]
  ------------------
  334|   181k|      bigint_comba_sqr4(z, x);
  335|   181k|   } else if(sized_for_comba_sqr<6>(x_sw, x_size, z_size)) {
  ------------------
  |  Branch (335:14): [True: 0, False: 7]
  ------------------
  336|      0|      bigint_comba_sqr6(z, x);
  337|      7|   } else if(sized_for_comba_sqr<8>(x_sw, x_size, z_size)) {
  ------------------
  |  Branch (337:14): [True: 0, False: 7]
  ------------------
  338|      0|      bigint_comba_sqr8(z, x);
  339|      7|   } else if(sized_for_comba_sqr<9>(x_sw, x_size, z_size)) {
  ------------------
  |  Branch (339:14): [True: 0, False: 7]
  ------------------
  340|      0|      bigint_comba_sqr9(z, x);
  341|      7|   } else if(sized_for_comba_sqr<16>(x_sw, x_size, z_size)) {
  ------------------
  |  Branch (341:14): [True: 0, False: 7]
  ------------------
  342|      0|      bigint_comba_sqr16(z, x);
  343|      7|   } else if(sized_for_comba_sqr<24>(x_sw, x_size, z_size)) {
  ------------------
  |  Branch (343:14): [True: 0, False: 7]
  ------------------
  344|      0|      bigint_comba_sqr24(z, x);
  345|      7|   } else if(x_size < KARATSUBA_SQUARE_THRESHOLD || !workspace) {
  ------------------
  |  Branch (345:14): [True: 7, False: 0]
  |  Branch (345:53): [True: 0, False: 0]
  ------------------
  346|      7|      basecase_sqr(z, z_size, x, x_sw);
  347|      7|   } else {
  348|      0|      const size_t N = karatsuba_size(z_size, x_size, x_sw);
  349|       |
  350|      0|      if(N && z_size >= 2 * N && ws_size >= 2 * N) {
  ------------------
  |  Branch (350:10): [True: 0, False: 0]
  |  Branch (350:15): [True: 0, False: 0]
  |  Branch (350:34): [True: 0, False: 0]
  ------------------
  351|      0|         karatsuba_sqr(z, x, N, workspace);
  352|      0|      } else {
  353|      0|         basecase_sqr(z, z_size, x, x_sw);
  354|      0|      }
  355|      0|   }
  356|   181k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm4EEEbmmmmm:
  271|  59.3k|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|  59.3k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 56.5k, False: 2.76k]
  |  Branch (272:26): [True: 56.5k, False: 0]
  |  Branch (272:42): [True: 55.2k, False: 1.27k]
  |  Branch (272:56): [True: 55.2k, False: 0]
  |  Branch (272:72): [True: 55.2k, False: 0]
  ------------------
  273|  59.3k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm6EEEbmmmmm:
  271|  4.03k|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|  4.03k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 4.03k, False: 0]
  |  Branch (272:26): [True: 4.03k, False: 0]
  |  Branch (272:42): [True: 4.03k, False: 0]
  |  Branch (272:56): [True: 4.03k, False: 0]
  |  Branch (272:72): [True: 0, False: 4.03k]
  ------------------
  273|  4.03k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm8EEEbmmmmm:
  271|  4.03k|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|  4.03k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 4.03k, False: 0]
  |  Branch (272:26): [True: 4.03k, False: 2]
  |  Branch (272:42): [True: 4.03k, False: 0]
  |  Branch (272:56): [True: 4.03k, False: 0]
  |  Branch (272:72): [True: 0, False: 4.03k]
  ------------------
  273|  4.03k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm9EEEbmmmmm:
  271|  4.03k|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|  4.03k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 4.03k, False: 0]
  |  Branch (272:26): [True: 1.12k, False: 2.91k]
  |  Branch (272:42): [True: 1.12k, False: 0]
  |  Branch (272:56): [True: 1.12k, False: 0]
  |  Branch (272:72): [True: 0, False: 1.12k]
  ------------------
  273|  4.03k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm16EEEbmmmmm:
  271|  4.03k|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|  4.03k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 4.03k, False: 0]
  |  Branch (272:26): [True: 1.12k, False: 2.91k]
  |  Branch (272:42): [True: 1.12k, False: 0]
  |  Branch (272:56): [True: 1.12k, False: 0]
  |  Branch (272:72): [True: 0, False: 1.12k]
  ------------------
  273|  4.03k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm24EEEbmmmmm:
  271|  4.03k|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|  4.03k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (272:12): [True: 4.03k, False: 0]
  |  Branch (272:26): [True: 1.12k, False: 2.91k]
  |  Branch (272:42): [True: 1.12k, False: 0]
  |  Branch (272:56): [True: 0, False: 1.12k]
  |  Branch (272:72): [True: 0, False: 0]
  ------------------
  273|  4.03k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_sqrILm4EEEbmmm:
  276|   181k|inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) {
  277|   181k|   return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (277:12): [True: 181k, False: 0]
  |  Branch (277:26): [True: 181k, False: 0]
  |  Branch (277:42): [True: 181k, False: 7]
  ------------------
  278|   181k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_sqrILm6EEEbmmm:
  276|      7|inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) {
  277|      7|   return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (277:12): [True: 7, False: 0]
  |  Branch (277:26): [True: 7, False: 0]
  |  Branch (277:42): [True: 0, False: 7]
  ------------------
  278|      7|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_sqrILm8EEEbmmm:
  276|      7|inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) {
  277|      7|   return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (277:12): [True: 7, False: 0]
  |  Branch (277:26): [True: 7, False: 0]
  |  Branch (277:42): [True: 0, False: 7]
  ------------------
  278|      7|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_sqrILm9EEEbmmm:
  276|      7|inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) {
  277|      7|   return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (277:12): [True: 7, False: 0]
  |  Branch (277:26): [True: 2, False: 5]
  |  Branch (277:42): [True: 0, False: 2]
  ------------------
  278|      7|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_sqrILm16EEEbmmm:
  276|      7|inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) {
  277|      7|   return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (277:12): [True: 7, False: 0]
  |  Branch (277:26): [True: 2, False: 5]
  |  Branch (277:42): [True: 0, False: 2]
  ------------------
  278|      7|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_sqrILm24EEEbmmm:
  276|      7|inline bool sized_for_comba_sqr(size_t x_sw, size_t x_size, size_t z_size) {
  277|      7|   return (x_sw <= SZ && x_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (277:12): [True: 7, False: 0]
  |  Branch (277:26): [True: 0, False: 7]
  |  Branch (277:42): [True: 0, False: 0]
  ------------------
  278|      7|}

_ZN5Botan19bigint_monty_redc_4EPmPKmmS0_:
   14|   231k|void bigint_monty_redc_4(word z[8], const word p[4], word p_dash, word ws[]) {
   15|   231k|   word w2 = 0, w1 = 0, w0 = 0;
   16|   231k|   w0 = z[0];
   17|   231k|   ws[0] = w0 * p_dash;
   18|   231k|   word3_muladd(&w2, &w1, &w0, ws[0], p[0]);
   19|   231k|   w0 = w1;
   20|   231k|   w1 = w2;
   21|   231k|   w2 = 0;
   22|   231k|   word3_muladd(&w2, &w1, &w0, ws[0], p[1]);
   23|   231k|   word3_add(&w2, &w1, &w0, z[1]);
   24|   231k|   ws[1] = w0 * p_dash;
   25|   231k|   word3_muladd(&w2, &w1, &w0, ws[1], p[0]);
   26|   231k|   w0 = w1;
   27|   231k|   w1 = w2;
   28|   231k|   w2 = 0;
   29|   231k|   word3_muladd(&w2, &w1, &w0, ws[0], p[2]);
   30|   231k|   word3_muladd(&w2, &w1, &w0, ws[1], p[1]);
   31|   231k|   word3_add(&w2, &w1, &w0, z[2]);
   32|   231k|   ws[2] = w0 * p_dash;
   33|   231k|   word3_muladd(&w2, &w1, &w0, ws[2], p[0]);
   34|   231k|   w0 = w1;
   35|   231k|   w1 = w2;
   36|   231k|   w2 = 0;
   37|   231k|   word3_muladd(&w2, &w1, &w0, ws[0], p[3]);
   38|   231k|   word3_muladd(&w2, &w1, &w0, ws[1], p[2]);
   39|   231k|   word3_muladd(&w2, &w1, &w0, ws[2], p[1]);
   40|   231k|   word3_add(&w2, &w1, &w0, z[3]);
   41|   231k|   ws[3] = w0 * p_dash;
   42|   231k|   word3_muladd(&w2, &w1, &w0, ws[3], p[0]);
   43|   231k|   w0 = w1;
   44|   231k|   w1 = w2;
   45|   231k|   w2 = 0;
   46|   231k|   word3_muladd(&w2, &w1, &w0, ws[1], p[3]);
   47|   231k|   word3_muladd(&w2, &w1, &w0, ws[2], p[2]);
   48|   231k|   word3_muladd(&w2, &w1, &w0, ws[3], p[1]);
   49|   231k|   word3_add(&w2, &w1, &w0, z[4]);
   50|   231k|   ws[0] = w0;
   51|   231k|   w0 = w1;
   52|   231k|   w1 = w2;
   53|   231k|   w2 = 0;
   54|   231k|   word3_muladd(&w2, &w1, &w0, ws[2], p[3]);
   55|   231k|   word3_muladd(&w2, &w1, &w0, ws[3], p[2]);
   56|   231k|   word3_add(&w2, &w1, &w0, z[5]);
   57|   231k|   ws[1] = w0;
   58|   231k|   w0 = w1;
   59|   231k|   w1 = w2;
   60|   231k|   w2 = 0;
   61|   231k|   word3_muladd(&w2, &w1, &w0, ws[3], p[3]);
   62|   231k|   word3_add(&w2, &w1, &w0, z[6]);
   63|   231k|   ws[2] = w0;
   64|   231k|   w0 = w1;
   65|   231k|   w1 = w2;
   66|   231k|   w2 = 0;
   67|   231k|   word3_add(&w2, &w1, &w0, z[7]);
   68|   231k|   ws[3] = w0;
   69|   231k|   ws[4] = w1;
   70|   231k|   word borrow = bigint_sub3(z, ws, 4 + 1, p, 4);
   71|   231k|   CT::conditional_assign_mem(borrow, z, ws, 4);
   72|   231k|   clear_mem(z + 4, 4);
   73|   231k|}

_ZN5Botan12random_primeERNS_21RandomNumberGeneratorEmRKNS_6BigIntEmmm:
   98|      1|   RandomNumberGenerator& rng, size_t bits, const BigInt& coprime, size_t equiv, size_t modulo, size_t prob) {
   99|      1|   if(bits <= 1) {
  ------------------
  |  Branch (99:7): [True: 0, False: 1]
  ------------------
  100|      0|      throw Invalid_Argument("random_prime: Can't make a prime of " + std::to_string(bits) + " bits");
  101|      0|   }
  102|      1|   if(coprime.is_negative() || (!coprime.is_zero() && coprime.is_even()) || coprime.bits() >= bits) {
  ------------------
  |  Branch (102:7): [True: 0, False: 1]
  |  Branch (102:33): [True: 0, False: 1]
  |  Branch (102:55): [True: 0, False: 0]
  |  Branch (102:77): [True: 0, False: 1]
  ------------------
  103|      0|      throw Invalid_Argument("random_prime: invalid coprime");
  104|      0|   }
  105|      1|   if(modulo == 0 || modulo >= 100000) {
  ------------------
  |  Branch (105:7): [True: 0, False: 1]
  |  Branch (105:22): [True: 0, False: 1]
  ------------------
  106|      0|      throw Invalid_Argument("random_prime: Invalid modulo value");
  107|      0|   }
  108|       |
  109|      1|   equiv %= modulo;
  110|       |
  111|      1|   if(equiv == 0) {
  ------------------
  |  Branch (111:7): [True: 0, False: 1]
  ------------------
  112|      0|      throw Invalid_Argument("random_prime Invalid value for equiv/modulo");
  113|      0|   }
  114|       |
  115|       |   // Handle small values:
  116|       |
  117|      1|   if(bits <= 16) {
  ------------------
  |  Branch (117:7): [True: 0, False: 1]
  ------------------
  118|      0|      if(equiv != 1 || modulo != 2 || coprime != 0) {
  ------------------
  |  Branch (118:10): [True: 0, False: 0]
  |  Branch (118:24): [True: 0, False: 0]
  |  Branch (118:39): [True: 0, False: 0]
  ------------------
  119|      0|         throw Not_Implemented("random_prime equiv/modulo/coprime options not usable for small primes");
  120|      0|      }
  121|       |
  122|      0|      if(bits == 2) {
  ------------------
  |  Branch (122:10): [True: 0, False: 0]
  ------------------
  123|      0|         return BigInt::from_word(((rng.next_byte() % 2) ? 2 : 3));
  ------------------
  |  Branch (123:36): [True: 0, False: 0]
  ------------------
  124|      0|      } else if(bits == 3) {
  ------------------
  |  Branch (124:17): [True: 0, False: 0]
  ------------------
  125|      0|         return BigInt::from_word(((rng.next_byte() % 2) ? 5 : 7));
  ------------------
  |  Branch (125:36): [True: 0, False: 0]
  ------------------
  126|      0|      } else if(bits == 4) {
  ------------------
  |  Branch (126:17): [True: 0, False: 0]
  ------------------
  127|      0|         return BigInt::from_word(((rng.next_byte() % 2) ? 11 : 13));
  ------------------
  |  Branch (127:36): [True: 0, False: 0]
  ------------------
  128|      0|      } else {
  129|      0|         for(;;) {
  130|       |            // This is slightly biased, but for small primes it does not seem to matter
  131|      0|            uint8_t b[4] = {0};
  132|      0|            rng.randomize(b, 4);
  133|      0|            const size_t idx = load_le<uint32_t>(b, 0) % PRIME_TABLE_SIZE;
  134|      0|            const uint16_t small_prime = PRIMES[idx];
  135|       |
  136|      0|            if(high_bit(small_prime) == bits) {
  ------------------
  |  Branch (136:16): [True: 0, False: 0]
  ------------------
  137|      0|               return BigInt::from_word(small_prime);
  138|      0|            }
  139|      0|         }
  140|      0|      }
  141|      0|   }
  142|       |
  143|      1|   const size_t MAX_ATTEMPTS = 32 * 1024;
  144|       |
  145|      1|   const size_t mr_trials = miller_rabin_test_iterations(bits, prob, true);
  146|       |
  147|      1|   while(true) {
  ------------------
  |  Branch (147:10): [Folded - Ignored]
  ------------------
  148|      1|      BigInt p(rng, bits);
  149|       |
  150|       |      // Force lowest and two top bits on
  151|      1|      p.set_bit(bits - 1);
  152|      1|      p.set_bit(bits - 2);
  153|      1|      p.set_bit(0);
  154|       |
  155|       |      // Force p to be equal to equiv mod modulo
  156|      1|      p += (modulo - (p % modulo)) + equiv;
  157|       |
  158|      1|      Prime_Sieve sieve(p, bits, modulo, true);
  159|       |
  160|    999|      for(size_t attempt = 0; attempt <= MAX_ATTEMPTS; ++attempt) {
  ------------------
  |  Branch (160:31): [True: 999, False: 0]
  ------------------
  161|    999|         p += modulo;
  162|       |
  163|    999|         if(!sieve.next()) {
  ------------------
  |  Branch (163:13): [True: 984, False: 15]
  ------------------
  164|    984|            continue;
  165|    984|         }
  166|       |
  167|       |         // here p can be even if modulo is odd, continue on in that case
  168|     15|         if(p.is_even()) {
  ------------------
  |  Branch (168:13): [True: 0, False: 15]
  ------------------
  169|      0|            continue;
  170|      0|         }
  171|       |
  172|     15|         BOTAN_DEBUG_ASSERT(no_small_multiples(p, sieve));
  ------------------
  |  |   99|     15|      do {                          \
  |  |  100|     15|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  173|       |
  174|     15|         Modular_Reducer mod_p(p);
  175|       |
  176|     15|         if(coprime > 1) {
  ------------------
  |  Branch (176:13): [True: 0, False: 15]
  ------------------
  177|       |            /*
  178|       |            First do a single M-R iteration to quickly elimate most non-primes,
  179|       |            before doing the coprimality check which is expensive
  180|       |            */
  181|      0|            if(is_miller_rabin_probable_prime(p, mod_p, rng, 1) == false) {
  ------------------
  |  Branch (181:16): [True: 0, False: 0]
  ------------------
  182|      0|               continue;
  183|      0|            }
  184|       |
  185|       |            /*
  186|       |            * Check if p - 1 and coprime are relatively prime, using gcd.
  187|       |            * The gcd computation is const-time
  188|       |            */
  189|      0|            if(gcd(p - 1, coprime) > 1) {
  ------------------
  |  Branch (189:16): [True: 0, False: 0]
  ------------------
  190|      0|               continue;
  191|      0|            }
  192|      0|         }
  193|       |
  194|     15|         if(p.bits() > bits) {
  ------------------
  |  Branch (194:13): [True: 0, False: 15]
  ------------------
  195|      0|            break;
  196|      0|         }
  197|       |
  198|     15|         if(is_miller_rabin_probable_prime(p, mod_p, rng, mr_trials) == false) {
  ------------------
  |  Branch (198:13): [True: 14, False: 1]
  ------------------
  199|     14|            continue;
  200|     14|         }
  201|       |
  202|      1|         if(prob > 32 && !is_lucas_probable_prime(p, mod_p)) {
  ------------------
  |  Branch (202:13): [True: 1, False: 0]
  |  Branch (202:26): [True: 0, False: 1]
  ------------------
  203|      0|            continue;
  204|      0|         }
  205|       |
  206|      1|         return p;
  207|      1|      }
  208|      1|   }
  209|      1|}
make_prm.cpp:_ZN5Botan12_GLOBAL__N_111Prime_SieveC2ERKNS_6BigIntEmmb:
   25|      1|            m_sieve(std::min(sieve_size, PRIME_TABLE_SIZE)), m_step(step), m_check_2p1(check_2p1) {
   26|    257|         for(size_t i = 0; i != m_sieve.size(); ++i) {
  ------------------
  |  Branch (26:28): [True: 256, False: 1]
  ------------------
   27|    256|            m_sieve[i] = init_value % PRIMES[i];
   28|    256|         }
   29|      1|      }
make_prm.cpp:_ZN5Botan12_GLOBAL__N_111Prime_Sieve4nextEv:
   35|    999|      bool next() {
   36|    999|         auto passes = CT::Mask<word>::set();
   37|   256k|         for(size_t i = 0; i != m_sieve.size(); ++i) {
  ------------------
  |  Branch (37:28): [True: 255k, False: 999]
  ------------------
   38|   255k|            m_sieve[i] = (m_sieve[i] + m_step) % PRIMES[i];
   39|       |
   40|       |            // If m_sieve[i] == 0 then val % p == 0 -> not prime
   41|   255k|            passes &= CT::Mask<word>::expand(m_sieve[i]);
   42|       |
   43|   255k|            if(this->check_2p1()) {
  ------------------
  |  Branch (43:16): [True: 255k, False: 0]
  ------------------
   44|       |               /*
   45|       |               If v % p == (p-1)/2 then 2*v+1 == 0 (mod p)
   46|       |
   47|       |               So if potentially generating a safe prime, we want to
   48|       |               avoid this value because 2*v+1 will certainly not be prime.
   49|       |
   50|       |               See "Safe Prime Generation with a Combined Sieve" M. Wiener
   51|       |               https://eprint.iacr.org/2003/186.pdf
   52|       |               */
   53|   255k|               passes &= ~CT::Mask<word>::is_equal(m_sieve[i], (PRIMES[i] - 1) / 2);
   54|   255k|            }
   55|   255k|         }
   56|       |
   57|    999|         return passes.as_bool();
   58|    999|      }
make_prm.cpp:_ZNK5Botan12_GLOBAL__N_111Prime_Sieve9check_2p1Ev:
   33|   255k|      bool check_2p1() const { return m_check_2p1; }

_ZN5Botan13monty_inverseEm:
   16|    685|word monty_inverse(word a) {
   17|    685|   if(a % 2 == 0) {
  ------------------
  |  Branch (17:7): [True: 0, False: 685]
  ------------------
   18|      0|      throw Invalid_Argument("monty_inverse only valid for odd integers");
   19|      0|   }
   20|       |
   21|       |   /*
   22|       |   * From "A New Algorithm for Inversion mod p^k" by Çetin Kaya Koç
   23|       |   * https://eprint.iacr.org/2017/411.pdf sections 5 and 7.
   24|       |   */
   25|       |
   26|    685|   word b = 1;
   27|    685|   word r = 0;
   28|       |
   29|  44.5k|   for(size_t i = 0; i != BOTAN_MP_WORD_BITS; ++i) {
  ------------------
  |  |   50|  44.5k|#define BOTAN_MP_WORD_BITS 64
  ------------------
  |  Branch (29:22): [True: 43.8k, False: 685]
  ------------------
   30|  43.8k|      const word bi = b % 2;
   31|  43.8k|      r >>= 1;
   32|  43.8k|      r += bi << (BOTAN_MP_WORD_BITS - 1);
  ------------------
  |  |   50|  43.8k|#define BOTAN_MP_WORD_BITS 64
  ------------------
   33|       |
   34|  43.8k|      b -= a * bi;
   35|  43.8k|      b >>= 1;
   36|  43.8k|   }
   37|       |
   38|       |   // Now invert in addition space
   39|    685|   r = (MP_WORD_MAX - r) + 1;
   40|       |
   41|    685|   return r;
   42|    685|}
_ZN5Botan17Montgomery_ParamsC2ERKNS_6BigIntERKNS_15Modular_ReducerE:
   44|    685|Montgomery_Params::Montgomery_Params(const BigInt& p, const Modular_Reducer& mod_p) {
   45|    685|   if(p.is_even() || p < 3) {
  ------------------
  |  Branch (45:7): [True: 0, False: 685]
  |  Branch (45:22): [True: 0, False: 685]
  ------------------
   46|      0|      throw Invalid_Argument("Montgomery_Params invalid modulus");
   47|      0|   }
   48|       |
   49|    685|   m_p = p;
   50|    685|   m_p_words = m_p.sig_words();
   51|    685|   m_p_dash = monty_inverse(m_p.word_at(0));
   52|       |
   53|    685|   const BigInt r = BigInt::power_of_2(m_p_words * BOTAN_MP_WORD_BITS);
  ------------------
  |  |   50|    685|#define BOTAN_MP_WORD_BITS 64
  ------------------
   54|       |
   55|    685|   m_r1 = mod_p.reduce(r);
   56|    685|   m_r2 = mod_p.square(m_r1);
   57|    685|   m_r3 = mod_p.multiply(m_r1, m_r2);
   58|    685|}
_ZNK5Botan17Montgomery_Params4redcERKNS_6BigIntERNSt3__16vectorImNS_16secure_allocatorImEEEE:
   84|    713|BigInt Montgomery_Params::redc(const BigInt& x, secure_vector<word>& ws) const {
   85|    713|   const size_t output_size = m_p_words + 1;
   86|       |
   87|    713|   if(ws.size() < output_size) {
  ------------------
  |  Branch (87:7): [True: 713, False: 0]
  ------------------
   88|    713|      ws.resize(output_size);
   89|    713|   }
   90|       |
   91|    713|   BigInt z = x;
   92|    713|   z.grow_to(2 * m_p_words);
   93|       |
   94|    713|   bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size());
   95|       |
   96|    713|   return z;
   97|    713|}
_ZNK5Botan17Montgomery_Params3mulERKNS_6BigIntES3_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
   99|  10.6k|BigInt Montgomery_Params::mul(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const {
  100|  10.6k|   const size_t output_size = 2 * m_p_words + 2;
  101|       |
  102|  10.6k|   if(ws.size() < output_size) {
  ------------------
  |  Branch (102:7): [True: 10.6k, False: 0]
  ------------------
  103|  10.6k|      ws.resize(output_size);
  104|  10.6k|   }
  105|       |
  106|  10.6k|   BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words);
  ------------------
  |  |   99|  10.6k|      do {                          \
  |  |  100|  10.6k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  107|  10.6k|   BOTAN_DEBUG_ASSERT(y.sig_words() <= m_p_words);
  ------------------
  |  |   99|  10.6k|      do {                          \
  |  |  100|  10.6k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  108|       |
  109|  10.6k|   BigInt z = BigInt::with_capacity(output_size);
  110|  10.6k|   bigint_mul(z.mutable_data(),
  111|  10.6k|              z.size(),
  112|  10.6k|              x.data(),
  113|  10.6k|              x.size(),
  114|  10.6k|              std::min(m_p_words, x.size()),
  115|  10.6k|              y.data(),
  116|  10.6k|              y.size(),
  117|  10.6k|              std::min(m_p_words, y.size()),
  118|  10.6k|              ws.data(),
  119|  10.6k|              ws.size());
  120|       |
  121|  10.6k|   bigint_monty_redc(z.mutable_data(), m_p.data(), m_p_words, m_p_dash, ws.data(), ws.size());
  122|       |
  123|  10.6k|   return z;
  124|  10.6k|}
_ZNK5Botan17Montgomery_Params6mul_byERNS_6BigIntERKNSt3__16vectorImNS_16secure_allocatorImEEEERS7_:
  151|  2.70k|void Montgomery_Params::mul_by(BigInt& x, const secure_vector<word>& y, secure_vector<word>& ws) const {
  152|  2.70k|   const size_t output_size = 2 * m_p_words;
  153|       |
  154|  2.70k|   if(ws.size() < 2 * output_size) {
  ------------------
  |  Branch (154:7): [True: 0, False: 2.70k]
  ------------------
  155|      0|      ws.resize(2 * output_size);
  156|      0|   }
  157|       |
  158|  2.70k|   word* z_data = &ws[0];
  159|  2.70k|   word* ws_data = &ws[output_size];
  160|       |
  161|  2.70k|   BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words);
  ------------------
  |  |   99|  2.70k|      do {                          \
  |  |  100|  2.70k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  162|       |
  163|  2.70k|   bigint_mul(z_data,
  164|  2.70k|              output_size,
  165|  2.70k|              x.data(),
  166|  2.70k|              x.size(),
  167|  2.70k|              std::min(m_p_words, x.size()),
  168|  2.70k|              y.data(),
  169|  2.70k|              y.size(),
  170|  2.70k|              std::min(m_p_words, y.size()),
  171|  2.70k|              ws_data,
  172|  2.70k|              output_size);
  173|       |
  174|  2.70k|   bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size);
  175|       |
  176|  2.70k|   if(x.size() < output_size) {
  ------------------
  |  Branch (176:7): [True: 0, False: 2.70k]
  ------------------
  177|      0|      x.grow_to(output_size);
  178|      0|   }
  179|  2.70k|   copy_mem(x.mutable_data(), z_data, output_size);
  180|  2.70k|}
_ZNK5Botan17Montgomery_Params6mul_byERNS_6BigIntERKS1_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  182|  38.1k|void Montgomery_Params::mul_by(BigInt& x, const BigInt& y, secure_vector<word>& ws) const {
  183|  38.1k|   const size_t output_size = 2 * m_p_words;
  184|       |
  185|  38.1k|   if(ws.size() < 2 * output_size) {
  ------------------
  |  Branch (185:7): [True: 0, False: 38.1k]
  ------------------
  186|      0|      ws.resize(2 * output_size);
  187|      0|   }
  188|       |
  189|  38.1k|   word* z_data = &ws[0];
  190|  38.1k|   word* ws_data = &ws[output_size];
  191|       |
  192|  38.1k|   BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words);
  ------------------
  |  |   99|  38.1k|      do {                          \
  |  |  100|  38.1k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  193|       |
  194|  38.1k|   bigint_mul(z_data,
  195|  38.1k|              output_size,
  196|  38.1k|              x.data(),
  197|  38.1k|              x.size(),
  198|  38.1k|              std::min(m_p_words, x.size()),
  199|  38.1k|              y.data(),
  200|  38.1k|              y.size(),
  201|  38.1k|              std::min(m_p_words, y.size()),
  202|  38.1k|              ws_data,
  203|  38.1k|              output_size);
  204|       |
  205|  38.1k|   bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size);
  206|       |
  207|  38.1k|   if(x.size() < output_size) {
  ------------------
  |  Branch (207:7): [True: 0, False: 38.1k]
  ------------------
  208|      0|      x.grow_to(output_size);
  209|      0|   }
  210|  38.1k|   copy_mem(x.mutable_data(), z_data, output_size);
  211|  38.1k|}
_ZNK5Botan17Montgomery_Params11square_thisERNS_6BigIntERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  231|   179k|void Montgomery_Params::square_this(BigInt& x, secure_vector<word>& ws) const {
  232|   179k|   const size_t output_size = 2 * m_p_words;
  233|       |
  234|   179k|   if(ws.size() < 2 * output_size) {
  ------------------
  |  Branch (234:7): [True: 713, False: 178k]
  ------------------
  235|    713|      ws.resize(2 * output_size);
  236|    713|   }
  237|       |
  238|   179k|   word* z_data = &ws[0];
  239|   179k|   word* ws_data = &ws[output_size];
  240|       |
  241|   179k|   BOTAN_DEBUG_ASSERT(x.sig_words() <= m_p_words);
  ------------------
  |  |   99|   179k|      do {                          \
  |  |  100|   179k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
  242|       |
  243|   179k|   bigint_sqr(z_data, output_size, x.data(), x.size(), std::min(m_p_words, x.size()), ws_data, output_size);
  244|       |
  245|   179k|   bigint_monty_redc(z_data, m_p.data(), m_p_words, m_p_dash, ws_data, output_size);
  246|       |
  247|   179k|   if(x.size() < output_size) {
  ------------------
  |  Branch (247:7): [True: 43, False: 179k]
  ------------------
  248|     43|      x.grow_to(output_size);
  249|     43|   }
  250|   179k|   copy_mem(x.mutable_data(), z_data, output_size);
  251|   179k|}
_ZN5Botan14Montgomery_IntC2ERKNSt3__110shared_ptrIKNS_17Montgomery_ParamsEEERKNS_6BigIntEb:
  256|  11.4k|      m_params(params) {
  257|  11.4k|   if(redc_needed == false) {
  ------------------
  |  Branch (257:7): [True: 10.6k, False: 713]
  ------------------
  258|  10.6k|      m_v = v;
  259|  10.6k|   } else {
  260|    713|      BOTAN_ASSERT_NOMSG(m_v < m_params->p());
  ------------------
  |  |   60|    713|   do {                                                                     \
  |  |   61|    713|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 713]
  |  |  ------------------
  |  |   62|    713|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|    713|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  261|    713|      secure_vector<word> ws;
  262|    713|      m_v = m_params->mul(v, m_params->R2(), ws);
  263|    713|   }
  264|  11.4k|}
_ZN5Botan14Montgomery_IntC2ENSt3__110shared_ptrIKNS_17Montgomery_ParamsEEEPKmmb:
  282|     43|      m_params(std::move(params)) {
  283|     43|   m_v.set_words(words, len);
  284|       |
  285|     43|   if(redc_needed) {
  ------------------
  |  Branch (285:7): [True: 0, False: 43]
  ------------------
  286|      0|      BOTAN_ASSERT_NOMSG(m_v < m_params->p());
  ------------------
  |  |   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]
  |  |  ------------------
  ------------------
  287|      0|      secure_vector<word> ws;
  288|      0|      m_v = m_params->mul(m_v, m_params->R2(), ws);
  289|      0|   }
  290|     43|}
_ZN5Botan14Montgomery_Int8fix_sizeEv:
  292|  11.4k|void Montgomery_Int::fix_size() {
  293|  11.4k|   const size_t p_words = m_params->p_words();
  294|       |
  295|  11.4k|   if(m_v.sig_words() > p_words) {
  ------------------
  |  Branch (295:7): [True: 0, False: 11.4k]
  ------------------
  296|      0|      throw Internal_Error("Montgomery_Int::fix_size v too large");
  297|      0|   }
  298|       |
  299|  11.4k|   m_v.grow_to(p_words);
  300|  11.4k|}
_ZNK5Botan14Montgomery_Int5valueEv:
  324|    713|BigInt Montgomery_Int::value() const {
  325|    713|   secure_vector<word> ws;
  326|    713|   return m_params->redc(m_v, ws);
  327|    713|}
_ZNK5Botan14Montgomery_IntmlERKS0_:
  363|  9.98k|Montgomery_Int Montgomery_Int::operator*(const Montgomery_Int& other) const {
  364|  9.98k|   secure_vector<word> ws;
  365|  9.98k|   return Montgomery_Int(m_params, m_params->mul(m_v, other.m_v, ws), false);
  366|  9.98k|}
_ZN5Botan14Montgomery_Int6mul_byERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  372|  38.1k|Montgomery_Int& Montgomery_Int::mul_by(const Montgomery_Int& other, secure_vector<word>& ws) {
  373|  38.1k|   m_params->mul_by(m_v, other.m_v, ws);
  374|  38.1k|   return (*this);
  375|  38.1k|}
_ZN5Botan14Montgomery_Int6mul_byERKNSt3__16vectorImNS_16secure_allocatorImEEEERS5_:
  377|  2.70k|Montgomery_Int& Montgomery_Int::mul_by(const secure_vector<word>& other, secure_vector<word>& ws) {
  378|  2.70k|   m_params->mul_by(m_v, other, ws);
  379|  2.70k|   return (*this);
  380|  2.70k|}
_ZN5Botan14Montgomery_Int19square_this_n_timesERNSt3__16vectorImNS_16secure_allocatorImEEEEm:
  392|  44.9k|Montgomery_Int& Montgomery_Int::square_this_n_times(secure_vector<word>& ws, size_t n) {
  393|   224k|   for(size_t i = 0; i != n; ++i) {
  ------------------
  |  Branch (393:22): [True: 179k, False: 44.9k]
  ------------------
  394|   179k|      m_params->square_this(m_v, ws);
  395|   179k|   }
  396|  44.9k|   return (*this);
  397|  44.9k|}

_ZN5Botan30Montgomery_Exponentation_StateC2ERKNSt3__110shared_ptrIKNS_17Montgomery_ParamsEEERKNS_6BigIntEmb:
   40|    713|      m_params(params), m_window_bits(window_bits == 0 ? 4 : window_bits) {
   41|    713|   BOTAN_ARG_CHECK(g < m_params->p(), "Montgomery base too big");
  ------------------
  |  |   30|    713|   do {                                                          \
  |  |   31|    713|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 713]
  |  |  ------------------
  |  |   32|    713|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|    713|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   42|       |
   43|    713|   if(m_window_bits < 1 || m_window_bits > 12) {  // really even 8 is too large ...
  ------------------
  |  Branch (43:7): [True: 0, False: 713]
  |  Branch (43:28): [True: 0, False: 713]
  ------------------
   44|      0|      throw Invalid_Argument("Invalid window bits for Montgomery exponentiation");
   45|      0|   }
   46|       |
   47|    713|   const size_t window_size = (static_cast<size_t>(1) << m_window_bits);
   48|       |
   49|    713|   m_g.reserve(window_size);
   50|       |
   51|    713|   m_g.push_back(Montgomery_Int(m_params, m_params->R1(), false));
   52|       |
   53|    713|   m_g.push_back(Montgomery_Int(m_params, g));
   54|       |
   55|  10.6k|   for(size_t i = 2; i != window_size; ++i) {
  ------------------
  |  Branch (55:22): [True: 9.98k, False: 713]
  ------------------
   56|  9.98k|      m_g.push_back(m_g[1] * m_g[i - 1]);
   57|  9.98k|   }
   58|       |
   59|       |   // Resize each element to exactly p words
   60|  12.1k|   for(size_t i = 0; i != window_size; ++i) {
  ------------------
  |  Branch (60:22): [True: 11.4k, False: 713]
  ------------------
   61|  11.4k|      m_g[i].fix_size();
   62|  11.4k|      if(const_time) {
  ------------------
  |  Branch (62:10): [True: 688, False: 10.7k]
  ------------------
   63|    688|         m_g[i].const_time_poison();
   64|    688|      }
   65|  11.4k|   }
   66|    713|}
_ZNK5Botan30Montgomery_Exponentation_State14exponentiationERKNS_6BigIntEm:
   95|     43|BigInt Montgomery_Exponentation_State::exponentiation(const BigInt& scalar, size_t max_k_bits) const {
   96|     43|   BOTAN_DEBUG_ASSERT(scalar.bits() <= max_k_bits);
  ------------------
  |  |   99|     43|      do {                          \
  |  |  100|     43|      } while(0)
  |  |  ------------------
  |  |  |  Branch (100:15): [Folded - Ignored]
  |  |  ------------------
  ------------------
   97|       |   // TODO add a const-time implementation of above assert and use it in release builds
   98|       |
   99|     43|   const size_t exp_nibbles = (max_k_bits + m_window_bits - 1) / m_window_bits;
  100|       |
  101|     43|   if(exp_nibbles == 0) {
  ------------------
  |  Branch (101:7): [True: 0, False: 43]
  ------------------
  102|      0|      return BigInt::one();
  103|      0|   }
  104|       |
  105|     43|   secure_vector<word> e_bits(m_params->p_words());
  106|     43|   secure_vector<word> ws;
  107|       |
  108|     43|   const_time_lookup(e_bits, m_g, scalar.get_substring(m_window_bits * (exp_nibbles - 1), m_window_bits));
  109|     43|   Montgomery_Int x(m_params, e_bits.data(), e_bits.size(), false);
  110|       |
  111|  2.75k|   for(size_t i = exp_nibbles - 1; i > 0; --i) {
  ------------------
  |  Branch (111:36): [True: 2.70k, False: 43]
  ------------------
  112|  2.70k|      x.square_this_n_times(ws, m_window_bits);
  113|  2.70k|      const_time_lookup(e_bits, m_g, scalar.get_substring(m_window_bits * (i - 1), m_window_bits));
  114|  2.70k|      x.mul_by(e_bits, ws);
  115|  2.70k|   }
  116|       |
  117|     43|   x.const_time_unpoison();
  118|     43|   return x.value();
  119|     43|}
_ZNK5Botan30Montgomery_Exponentation_State22exponentiation_vartimeERKNS_6BigIntE:
  121|    670|BigInt Montgomery_Exponentation_State::exponentiation_vartime(const BigInt& scalar) const {
  122|    670|   const size_t exp_nibbles = (scalar.bits() + m_window_bits - 1) / m_window_bits;
  123|       |
  124|    670|   secure_vector<word> ws;
  125|       |
  126|    670|   if(exp_nibbles == 0) {
  ------------------
  |  Branch (126:7): [True: 0, False: 670]
  ------------------
  127|      0|      return BigInt::one();
  128|      0|   }
  129|       |
  130|    670|   Montgomery_Int x = m_g[scalar.get_substring(m_window_bits * (exp_nibbles - 1), m_window_bits)];
  131|       |
  132|  42.8k|   for(size_t i = exp_nibbles - 1; i > 0; --i) {
  ------------------
  |  Branch (132:36): [True: 42.2k, False: 670]
  ------------------
  133|  42.2k|      x.square_this_n_times(ws, m_window_bits);
  134|       |
  135|  42.2k|      const uint32_t nibble = scalar.get_substring(m_window_bits * (i - 1), m_window_bits);
  136|  42.2k|      if(nibble > 0) {
  ------------------
  |  Branch (136:10): [True: 38.1k, False: 4.02k]
  ------------------
  137|  38.1k|         x.mul_by(m_g[nibble], ws);
  138|  38.1k|      }
  139|  42.2k|   }
  140|       |
  141|    670|   x.const_time_unpoison();
  142|    670|   return x.value();
  143|    670|}
_ZN5Botan16monty_precomputeERKNSt3__110shared_ptrIKNS_17Montgomery_ParamsEEERKNS_6BigIntEmb:
  146|    713|   const std::shared_ptr<const Montgomery_Params>& params, const BigInt& g, size_t window_bits, bool const_time) {
  147|    713|   return std::make_shared<const Montgomery_Exponentation_State>(params, g, window_bits, const_time);
  148|    713|}
_ZN5Botan13monty_executeERKNS_30Montgomery_Exponentation_StateERKNS_6BigIntEm:
  150|     43|BigInt monty_execute(const Montgomery_Exponentation_State& precomputed_state, const BigInt& k, size_t max_k_bits) {
  151|     43|   return precomputed_state.exponentiation(k, max_k_bits);
  152|     43|}
_ZN5Botan21monty_execute_vartimeERKNS_30Montgomery_Exponentation_StateERKNS_6BigIntE:
  154|    670|BigInt monty_execute_vartime(const Montgomery_Exponentation_State& precomputed_state, const BigInt& k) {
  155|    670|   return precomputed_state.exponentiation_vartime(k);
  156|    670|}
monty_exp.cpp:_ZN5Botan12_GLOBAL__N_117const_time_lookupERNSt3__16vectorImNS_16secure_allocatorImEEEERKNS2_INS_14Montgomery_IntENS1_9allocatorIS7_EEEEm:
   70|  2.75k|void const_time_lookup(secure_vector<word>& output, const std::vector<Montgomery_Int>& g, size_t nibble) {
   71|  2.75k|   BOTAN_ASSERT_NOMSG(g.size() % 2 == 0);  // actually a power of 2
  ------------------
  |  |   60|  2.75k|   do {                                                                     \
  |  |   61|  2.75k|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 2.75k]
  |  |  ------------------
  |  |   62|  2.75k|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|  2.75k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   72|       |
   73|  2.75k|   const size_t words = output.size();
   74|       |
   75|  2.75k|   clear_mem(output.data(), output.size());
   76|       |
   77|  24.7k|   for(size_t i = 0; i != g.size(); i += 2) {
  ------------------
  |  Branch (77:22): [True: 22.0k, False: 2.75k]
  ------------------
   78|  22.0k|      const secure_vector<word>& vec_0 = g[i].repr().get_word_vector();
   79|  22.0k|      const secure_vector<word>& vec_1 = g[i + 1].repr().get_word_vector();
   80|       |
   81|  22.0k|      BOTAN_ASSERT_NOMSG(vec_0.size() >= words && vec_1.size() >= words);
  ------------------
  |  |   60|  22.0k|   do {                                                                     \
  |  |   61|  44.0k|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:12): [True: 22.0k, False: 0]
  |  |  |  Branch (61:12): [True: 22.0k, False: 0]
  |  |  ------------------
  |  |   62|  22.0k|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|  22.0k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   82|       |
   83|  22.0k|      const auto mask_0 = CT::Mask<word>::is_equal(nibble, i);
   84|  22.0k|      const auto mask_1 = CT::Mask<word>::is_equal(nibble, i + 1);
   85|       |
   86|   110k|      for(size_t w = 0; w != words; ++w) {
  ------------------
  |  Branch (86:25): [True: 88.0k, False: 22.0k]
  ------------------
   87|  88.0k|         output[w] |= mask_0.if_set_return(vec_0[w]);
   88|  88.0k|         output[w] |= mask_1.if_set_return(vec_1[w]);
   89|  88.0k|      }
   90|  22.0k|   }
   91|  2.75k|}

_ZN5Botan17sqrt_modulo_primeERKNS_6BigIntES2_:
   26|  1.05k|BigInt sqrt_modulo_prime(const BigInt& a, const BigInt& p) {
   27|  1.05k|   BOTAN_ARG_CHECK(p > 1, "invalid prime");
  ------------------
  |  |   30|  1.05k|   do {                                                          \
  |  |   31|  1.05k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 1.05k]
  |  |  ------------------
  |  |   32|  1.05k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|  1.05k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   28|  1.05k|   BOTAN_ARG_CHECK(a < p, "value to solve for must be less than p");
  ------------------
  |  |   30|  1.05k|   do {                                                          \
  |  |   31|  1.05k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 1, False: 1.05k]
  |  |  ------------------
  |  |   32|  1.05k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|  1.05k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   29|  1.05k|   BOTAN_ARG_CHECK(a >= 0, "value to solve for must not be negative");
  ------------------
  |  |   30|  1.05k|   do {                                                          \
  |  |   31|  1.05k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 1.05k]
  |  |  ------------------
  |  |   32|  1.05k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|  1.05k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   30|       |
   31|       |   // some very easy cases
   32|  1.05k|   if(p == 2 || a <= 1) {
  ------------------
  |  Branch (32:7): [True: 1, False: 1.05k]
  |  Branch (32:17): [True: 2, False: 1.05k]
  ------------------
   33|      2|      return a;
   34|      2|   }
   35|       |
   36|  1.05k|   BOTAN_ARG_CHECK(p.is_odd(), "invalid prime");
  ------------------
  |  |   30|  1.05k|   do {                                                          \
  |  |   31|  1.05k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 1.05k]
  |  |  ------------------
  |  |   32|  1.05k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|  1.05k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   37|       |
   38|  1.05k|   if(jacobi(a, p) != 1) {  // not a quadratic residue
  ------------------
  |  Branch (38:7): [True: 382, False: 671]
  ------------------
   39|    382|      return BigInt::from_s32(-1);
   40|    382|   }
   41|       |
   42|    671|   Modular_Reducer mod_p(p);
   43|    671|   auto monty_p = std::make_shared<Montgomery_Params>(p, mod_p);
   44|       |
   45|       |   // If p == 3 (mod 4) there is a simple solution
   46|    671|   if(p % 4 == 3) {
  ------------------
  |  Branch (46:7): [True: 670, False: 1]
  ------------------
   47|    670|      return monty_exp_vartime(monty_p, a, ((p + 1) >> 2));
   48|    670|   }
   49|       |
   50|       |   // Otherwise we have to use Shanks-Tonelli
   51|      1|   size_t s = low_zero_bits(p - 1);
   52|      1|   BigInt q = p >> s;
   53|       |
   54|      1|   q -= 1;
   55|      1|   q >>= 1;
   56|       |
   57|      1|   BigInt r = monty_exp_vartime(monty_p, a, q);
   58|      1|   BigInt n = mod_p.multiply(a, mod_p.square(r));
   59|      1|   r = mod_p.multiply(r, a);
   60|       |
   61|      1|   if(n == 1) {
  ------------------
  |  Branch (61:7): [True: 0, False: 1]
  ------------------
   62|      0|      return r;
   63|      0|   }
   64|       |
   65|       |   // find random quadratic nonresidue z
   66|      1|   word z = 2;
   67|      1|   for(;;) {
   68|      0|      if(jacobi(BigInt::from_word(z), p) == -1) {  // found one
  ------------------
  |  Branch (68:10): [True: 0, False: 0]
  ------------------
   69|      0|         break;
   70|      0|      }
   71|       |
   72|      0|      z += 1;  // try next z
   73|       |
   74|       |      /*
   75|       |      * The expected number of tests to find a non-residue modulo a
   76|       |      * prime is 2. If we have not found one after 256 then almost
   77|       |      * certainly we have been given a non-prime p.
   78|       |      */
   79|      0|      if(z >= 256) {
  ------------------
  |  Branch (79:10): [True: 0, False: 0]
  ------------------
   80|      0|         return BigInt::from_s32(-1);
   81|      0|      }
   82|      0|   }
   83|       |
   84|      1|   BigInt c = monty_exp_vartime(monty_p, BigInt::from_word(z), (q << 1) + 1);
   85|       |
   86|      1|   while(n > 1) {
  ------------------
  |  Branch (86:10): [True: 0, False: 1]
  ------------------
   87|      0|      q = n;
   88|       |
   89|      0|      size_t i = 0;
   90|      0|      while(q != 1) {
  ------------------
  |  Branch (90:13): [True: 0, False: 0]
  ------------------
   91|      0|         q = mod_p.square(q);
   92|      0|         ++i;
   93|       |
   94|      0|         if(i >= s) {
  ------------------
  |  Branch (94:13): [True: 0, False: 0]
  ------------------
   95|      0|            return BigInt::from_s32(-1);
   96|      0|         }
   97|      0|      }
   98|       |
   99|      0|      BOTAN_ASSERT_NOMSG(s >= (i + 1));  // No underflow!
  ------------------
  |  |   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]
  |  |  ------------------
  ------------------
  100|      0|      c = monty_exp_vartime(monty_p, c, BigInt::power_of_2(s - i - 1));
  101|      0|      r = mod_p.multiply(r, c);
  102|      0|      c = mod_p.square(c);
  103|      0|      n = mod_p.multiply(n, c);
  104|       |
  105|       |      // s decreases as the algorithm proceeds
  106|      0|      BOTAN_ASSERT_NOMSG(s >= i);
  ------------------
  |  |   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]
  |  |  ------------------
  ------------------
  107|      0|      s = i;
  108|      0|   }
  109|       |
  110|      1|   return r;
  111|      1|}
_ZN5Botan6jacobiERKNS_6BigIntES2_:
  116|  1.05k|int32_t jacobi(const BigInt& a, const BigInt& n) {
  117|  1.05k|   if(n.is_even() || n < 2) {
  ------------------
  |  Branch (117:7): [True: 0, False: 1.05k]
  |  Branch (117:22): [True: 0, False: 1.05k]
  ------------------
  118|      0|      throw Invalid_Argument("jacobi: second argument must be odd and > 1");
  119|      0|   }
  120|       |
  121|  1.05k|   BigInt x = a % n;
  122|  1.05k|   BigInt y = n;
  123|  1.05k|   int32_t J = 1;
  124|       |
  125|  25.6k|   while(y > 1) {
  ------------------
  |  Branch (125:10): [True: 24.5k, False: 1.05k]
  ------------------
  126|  24.5k|      x %= y;
  127|  24.5k|      if(x > y / 2) {
  ------------------
  |  Branch (127:10): [True: 10.7k, False: 13.8k]
  ------------------
  128|  10.7k|         x = y - x;
  129|  10.7k|         if(y % 4 == 3) {
  ------------------
  |  Branch (129:13): [True: 5.50k, False: 5.22k]
  ------------------
  130|  5.50k|            J = -J;
  131|  5.50k|         }
  132|  10.7k|      }
  133|  24.5k|      if(x.is_zero()) {
  ------------------
  |  Branch (133:10): [True: 0, False: 24.5k]
  ------------------
  134|      0|         return 0;
  135|      0|      }
  136|       |
  137|  24.5k|      size_t shifts = low_zero_bits(x);
  138|  24.5k|      x >>= shifts;
  139|  24.5k|      if(shifts % 2) {
  ------------------
  |  Branch (139:10): [True: 7.46k, False: 17.1k]
  ------------------
  140|  7.46k|         word y_mod_8 = y % 8;
  141|  7.46k|         if(y_mod_8 == 3 || y_mod_8 == 5) {
  ------------------
  |  Branch (141:13): [True: 1.78k, False: 5.68k]
  |  Branch (141:29): [True: 1.84k, False: 3.83k]
  ------------------
  142|  3.63k|            J = -J;
  143|  3.63k|         }
  144|  7.46k|      }
  145|       |
  146|  24.5k|      if(x % 4 == 3 && y % 4 == 3) {
  ------------------
  |  Branch (146:10): [True: 11.9k, False: 12.6k]
  |  Branch (146:24): [True: 6.40k, False: 5.57k]
  ------------------
  147|  6.40k|         J = -J;
  148|  6.40k|      }
  149|  24.5k|      std::swap(x, y);
  150|  24.5k|   }
  151|  1.05k|   return J;
  152|  1.05k|}
_ZN5Botan6squareERKNS_6BigIntE:
  157|  1.88k|BigInt square(const BigInt& x) {
  158|  1.88k|   BigInt z = x;
  159|  1.88k|   secure_vector<word> ws;
  160|  1.88k|   z.square(ws);
  161|  1.88k|   return z;
  162|  1.88k|}
_ZN5Botan13low_zero_bitsERKNS_6BigIntE:
  167|  24.6k|size_t low_zero_bits(const BigInt& n) {
  168|  24.6k|   size_t low_zero = 0;
  169|       |
  170|  24.6k|   auto seen_nonempty_word = CT::Mask<word>::cleared();
  171|       |
  172|   221k|   for(size_t i = 0; i != n.size(); ++i) {
  ------------------
  |  Branch (172:22): [True: 196k, False: 24.6k]
  ------------------
  173|   196k|      const word x = n.word_at(i);
  174|       |
  175|       |      // ctz(0) will return sizeof(word)
  176|   196k|      const size_t tz_x = ctz(x);
  177|       |
  178|       |      // if x > 0 we want to count tz_x in total but not any
  179|       |      // further words, so set the mask after the addition
  180|   196k|      low_zero += seen_nonempty_word.if_not_set_return(tz_x);
  181|       |
  182|   196k|      seen_nonempty_word |= CT::Mask<word>::expand(x);
  183|   196k|   }
  184|       |
  185|       |   // if we saw no words with x > 0 then n == 0 and the value we have
  186|       |   // computed is meaningless. Instead return BigInt::zero() in that case.
  187|  24.6k|   return static_cast<size_t>(seen_nonempty_word.if_set_return(low_zero));
  188|  24.6k|}

_ZN5Botan23is_lucas_probable_primeERKNS_6BigIntERKNS_15Modular_ReducerE:
   18|      1|bool is_lucas_probable_prime(const BigInt& C, const Modular_Reducer& mod_C) {
   19|      1|   if(C == 2 || C == 3 || C == 5 || C == 7 || C == 11 || C == 13) {
  ------------------
  |  Branch (19:7): [True: 0, False: 1]
  |  Branch (19:17): [True: 0, False: 1]
  |  Branch (19:27): [True: 0, False: 1]
  |  Branch (19:37): [True: 0, False: 1]
  |  Branch (19:47): [True: 0, False: 1]
  |  Branch (19:58): [True: 0, False: 1]
  ------------------
   20|      0|      return true;
   21|      0|   }
   22|       |
   23|      1|   if(C <= 1 || C.is_even()) {
  ------------------
  |  Branch (23:7): [True: 0, False: 1]
  |  Branch (23:17): [True: 0, False: 1]
  ------------------
   24|      0|      return false;
   25|      0|   }
   26|       |
   27|      1|   BigInt D = BigInt::from_word(5);
   28|       |
   29|      1|   for(;;) {
   30|      1|      int32_t j = jacobi(D, C);
   31|      1|      if(j == 0) {
  ------------------
  |  Branch (31:10): [True: 0, False: 1]
  ------------------
   32|      0|         return false;
   33|      0|      }
   34|       |
   35|      1|      if(j == -1) {
  ------------------
  |  Branch (35:10): [True: 1, False: 0]
  ------------------
   36|      1|         break;
   37|      1|      }
   38|       |
   39|       |      // Check 5, -7, 9, -11, 13, -15, 17, ...
   40|      0|      if(D.is_negative()) {
  ------------------
  |  Branch (40:10): [True: 0, False: 0]
  ------------------
   41|      0|         D.flip_sign();
   42|      0|         D += 2;
   43|      0|      } else {
   44|      0|         D += 2;
   45|      0|         D.flip_sign();
   46|      0|      }
   47|       |
   48|      0|      if(D == 17 && is_perfect_square(C).is_nonzero()) {
  ------------------
  |  Branch (48:10): [True: 0, False: 0]
  |  Branch (48:10): [True: 0, False: 0]
  |  Branch (48:21): [True: 0, False: 0]
  ------------------
   49|      0|         return false;
   50|      0|      }
   51|      0|   }
   52|       |
   53|      1|   const BigInt K = C + 1;
   54|      1|   const size_t K_bits = K.bits() - 1;
   55|       |
   56|      1|   BigInt U = BigInt::one();
   57|      1|   BigInt V = BigInt::one();
   58|       |
   59|      1|   BigInt Ut, Vt, U2, V2;
   60|       |
   61|    256|   for(size_t i = 0; i != K_bits; ++i) {
  ------------------
  |  Branch (61:22): [True: 255, False: 1]
  ------------------
   62|    255|      const bool k_bit = K.get_bit(K_bits - 1 - i);
   63|       |
   64|    255|      Ut = mod_C.multiply(U, V);
   65|       |
   66|    255|      Vt = mod_C.reduce(mod_C.square(V) + mod_C.multiply(D, mod_C.square(U)));
   67|    255|      Vt.ct_cond_add(Vt.is_odd(), C);
   68|    255|      Vt >>= 1;
   69|    255|      Vt = mod_C.reduce(Vt);
   70|       |
   71|    255|      U = Ut;
   72|    255|      V = Vt;
   73|       |
   74|    255|      U2 = mod_C.reduce(Ut + Vt);
   75|    255|      U2.ct_cond_add(U2.is_odd(), C);
   76|    255|      U2 >>= 1;
   77|       |
   78|    255|      V2 = mod_C.reduce(Vt + Ut * D);
   79|    255|      V2.ct_cond_add(V2.is_odd(), C);
   80|    255|      V2 >>= 1;
   81|       |
   82|    255|      U.ct_cond_assign(k_bit, U2);
   83|    255|      V.ct_cond_assign(k_bit, V2);
   84|    255|   }
   85|       |
   86|      1|   return (U == 0);
   87|      1|}
_ZN5Botan24passes_miller_rabin_testERKNS_6BigIntERKNS_15Modular_ReducerERKNSt3__110shared_ptrINS_17Montgomery_ParamsEEES2_:
  109|     43|                              const BigInt& a) {
  110|     43|   if(n < 3 || n.is_even()) {
  ------------------
  |  Branch (110:7): [True: 0, False: 43]
  |  Branch (110:16): [True: 0, False: 43]
  ------------------
  111|      0|      return false;
  112|      0|   }
  113|       |
  114|     43|   BOTAN_ASSERT_NOMSG(n > 1);
  ------------------
  |  |   60|     43|   do {                                                                     \
  |  |   61|     43|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 43]
  |  |  ------------------
  |  |   62|     43|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|     43|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  115|       |
  116|     43|   const BigInt n_minus_1 = n - 1;
  117|     43|   const size_t s = low_zero_bits(n_minus_1);
  118|     43|   const BigInt nm1_s = n_minus_1 >> s;
  119|     43|   const size_t n_bits = n.bits();
  120|       |
  121|     43|   const size_t powm_window = 4;
  122|       |
  123|     43|   auto powm_a_n = monty_precompute(monty_n, a, powm_window);
  124|       |
  125|     43|   BigInt y = monty_execute(*powm_a_n, nm1_s, n_bits);
  126|       |
  127|     43|   if(y == 1 || y == n_minus_1) {
  ------------------
  |  Branch (127:7): [True: 13, False: 30]
  |  Branch (127:17): [True: 16, False: 14]
  ------------------
  128|     29|      return true;
  129|     29|   }
  130|       |
  131|     28|   for(size_t i = 1; i != s; ++i) {
  ------------------
  |  Branch (131:22): [True: 14, False: 14]
  ------------------
  132|     14|      y = mod_n.square(y);
  133|       |
  134|     14|      if(y == 1) {  // found a non-trivial square root
  ------------------
  |  Branch (134:10): [True: 0, False: 14]
  ------------------
  135|      0|         return false;
  136|      0|      }
  137|       |
  138|       |      /*
  139|       |      -1 is the trivial square root of unity, so ``a`` is not a
  140|       |      witness for this number - give up
  141|       |      */
  142|     14|      if(y == n_minus_1) {
  ------------------
  |  Branch (142:10): [True: 0, False: 14]
  ------------------
  143|      0|         return true;
  144|      0|      }
  145|     14|   }
  146|       |
  147|     14|   return false;
  148|     14|}
_ZN5Botan30is_miller_rabin_probable_primeERKNS_6BigIntERKNS_15Modular_ReducerERNS_21RandomNumberGeneratorEm:
  153|     15|                                    size_t test_iterations) {
  154|     15|   if(n < 3 || n.is_even()) {
  ------------------
  |  Branch (154:7): [True: 0, False: 15]
  |  Branch (154:16): [True: 0, False: 15]
  ------------------
  155|      0|      return false;
  156|      0|   }
  157|       |
  158|     15|   auto monty_n = std::make_shared<Montgomery_Params>(n, mod_n);
  159|       |
  160|     44|   for(size_t i = 0; i != test_iterations; ++i) {
  ------------------
  |  Branch (160:22): [True: 43, False: 1]
  ------------------
  161|     43|      const BigInt a = BigInt::random_integer(rng, BigInt::from_word(2), n);
  162|       |
  163|     43|      if(!passes_miller_rabin_test(n, mod_n, monty_n, a)) {
  ------------------
  |  Branch (163:10): [True: 14, False: 29]
  ------------------
  164|     14|         return false;
  165|     14|      }
  166|     43|   }
  167|       |
  168|       |   // Failed to find a counterexample
  169|      1|   return true;
  170|     15|}
_ZN5Botan28miller_rabin_test_iterationsEmmb:
  172|      1|size_t miller_rabin_test_iterations(size_t n_bits, size_t prob, bool random) {
  173|      1|   const size_t base = (prob + 2) / 2;  // worst case 4^-t error rate
  174|       |
  175|       |   /*
  176|       |   * If the candidate prime was maliciously constructed, we can't rely
  177|       |   * on arguments based on p being random.
  178|       |   */
  179|      1|   if(random == false) {
  ------------------
  |  Branch (179:7): [True: 0, False: 1]
  ------------------
  180|      0|      return base;
  181|      0|   }
  182|       |
  183|       |   /*
  184|       |   * For randomly chosen numbers we can use the estimates from
  185|       |   * http://www.math.dartmouth.edu/~carlp/PDF/paper88.pdf
  186|       |   *
  187|       |   * These values are derived from the inequality for p(k,t) given on
  188|       |   * the second page.
  189|       |   */
  190|      1|   if(prob <= 128) {
  ------------------
  |  Branch (190:7): [True: 1, False: 0]
  ------------------
  191|      1|      if(n_bits >= 1536) {
  ------------------
  |  Branch (191:10): [True: 0, False: 1]
  ------------------
  192|      0|         return 4;  // < 2^-133
  193|      0|      }
  194|      1|      if(n_bits >= 1024) {
  ------------------
  |  Branch (194:10): [True: 0, False: 1]
  ------------------
  195|      0|         return 6;  // < 2^-133
  196|      0|      }
  197|      1|      if(n_bits >= 512) {
  ------------------
  |  Branch (197:10): [True: 0, False: 1]
  ------------------
  198|      0|         return 12;  // < 2^-129
  199|      0|      }
  200|      1|      if(n_bits >= 256) {
  ------------------
  |  Branch (200:10): [True: 1, False: 0]
  ------------------
  201|      1|         return 29;  // < 2^-128
  202|      1|      }
  203|      1|   }
  204|       |
  205|       |   /*
  206|       |   If the user desires a smaller error probability than we have
  207|       |   precomputed error estimates for, just fall back to using the worst
  208|       |   case error rate.
  209|       |   */
  210|      0|   return base;
  211|      1|}

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

_ZN5Botan10ChaCha_RNGC2ENSt3__14spanIKhLm18446744073709551615EEE:
   18|      1|ChaCha_RNG::ChaCha_RNG(std::span<const uint8_t> seed) : Stateful_RNG() {
   19|      1|   m_hmac = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
   20|      1|   m_chacha = StreamCipher::create_or_throw("ChaCha(20)");
   21|      1|   clear();
   22|      1|   add_entropy(seed);
   23|      1|}
_ZN5Botan10ChaCha_RNG11clear_stateEv:
   48|      1|void ChaCha_RNG::clear_state() {
   49|      1|   m_hmac->set_key(std::vector<uint8_t>(m_hmac->output_length(), 0x00));
   50|      1|   m_chacha->set_key(m_hmac->final());
   51|      1|}
_ZN5Botan10ChaCha_RNG15generate_outputENSt3__14spanIhLm18446744073709551615EEENS2_IKhLm18446744073709551615EEE:
   53|     53|void ChaCha_RNG::generate_output(std::span<uint8_t> output, std::span<const uint8_t> input) {
   54|     53|   BOTAN_ASSERT_NOMSG(!output.empty());
  ------------------
  |  |   60|     53|   do {                                                                     \
  |  |   61|     53|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 53]
  |  |  ------------------
  |  |   62|     53|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|     53|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   55|       |
   56|     53|   if(!input.empty()) {
  ------------------
  |  Branch (56:7): [True: 0, False: 53]
  ------------------
   57|      0|      update(input);
   58|      0|   }
   59|       |
   60|     53|   m_chacha->write_keystream(output);
   61|     53|}
_ZN5Botan10ChaCha_RNG6updateENSt3__14spanIKhLm18446744073709551615EEE:
   63|      1|void ChaCha_RNG::update(std::span<const uint8_t> input) {
   64|      1|   m_hmac->update(input);
   65|      1|   m_chacha->set_key(m_hmac->final());
   66|      1|   const auto mac_key = m_chacha->keystream_bytes(m_hmac->output_length());
   67|      1|   m_hmac->set_key(mac_key);
   68|      1|}
_ZNK5Botan10ChaCha_RNG14security_levelEv:
   70|      1|size_t ChaCha_RNG::security_level() const {
   71|      1|   return 256;
   72|      1|}

_ZN5Botan12Stateful_RNG5clearEv:
   14|      1|void Stateful_RNG::clear() {
   15|      1|   lock_guard_type<recursive_mutex_type> lock(m_mutex);
   16|      1|   m_reseed_counter = 0;
   17|      1|   m_last_pid = 0;
   18|      1|   clear_state();
   19|      1|}
_ZNK5Botan12Stateful_RNG9is_seededEv:
   26|     53|bool Stateful_RNG::is_seeded() const {
   27|     53|   lock_guard_type<recursive_mutex_type> lock(m_mutex);
   28|     53|   return m_reseed_counter > 0;
   29|     53|}
_ZN5Botan12Stateful_RNG23generate_batched_outputENSt3__14spanIhLm18446744073709551615EEENS2_IKhLm18446744073709551615EEE:
   38|     53|void Stateful_RNG::generate_batched_output(std::span<uint8_t> output, std::span<const uint8_t> input) {
   39|     53|   BOTAN_ASSERT_NOMSG(!output.empty());
  ------------------
  |  |   60|     53|   do {                                                                     \
  |  |   61|     53|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 53]
  |  |  ------------------
  |  |   62|     53|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|     53|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   40|       |
   41|     53|   const size_t max_per_request = max_number_of_bytes_per_request();
   42|       |
   43|     53|   if(max_per_request == 0)  // no limit
  ------------------
  |  Branch (43:7): [True: 53, False: 0]
  ------------------
   44|     53|   {
   45|     53|      reseed_check();
   46|     53|      this->generate_output(output, input);
   47|     53|   } else {
   48|      0|      while(!output.empty()) {
  ------------------
  |  Branch (48:13): [True: 0, False: 0]
  ------------------
   49|      0|         const size_t this_req = std::min(max_per_request, output.size());
   50|       |
   51|      0|         reseed_check();
   52|      0|         this->generate_output(output.subspan(0, this_req), input);
   53|       |
   54|       |         // only include the input for the first iteration
   55|      0|         input = {};
   56|       |
   57|      0|         output = output.subspan(this_req);
   58|      0|      }
   59|      0|   }
   60|     53|}
_ZN5Botan12Stateful_RNG21fill_bytes_with_inputENSt3__14spanIhLm18446744073709551615EEENS2_IKhLm18446744073709551615EEE:
   62|     54|void Stateful_RNG::fill_bytes_with_input(std::span<uint8_t> output, std::span<const uint8_t> input) {
   63|     54|   lock_guard_type<recursive_mutex_type> lock(m_mutex);
   64|       |
   65|     54|   if(output.empty()) {
  ------------------
  |  Branch (65:7): [True: 1, False: 53]
  ------------------
   66|       |      // Special case for exclusively adding entropy to the stateful RNG.
   67|      1|      this->update(input);
   68|       |
   69|      1|      if(8 * input.size() >= security_level()) {
  ------------------
  |  Branch (69:10): [True: 1, False: 0]
  ------------------
   70|      1|         reset_reseed_counter();
   71|      1|      }
   72|     53|   } else {
   73|     53|      generate_batched_output(output, input);
   74|     53|   }
   75|     54|}
_ZN5Botan12Stateful_RNG20reset_reseed_counterEv:
   99|      1|void Stateful_RNG::reset_reseed_counter() {
  100|       |   // Lock is held whenever this function is called
  101|      1|   m_reseed_counter = 1;
  102|      1|}
_ZN5Botan12Stateful_RNG12reseed_checkEv:
  104|     53|void Stateful_RNG::reseed_check() {
  105|       |   // Lock is held whenever this function is called
  106|       |
  107|     53|   const uint32_t cur_pid = OS::get_process_id();
  108|       |
  109|     53|   const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);
  ------------------
  |  Branch (109:31): [True: 0, False: 53]
  |  Branch (109:51): [True: 0, False: 0]
  ------------------
  110|       |
  111|     53|   if(is_seeded() == false || fork_detected || (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval)) {
  ------------------
  |  Branch (111:7): [True: 0, False: 53]
  |  Branch (111:31): [True: 0, False: 53]
  |  Branch (111:49): [True: 0, False: 53]
  |  Branch (111:74): [True: 0, False: 0]
  ------------------
  112|      0|      m_reseed_counter = 0;
  113|      0|      m_last_pid = cur_pid;
  114|       |
  115|      0|      if(m_underlying_rng) {
  ------------------
  |  Branch (115:10): [True: 0, False: 0]
  ------------------
  116|      0|         reseed_from_rng(*m_underlying_rng, security_level());
  117|      0|      }
  118|       |
  119|      0|      if(m_entropy_sources) {
  ------------------
  |  Branch (119:10): [True: 0, False: 0]
  ------------------
  120|      0|         reseed(*m_entropy_sources, security_level());
  121|      0|      }
  122|       |
  123|      0|      if(!is_seeded()) {
  ------------------
  |  Branch (123:10): [True: 0, False: 0]
  ------------------
  124|      0|         if(fork_detected) {
  ------------------
  |  Branch (124:13): [True: 0, False: 0]
  ------------------
  125|      0|            throw Invalid_State("Detected use of fork but cannot reseed DRBG");
  126|      0|         } else {
  127|      0|            throw PRNG_Unseeded(name());
  128|      0|         }
  129|      0|      }
  130|     53|   } else {
  131|     53|      BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
  ------------------
  |  |   51|     53|   do {                                                                                 \
  |  |   52|     53|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 53]
  |  |  ------------------
  |  |   53|     53|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|     53|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  132|     53|      m_reseed_counter += 1;
  133|     53|   }
  134|     53|}

_ZN5Botan6ChaChaC2Em:
   69|      1|ChaCha::ChaCha(size_t rounds) : m_rounds(rounds) {
   70|      1|   BOTAN_ARG_CHECK(m_rounds == 8 || m_rounds == 12 || m_rounds == 20, "ChaCha only supports 8, 12 or 20 rounds");
  ------------------
  |  |   30|      1|   do {                                                          \
  |  |   31|      4|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:12): [True: 0, False: 1]
  |  |  |  Branch (31:12): [True: 0, False: 1]
  |  |  |  Branch (31:12): [True: 1, False: 0]
  |  |  ------------------
  |  |   32|      1|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|      1|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   71|      1|}
_ZN5Botan6ChaCha11parallelismEv:
   73|      2|size_t ChaCha::parallelism() {
   74|      2|#if defined(BOTAN_HAS_CHACHA_AVX512)
   75|      2|   if(CPUID::has_avx512()) {
  ------------------
  |  Branch (75:7): [True: 0, False: 2]
  ------------------
   76|      0|      return 16;
   77|      0|   }
   78|      2|#endif
   79|       |
   80|      2|#if defined(BOTAN_HAS_CHACHA_AVX2)
   81|      2|   if(CPUID::has_avx2()) {
  ------------------
  |  Branch (81:7): [True: 2, False: 0]
  ------------------
   82|      2|      return 8;
   83|      2|   }
   84|      0|#endif
   85|       |
   86|      0|   return 4;
   87|      2|}
_ZN5Botan6ChaCha6chachaEPhmPjm:
  111|      5|void ChaCha::chacha(uint8_t output[], size_t output_blocks, uint32_t state[16], size_t rounds) {
  112|      5|   BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
  ------------------
  |  |   51|      5|   do {                                                                                 \
  |  |   52|      5|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 5]
  |  |  ------------------
  |  |   53|      5|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|      5|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  113|       |
  114|      5|#if defined(BOTAN_HAS_CHACHA_AVX512)
  115|      5|   if(CPUID::has_avx512()) {
  ------------------
  |  Branch (115:7): [True: 0, False: 5]
  ------------------
  116|      0|      while(output_blocks >= 16) {
  ------------------
  |  Branch (116:13): [True: 0, False: 0]
  ------------------
  117|      0|         ChaCha::chacha_avx512_x16(output, state, rounds);
  118|      0|         output += 16 * 64;
  119|      0|         output_blocks -= 16;
  120|      0|      }
  121|      0|   }
  122|      5|#endif
  123|       |
  124|      5|#if defined(BOTAN_HAS_CHACHA_AVX2)
  125|      5|   if(CPUID::has_avx2()) {
  ------------------
  |  Branch (125:7): [True: 5, False: 0]
  ------------------
  126|     10|      while(output_blocks >= 8) {
  ------------------
  |  Branch (126:13): [True: 5, False: 5]
  ------------------
  127|      5|         ChaCha::chacha_avx2_x8(output, state, rounds);
  128|      5|         output += 8 * 64;
  129|      5|         output_blocks -= 8;
  130|      5|      }
  131|      5|   }
  132|      5|#endif
  133|       |
  134|      5|#if defined(BOTAN_HAS_CHACHA_SIMD32)
  135|      5|   if(CPUID::has_simd_32()) {
  ------------------
  |  Branch (135:7): [True: 5, False: 0]
  ------------------
  136|      5|      while(output_blocks >= 4) {
  ------------------
  |  Branch (136:13): [True: 0, False: 5]
  ------------------
  137|      0|         ChaCha::chacha_simd32_x4(output, state, rounds);
  138|      0|         output += 4 * 64;
  139|      0|         output_blocks -= 4;
  140|      0|      }
  141|      5|   }
  142|      5|#endif
  143|       |
  144|       |   // TODO interleave rounds
  145|      5|   for(size_t i = 0; i != output_blocks; ++i) {
  ------------------
  |  Branch (145:22): [True: 0, False: 5]
  ------------------
  146|      0|      uint32_t x00 = state[0], x01 = state[1], x02 = state[2], x03 = state[3], x04 = state[4], x05 = state[5],
  147|      0|               x06 = state[6], x07 = state[7], x08 = state[8], x09 = state[9], x10 = state[10], x11 = state[11],
  148|      0|               x12 = state[12], x13 = state[13], x14 = state[14], x15 = state[15];
  149|       |
  150|      0|      for(size_t r = 0; r != rounds / 2; ++r) {
  ------------------
  |  Branch (150:25): [True: 0, False: 0]
  ------------------
  151|      0|         chacha_quarter_round(x00, x04, x08, x12);
  152|      0|         chacha_quarter_round(x01, x05, x09, x13);
  153|      0|         chacha_quarter_round(x02, x06, x10, x14);
  154|      0|         chacha_quarter_round(x03, x07, x11, x15);
  155|       |
  156|      0|         chacha_quarter_round(x00, x05, x10, x15);
  157|      0|         chacha_quarter_round(x01, x06, x11, x12);
  158|      0|         chacha_quarter_round(x02, x07, x08, x13);
  159|      0|         chacha_quarter_round(x03, x04, x09, x14);
  160|      0|      }
  161|       |
  162|      0|      x00 += state[0];
  163|      0|      x01 += state[1];
  164|      0|      x02 += state[2];
  165|      0|      x03 += state[3];
  166|      0|      x04 += state[4];
  167|      0|      x05 += state[5];
  168|      0|      x06 += state[6];
  169|      0|      x07 += state[7];
  170|      0|      x08 += state[8];
  171|      0|      x09 += state[9];
  172|      0|      x10 += state[10];
  173|      0|      x11 += state[11];
  174|      0|      x12 += state[12];
  175|      0|      x13 += state[13];
  176|      0|      x14 += state[14];
  177|      0|      x15 += state[15];
  178|       |
  179|      0|      store_le(x00, output + 64 * i + 4 * 0);
  180|      0|      store_le(x01, output + 64 * i + 4 * 1);
  181|      0|      store_le(x02, output + 64 * i + 4 * 2);
  182|      0|      store_le(x03, output + 64 * i + 4 * 3);
  183|      0|      store_le(x04, output + 64 * i + 4 * 4);
  184|      0|      store_le(x05, output + 64 * i + 4 * 5);
  185|      0|      store_le(x06, output + 64 * i + 4 * 6);
  186|      0|      store_le(x07, output + 64 * i + 4 * 7);
  187|      0|      store_le(x08, output + 64 * i + 4 * 8);
  188|      0|      store_le(x09, output + 64 * i + 4 * 9);
  189|      0|      store_le(x10, output + 64 * i + 4 * 10);
  190|      0|      store_le(x11, output + 64 * i + 4 * 11);
  191|      0|      store_le(x12, output + 64 * i + 4 * 12);
  192|      0|      store_le(x13, output + 64 * i + 4 * 13);
  193|      0|      store_le(x14, output + 64 * i + 4 * 14);
  194|      0|      store_le(x15, output + 64 * i + 4 * 15);
  195|       |
  196|      0|      state[12]++;
  197|      0|      state[13] += (state[12] == 0);
  198|      0|   }
  199|      5|}
_ZN5Botan6ChaCha18generate_keystreamEPhm:
  224|     54|void ChaCha::generate_keystream(uint8_t out[], size_t length) {
  225|     54|   assert_key_material_set();
  226|       |
  227|     57|   while(length >= m_buffer.size() - m_position) {
  ------------------
  |  Branch (227:10): [True: 3, False: 54]
  ------------------
  228|      3|      const size_t available = m_buffer.size() - m_position;
  229|       |
  230|       |      // TODO: this could write directly to the output buffer
  231|       |      // instead of bouncing it through m_buffer first
  232|      3|      copy_mem(out, &m_buffer[m_position], available);
  233|      3|      chacha(m_buffer.data(), m_buffer.size() / 64, m_state.data(), m_rounds);
  234|       |
  235|      3|      length -= available;
  236|      3|      out += available;
  237|      3|      m_position = 0;
  238|      3|   }
  239|       |
  240|     54|   copy_mem(out, &m_buffer[m_position], length);
  241|       |
  242|     54|   m_position += length;
  243|     54|}
_ZN5Botan6ChaCha16initialize_stateEv:
  245|      2|void ChaCha::initialize_state() {
  246|      2|   static const uint32_t TAU[] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574};
  247|       |
  248|      2|   static const uint32_t SIGMA[] = {0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};
  249|       |
  250|      2|   m_state[4] = m_key[0];
  251|      2|   m_state[5] = m_key[1];
  252|      2|   m_state[6] = m_key[2];
  253|      2|   m_state[7] = m_key[3];
  254|       |
  255|      2|   if(m_key.size() == 4) {
  ------------------
  |  Branch (255:7): [True: 0, False: 2]
  ------------------
  256|      0|      m_state[0] = TAU[0];
  257|      0|      m_state[1] = TAU[1];
  258|      0|      m_state[2] = TAU[2];
  259|      0|      m_state[3] = TAU[3];
  260|       |
  261|      0|      m_state[8] = m_key[0];
  262|      0|      m_state[9] = m_key[1];
  263|      0|      m_state[10] = m_key[2];
  264|      0|      m_state[11] = m_key[3];
  265|      2|   } else {
  266|      2|      m_state[0] = SIGMA[0];
  267|      2|      m_state[1] = SIGMA[1];
  268|      2|      m_state[2] = SIGMA[2];
  269|      2|      m_state[3] = SIGMA[3];
  270|       |
  271|      2|      m_state[8] = m_key[4];
  272|      2|      m_state[9] = m_key[5];
  273|      2|      m_state[10] = m_key[6];
  274|      2|      m_state[11] = m_key[7];
  275|      2|   }
  276|       |
  277|      2|   m_state[12] = 0;
  278|      2|   m_state[13] = 0;
  279|      2|   m_state[14] = 0;
  280|      2|   m_state[15] = 0;
  281|       |
  282|      2|   m_position = 0;
  283|      2|}
_ZNK5Botan6ChaCha19has_keying_materialEv:
  285|     56|bool ChaCha::has_keying_material() const {
  286|     56|   return !m_state.empty();
  287|     56|}
_ZN5Botan6ChaCha12key_scheduleENSt3__14spanIKhLm18446744073709551615EEE:
  296|      2|void ChaCha::key_schedule(std::span<const uint8_t> key) {
  297|      2|   m_key.resize(key.size() / 4);
  298|      2|   load_le<uint32_t>(m_key.data(), key.data(), m_key.size());
  299|       |
  300|      2|   m_state.resize(16);
  301|       |
  302|      2|   const size_t chacha_block = 64;
  303|      2|   m_buffer.resize(parallelism() * chacha_block);
  304|       |
  305|      2|   set_iv(nullptr, 0);
  306|      2|}
_ZNK5Botan6ChaCha8key_specEv:
  312|      2|Key_Length_Specification ChaCha::key_spec() const {
  313|      2|   return Key_Length_Specification(16, 32, 16);
  314|      2|}
_ZNK5Botan6ChaCha15valid_iv_lengthEm:
  320|      2|bool ChaCha::valid_iv_length(size_t iv_len) const {
  321|      2|   return (iv_len == 0 || iv_len == 8 || iv_len == 12 || iv_len == 24);
  ------------------
  |  Branch (321:12): [True: 2, False: 0]
  |  Branch (321:27): [True: 0, False: 0]
  |  Branch (321:42): [True: 0, False: 0]
  |  Branch (321:58): [True: 0, False: 0]
  ------------------
  322|      2|}
_ZN5Botan6ChaCha12set_iv_bytesEPKhm:
  324|      2|void ChaCha::set_iv_bytes(const uint8_t iv[], size_t length) {
  325|      2|   assert_key_material_set();
  326|       |
  327|      2|   if(!valid_iv_length(length)) {
  ------------------
  |  Branch (327:7): [True: 0, False: 2]
  ------------------
  328|      0|      throw Invalid_IV_Length(name(), length);
  329|      0|   }
  330|       |
  331|      2|   initialize_state();
  332|       |
  333|      2|   if(length == 0) {
  ------------------
  |  Branch (333:7): [True: 2, False: 0]
  ------------------
  334|       |      // Treat zero length IV same as an all-zero IV
  335|      2|      m_state[14] = 0;
  336|      2|      m_state[15] = 0;
  337|      2|   } else if(length == 8) {
  ------------------
  |  Branch (337:14): [True: 0, False: 0]
  ------------------
  338|      0|      m_state[14] = load_le<uint32_t>(iv, 0);
  339|      0|      m_state[15] = load_le<uint32_t>(iv, 1);
  340|      0|   } else if(length == 12) {
  ------------------
  |  Branch (340:14): [True: 0, False: 0]
  ------------------
  341|      0|      m_state[13] = load_le<uint32_t>(iv, 0);
  342|      0|      m_state[14] = load_le<uint32_t>(iv, 1);
  343|      0|      m_state[15] = load_le<uint32_t>(iv, 2);
  344|      0|   } else if(length == 24) {
  ------------------
  |  Branch (344:14): [True: 0, False: 0]
  ------------------
  345|      0|      m_state[12] = load_le<uint32_t>(iv, 0);
  346|      0|      m_state[13] = load_le<uint32_t>(iv, 1);
  347|      0|      m_state[14] = load_le<uint32_t>(iv, 2);
  348|      0|      m_state[15] = load_le<uint32_t>(iv, 3);
  349|       |
  350|      0|      secure_vector<uint32_t> hc(8);
  351|      0|      hchacha(hc.data(), m_state.data(), m_rounds);
  352|       |
  353|      0|      m_state[4] = hc[0];
  354|      0|      m_state[5] = hc[1];
  355|      0|      m_state[6] = hc[2];
  356|      0|      m_state[7] = hc[3];
  357|      0|      m_state[8] = hc[4];
  358|      0|      m_state[9] = hc[5];
  359|      0|      m_state[10] = hc[6];
  360|      0|      m_state[11] = hc[7];
  361|      0|      m_state[12] = 0;
  362|      0|      m_state[13] = 0;
  363|      0|      m_state[14] = load_le<uint32_t>(iv, 4);
  364|      0|      m_state[15] = load_le<uint32_t>(iv, 5);
  365|      0|   }
  366|       |
  367|      2|   chacha(m_buffer.data(), m_buffer.size() / 64, m_state.data(), m_rounds);
  368|      2|   m_position = 0;
  369|      2|}

_ZN5Botan6ChaCha14chacha_avx2_x8EPhPjm:
   15|      5|void ChaCha::chacha_avx2_x8(uint8_t output[64 * 8], uint32_t state[16], size_t rounds) {
   16|      5|   SIMD_8x32::reset_registers();
   17|       |
   18|      5|   BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
  ------------------
  |  |   51|      5|   do {                                                                                 \
  |  |   52|      5|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 5]
  |  |  ------------------
  |  |   53|      5|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|      5|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
   19|      5|   const SIMD_8x32 CTR0 = SIMD_8x32(0, 1, 2, 3, 4, 5, 6, 7);
   20|       |
   21|      5|   const uint32_t C = 0xFFFFFFFF - state[12];
   22|      5|   const SIMD_8x32 CTR1 = SIMD_8x32(0, C < 1, C < 2, C < 3, C < 4, C < 5, C < 6, C < 7);
   23|       |
   24|      5|   SIMD_8x32 R00 = SIMD_8x32::splat(state[0]);
   25|      5|   SIMD_8x32 R01 = SIMD_8x32::splat(state[1]);
   26|      5|   SIMD_8x32 R02 = SIMD_8x32::splat(state[2]);
   27|      5|   SIMD_8x32 R03 = SIMD_8x32::splat(state[3]);
   28|      5|   SIMD_8x32 R04 = SIMD_8x32::splat(state[4]);
   29|      5|   SIMD_8x32 R05 = SIMD_8x32::splat(state[5]);
   30|      5|   SIMD_8x32 R06 = SIMD_8x32::splat(state[6]);
   31|      5|   SIMD_8x32 R07 = SIMD_8x32::splat(state[7]);
   32|      5|   SIMD_8x32 R08 = SIMD_8x32::splat(state[8]);
   33|      5|   SIMD_8x32 R09 = SIMD_8x32::splat(state[9]);
   34|      5|   SIMD_8x32 R10 = SIMD_8x32::splat(state[10]);
   35|      5|   SIMD_8x32 R11 = SIMD_8x32::splat(state[11]);
   36|      5|   SIMD_8x32 R12 = SIMD_8x32::splat(state[12]) + CTR0;
   37|      5|   SIMD_8x32 R13 = SIMD_8x32::splat(state[13]) + CTR1;
   38|      5|   SIMD_8x32 R14 = SIMD_8x32::splat(state[14]);
   39|      5|   SIMD_8x32 R15 = SIMD_8x32::splat(state[15]);
   40|       |
   41|     55|   for(size_t r = 0; r != rounds / 2; ++r) {
  ------------------
  |  Branch (41:22): [True: 50, False: 5]
  ------------------
   42|     50|      R00 += R04;
   43|     50|      R01 += R05;
   44|     50|      R02 += R06;
   45|     50|      R03 += R07;
   46|       |
   47|     50|      R12 ^= R00;
   48|     50|      R13 ^= R01;
   49|     50|      R14 ^= R02;
   50|     50|      R15 ^= R03;
   51|       |
   52|     50|      R12 = R12.rotl<16>();
   53|     50|      R13 = R13.rotl<16>();
   54|     50|      R14 = R14.rotl<16>();
   55|     50|      R15 = R15.rotl<16>();
   56|       |
   57|     50|      R08 += R12;
   58|     50|      R09 += R13;
   59|     50|      R10 += R14;
   60|     50|      R11 += R15;
   61|       |
   62|     50|      R04 ^= R08;
   63|     50|      R05 ^= R09;
   64|     50|      R06 ^= R10;
   65|     50|      R07 ^= R11;
   66|       |
   67|     50|      R04 = R04.rotl<12>();
   68|     50|      R05 = R05.rotl<12>();
   69|     50|      R06 = R06.rotl<12>();
   70|     50|      R07 = R07.rotl<12>();
   71|       |
   72|     50|      R00 += R04;
   73|     50|      R01 += R05;
   74|     50|      R02 += R06;
   75|     50|      R03 += R07;
   76|       |
   77|     50|      R12 ^= R00;
   78|     50|      R13 ^= R01;
   79|     50|      R14 ^= R02;
   80|     50|      R15 ^= R03;
   81|       |
   82|     50|      R12 = R12.rotl<8>();
   83|     50|      R13 = R13.rotl<8>();
   84|     50|      R14 = R14.rotl<8>();
   85|     50|      R15 = R15.rotl<8>();
   86|       |
   87|     50|      R08 += R12;
   88|     50|      R09 += R13;
   89|     50|      R10 += R14;
   90|     50|      R11 += R15;
   91|       |
   92|     50|      R04 ^= R08;
   93|     50|      R05 ^= R09;
   94|     50|      R06 ^= R10;
   95|     50|      R07 ^= R11;
   96|       |
   97|     50|      R04 = R04.rotl<7>();
   98|     50|      R05 = R05.rotl<7>();
   99|     50|      R06 = R06.rotl<7>();
  100|     50|      R07 = R07.rotl<7>();
  101|       |
  102|     50|      R00 += R05;
  103|     50|      R01 += R06;
  104|     50|      R02 += R07;
  105|     50|      R03 += R04;
  106|       |
  107|     50|      R15 ^= R00;
  108|     50|      R12 ^= R01;
  109|     50|      R13 ^= R02;
  110|     50|      R14 ^= R03;
  111|       |
  112|     50|      R15 = R15.rotl<16>();
  113|     50|      R12 = R12.rotl<16>();
  114|     50|      R13 = R13.rotl<16>();
  115|     50|      R14 = R14.rotl<16>();
  116|       |
  117|     50|      R10 += R15;
  118|     50|      R11 += R12;
  119|     50|      R08 += R13;
  120|     50|      R09 += R14;
  121|       |
  122|     50|      R05 ^= R10;
  123|     50|      R06 ^= R11;
  124|     50|      R07 ^= R08;
  125|     50|      R04 ^= R09;
  126|       |
  127|     50|      R05 = R05.rotl<12>();
  128|     50|      R06 = R06.rotl<12>();
  129|     50|      R07 = R07.rotl<12>();
  130|     50|      R04 = R04.rotl<12>();
  131|       |
  132|     50|      R00 += R05;
  133|     50|      R01 += R06;
  134|     50|      R02 += R07;
  135|     50|      R03 += R04;
  136|       |
  137|     50|      R15 ^= R00;
  138|     50|      R12 ^= R01;
  139|     50|      R13 ^= R02;
  140|     50|      R14 ^= R03;
  141|       |
  142|     50|      R15 = R15.rotl<8>();
  143|     50|      R12 = R12.rotl<8>();
  144|     50|      R13 = R13.rotl<8>();
  145|     50|      R14 = R14.rotl<8>();
  146|       |
  147|     50|      R10 += R15;
  148|     50|      R11 += R12;
  149|     50|      R08 += R13;
  150|     50|      R09 += R14;
  151|       |
  152|     50|      R05 ^= R10;
  153|     50|      R06 ^= R11;
  154|     50|      R07 ^= R08;
  155|     50|      R04 ^= R09;
  156|       |
  157|     50|      R05 = R05.rotl<7>();
  158|     50|      R06 = R06.rotl<7>();
  159|     50|      R07 = R07.rotl<7>();
  160|     50|      R04 = R04.rotl<7>();
  161|     50|   }
  162|       |
  163|      5|   R00 += SIMD_8x32::splat(state[0]);
  164|      5|   R01 += SIMD_8x32::splat(state[1]);
  165|      5|   R02 += SIMD_8x32::splat(state[2]);
  166|      5|   R03 += SIMD_8x32::splat(state[3]);
  167|      5|   R04 += SIMD_8x32::splat(state[4]);
  168|      5|   R05 += SIMD_8x32::splat(state[5]);
  169|      5|   R06 += SIMD_8x32::splat(state[6]);
  170|      5|   R07 += SIMD_8x32::splat(state[7]);
  171|      5|   R08 += SIMD_8x32::splat(state[8]);
  172|      5|   R09 += SIMD_8x32::splat(state[9]);
  173|      5|   R10 += SIMD_8x32::splat(state[10]);
  174|      5|   R11 += SIMD_8x32::splat(state[11]);
  175|      5|   R12 += SIMD_8x32::splat(state[12]) + CTR0;
  176|      5|   R13 += SIMD_8x32::splat(state[13]) + CTR1;
  177|      5|   R14 += SIMD_8x32::splat(state[14]);
  178|      5|   R15 += SIMD_8x32::splat(state[15]);
  179|       |
  180|      5|   SIMD_8x32::transpose(R00, R01, R02, R03, R04, R05, R06, R07);
  181|      5|   SIMD_8x32::transpose(R08, R09, R10, R11, R12, R13, R14, R15);
  182|       |
  183|      5|   R00.store_le(output);
  184|      5|   R08.store_le(output + 32 * 1);
  185|      5|   R01.store_le(output + 32 * 2);
  186|      5|   R09.store_le(output + 32 * 3);
  187|      5|   R02.store_le(output + 32 * 4);
  188|      5|   R10.store_le(output + 32 * 5);
  189|      5|   R03.store_le(output + 32 * 6);
  190|      5|   R11.store_le(output + 32 * 7);
  191|      5|   R04.store_le(output + 32 * 8);
  192|      5|   R12.store_le(output + 32 * 9);
  193|      5|   R05.store_le(output + 32 * 10);
  194|      5|   R13.store_le(output + 32 * 11);
  195|      5|   R06.store_le(output + 32 * 12);
  196|      5|   R14.store_le(output + 32 * 13);
  197|      5|   R07.store_le(output + 32 * 14);
  198|      5|   R15.store_le(output + 32 * 15);
  199|       |
  200|      5|   SIMD_8x32::zero_registers();
  201|       |
  202|      5|   state[12] += 8;
  203|      5|   if(state[12] < 8) {
  ------------------
  |  Branch (203:7): [True: 0, False: 5]
  ------------------
  204|      0|      state[13]++;
  205|      0|   }
  206|      5|}

_ZN5Botan12StreamCipher6createENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_:
   40|      1|std::unique_ptr<StreamCipher> StreamCipher::create(std::string_view algo_spec, std::string_view provider) {
   41|      1|#if defined(BOTAN_HAS_SHAKE_CIPHER)
   42|      1|   if(algo_spec == "SHAKE-128" || algo_spec == "SHAKE-128-XOF") {
  ------------------
  |  Branch (42:7): [True: 0, False: 1]
  |  Branch (42:35): [True: 0, False: 1]
  ------------------
   43|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (43:10): [True: 0, False: 0]
  |  Branch (43:30): [True: 0, False: 0]
  ------------------
   44|      0|         return std::make_unique<SHAKE_128_Cipher>();
   45|      0|      }
   46|      0|   }
   47|       |
   48|      1|   if(algo_spec == "SHAKE-256" || algo_spec == "SHAKE-256-XOF") {
  ------------------
  |  Branch (48:7): [True: 0, False: 1]
  |  Branch (48:35): [True: 0, False: 1]
  ------------------
   49|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (49:10): [True: 0, False: 0]
  |  Branch (49:30): [True: 0, False: 0]
  ------------------
   50|      0|         return std::make_unique<SHAKE_256_Cipher>();
   51|      0|      }
   52|      0|   }
   53|      1|#endif
   54|       |
   55|      1|#if defined(BOTAN_HAS_CHACHA)
   56|      1|   if(algo_spec == "ChaCha20") {
  ------------------
  |  Branch (56:7): [True: 0, False: 1]
  ------------------
   57|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (57:10): [True: 0, False: 0]
  |  Branch (57:30): [True: 0, False: 0]
  ------------------
   58|      0|         return std::make_unique<ChaCha>(20);
   59|      0|      }
   60|      0|   }
   61|      1|#endif
   62|       |
   63|      1|#if defined(BOTAN_HAS_SALSA20)
   64|      1|   if(algo_spec == "Salsa20") {
  ------------------
  |  Branch (64:7): [True: 0, False: 1]
  ------------------
   65|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (65:10): [True: 0, False: 0]
  |  Branch (65:30): [True: 0, False: 0]
  ------------------
   66|      0|         return std::make_unique<Salsa20>();
   67|      0|      }
   68|      0|   }
   69|      1|#endif
   70|       |
   71|      1|   const SCAN_Name req(algo_spec);
   72|       |
   73|      1|#if defined(BOTAN_HAS_CTR_BE)
   74|      1|   if((req.algo_name() == "CTR-BE" || req.algo_name() == "CTR") && req.arg_count_between(1, 2)) {
  ------------------
  |  Branch (74:8): [True: 0, False: 1]
  |  Branch (74:39): [True: 0, False: 1]
  |  Branch (74:68): [True: 0, False: 0]
  ------------------
   75|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (75:10): [True: 0, False: 0]
  |  Branch (75:30): [True: 0, False: 0]
  ------------------
   76|      0|         auto cipher = BlockCipher::create(req.arg(0));
   77|      0|         if(cipher) {
  ------------------
  |  Branch (77:13): [True: 0, False: 0]
  ------------------
   78|      0|            size_t ctr_size = req.arg_as_integer(1, cipher->block_size());
   79|      0|            return std::make_unique<CTR_BE>(std::move(cipher), ctr_size);
   80|      0|         }
   81|      0|      }
   82|      0|   }
   83|      1|#endif
   84|       |
   85|      1|#if defined(BOTAN_HAS_CHACHA)
   86|      1|   if(req.algo_name() == "ChaCha") {
  ------------------
  |  Branch (86:7): [True: 1, False: 0]
  ------------------
   87|      1|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (87:10): [True: 1, False: 0]
  |  Branch (87:30): [True: 0, False: 0]
  ------------------
   88|      1|         return std::make_unique<ChaCha>(req.arg_as_integer(0, 20));
   89|      1|      }
   90|      1|   }
   91|      0|#endif
   92|       |
   93|      0|#if defined(BOTAN_HAS_OFB)
   94|      0|   if(req.algo_name() == "OFB" && req.arg_count() == 1) {
  ------------------
  |  Branch (94:7): [True: 0, False: 0]
  |  Branch (94:35): [True: 0, False: 0]
  ------------------
   95|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (95:10): [True: 0, False: 0]
  |  Branch (95:30): [True: 0, False: 0]
  ------------------
   96|      0|         if(auto cipher = BlockCipher::create(req.arg(0))) {
  ------------------
  |  Branch (96:18): [True: 0, False: 0]
  ------------------
   97|      0|            return std::make_unique<OFB>(std::move(cipher));
   98|      0|         }
   99|      0|      }
  100|      0|   }
  101|      0|#endif
  102|       |
  103|      0|#if defined(BOTAN_HAS_RC4)
  104|       |
  105|      0|   if(req.algo_name() == "RC4" || req.algo_name() == "ARC4" || req.algo_name() == "MARK-4") {
  ------------------
  |  Branch (105:7): [True: 0, False: 0]
  |  Branch (105:35): [True: 0, False: 0]
  |  Branch (105:64): [True: 0, False: 0]
  ------------------
  106|      0|      const size_t skip = (req.algo_name() == "MARK-4") ? 256 : req.arg_as_integer(0, 0);
  ------------------
  |  Branch (106:27): [True: 0, False: 0]
  ------------------
  107|       |
  108|      0|      if(provider.empty() || provider == "base") {
  ------------------
  |  Branch (108:10): [True: 0, False: 0]
  |  Branch (108:30): [True: 0, False: 0]
  ------------------
  109|      0|         return std::make_unique<RC4>(skip);
  110|      0|      }
  111|      0|   }
  112|       |
  113|      0|#endif
  114|       |
  115|      0|   BOTAN_UNUSED(req);
  ------------------
  |  |  118|      0|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
  116|      0|   BOTAN_UNUSED(provider);
  ------------------
  |  |  118|      0|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
  117|       |
  118|      0|   return nullptr;
  119|      0|}
_ZN5Botan12StreamCipher15create_or_throwENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEES5_:
  122|      1|std::unique_ptr<StreamCipher> StreamCipher::create_or_throw(std::string_view algo, std::string_view provider) {
  123|      1|   if(auto sc = StreamCipher::create(algo, provider)) {
  ------------------
  |  Branch (123:12): [True: 1, False: 0]
  ------------------
  124|      1|      return sc;
  125|      1|   }
  126|      0|   throw Lookup_Error("Stream cipher", algo, provider);
  127|      1|}

_ZN5Botan15allocate_memoryEmm:
   20|   220k|BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t elem_size) {
   21|   220k|   if(elems == 0 || elem_size == 0) {
  ------------------
  |  Branch (21:7): [True: 0, False: 220k]
  |  Branch (21:21): [True: 0, False: 220k]
  ------------------
   22|      0|      return nullptr;
   23|      0|   }
   24|       |
   25|       |   // Some calloc implementations do not check for overflow (?!?)
   26|       |
   27|   220k|   if(!BOTAN_CHECKED_MUL(elems, elem_size).has_value()) {
  ------------------
  |  |   74|   220k|#define BOTAN_CHECKED_MUL(x, y) checked_mul(x, y)
  ------------------
  |  Branch (27:7): [True: 0, False: 220k]
  ------------------
   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|   220k|   void* ptr = std::calloc(elems, elem_size);  // NOLINT(*-no-malloc)
   41|   220k|#endif
   42|   220k|   if(!ptr) {
  ------------------
  |  Branch (42:7): [True: 0, False: 220k]
  ------------------
   43|      0|      [[unlikely]] throw std::bad_alloc();
   44|      0|   }
   45|   220k|   return ptr;
   46|   220k|}
_ZN5Botan17deallocate_memoryEPvmm:
   48|   220k|void deallocate_memory(void* p, size_t elems, size_t elem_size) {
   49|   220k|   if(p == nullptr) {
  ------------------
  |  Branch (49:7): [True: 0, False: 220k]
  ------------------
   50|      0|      [[unlikely]] return;
   51|      0|   }
   52|       |
   53|   220k|   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|   220k|   std::free(p);  // NOLINT(*-no-malloc)
   62|   220k|}

_ZN5Botan22throw_invalid_argumentEPKcS1_S1_:
   21|      1|void throw_invalid_argument(const char* message, const char* func, const char* file) {
   22|      1|   throw Invalid_Argument(fmt("{} in {}:{}", message, func, file));
   23|      1|}

_ZN5Botan5CPUID11has_simd_32Ev:
   18|      5|bool CPUID::has_simd_32() {
   19|      5|#if defined(BOTAN_TARGET_SUPPORTS_SSE2)
   20|      5|   return CPUID::has_sse2();
   21|       |#elif defined(BOTAN_TARGET_SUPPORTS_ALTIVEC)
   22|       |   return CPUID::has_altivec();
   23|       |#elif defined(BOTAN_TARGET_SUPPORTS_NEON)
   24|       |   return CPUID::has_neon();
   25|       |#else
   26|       |   return true;
   27|       |#endif
   28|      5|}
_ZN5Botan5CPUID10CPUID_DataC2Ev:
  122|      1|CPUID::CPUID_Data::CPUID_Data() {
  123|      1|   m_processor_features = 0;
  124|       |
  125|      1|#if defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) || defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) || \
  126|      1|   defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
  127|       |
  128|      1|   m_processor_features = detect_cpu_features();
  129|       |
  130|      1|#endif
  131|       |
  132|      1|   m_processor_features |= CPUID::CPUID_INITIALIZED_BIT;
  133|       |
  134|      1|   if(runtime_check_if_big_endian()) {
  ------------------
  |  Branch (134:7): [True: 0, False: 1]
  ------------------
  135|      0|      m_processor_features |= CPUID::CPUID_IS_BIG_ENDIAN_BIT;
  136|      0|   }
  137|       |
  138|      1|   std::string clear_cpuid_env;
  139|      1|   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID")) {
  ------------------
  |  Branch (139:7): [True: 0, False: 1]
  ------------------
  140|      0|      for(const auto& cpuid : split_on(clear_cpuid_env, ',')) {
  ------------------
  |  Branch (140:29): [True: 0, False: 0]
  ------------------
  141|      0|         for(auto& bit : CPUID::bit_from_string(cpuid)) {
  ------------------
  |  Branch (141:24): [True: 0, False: 0]
  ------------------
  142|      0|            const uint32_t cleared = ~static_cast<uint32_t>(bit);
  143|      0|            m_processor_features &= cleared;
  144|      0|         }
  145|      0|      }
  146|      0|   }
  147|      1|}
cpuid.cpp:_ZN5Botan12_GLOBAL__N_127runtime_check_if_big_endianEv:
   95|      1|bool runtime_check_if_big_endian() {
   96|       |   // Check runtime endian
   97|      1|   const uint32_t endian32 = 0x01234567;
   98|      1|   const uint8_t* e8 = reinterpret_cast<const uint8_t*>(&endian32);
   99|       |
  100|      1|   bool is_big_endian = false;
  101|       |
  102|      1|   if(e8[0] == 0x01 && e8[1] == 0x23 && e8[2] == 0x45 && e8[3] == 0x67) {
  ------------------
  |  Branch (102:7): [True: 0, False: 1]
  |  Branch (102:24): [True: 0, False: 0]
  |  Branch (102:41): [True: 0, False: 0]
  |  Branch (102:58): [True: 0, False: 0]
  ------------------
  103|      0|      is_big_endian = true;
  104|      1|   } else if(e8[0] == 0x67 && e8[1] == 0x45 && e8[2] == 0x23 && e8[3] == 0x01) {
  ------------------
  |  Branch (104:14): [True: 1, False: 0]
  |  Branch (104:31): [True: 1, False: 0]
  |  Branch (104:48): [True: 1, False: 0]
  |  Branch (104:65): [True: 1, False: 0]
  ------------------
  105|      1|      is_big_endian = false;
  106|      1|   } else {
  107|      0|      throw Internal_Error("Unexpected endian at runtime, neither big nor little");
  108|      0|   }
  109|       |
  110|       |   // If we were compiled with a known endian, verify it matches at runtime
  111|      1|#if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN)
  112|      1|   BOTAN_ASSERT(!is_big_endian, "Build and runtime endian match");
  ------------------
  |  |   51|      1|   do {                                                                                 \
  |  |   52|      1|      if(!(expr))                                                                       \
  |  |  ------------------
  |  |  |  Branch (52:10): [True: 0, False: 1]
  |  |  ------------------
  |  |   53|      1|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   54|      1|   } while(0)
  |  |  ------------------
  |  |  |  Branch (54:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  113|       |#elif defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN)
  114|       |   BOTAN_ASSERT(is_big_endian, "Build and runtime endian match");
  115|       |#endif
  116|       |
  117|      1|   return is_big_endian;
  118|      1|}

_ZN5Botan5CPUID10CPUID_Data19detect_cpu_featuresEv:
   71|      1|uint32_t CPUID::CPUID_Data::detect_cpu_features() {
   72|      1|   uint32_t features_detected = 0;
   73|      1|   uint32_t cpuid[4] = {0};
   74|      1|   bool has_os_ymm_support = false;
   75|      1|   bool has_os_zmm_support = false;
   76|       |
   77|       |   // CPUID 0: vendor identification, max sublevel
   78|      1|   invoke_cpuid(0, cpuid);
   79|       |
   80|      1|   const uint32_t max_supported_sublevel = cpuid[0];
   81|       |
   82|      1|   if(max_supported_sublevel >= 1) {
  ------------------
  |  Branch (82:7): [True: 1, False: 0]
  ------------------
   83|       |      // CPUID 1: feature bits
   84|      1|      invoke_cpuid(1, cpuid);
   85|      1|      const uint64_t flags0 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[3];
   86|       |
   87|      1|      enum x86_CPUID_1_bits : uint64_t {
   88|      1|         RDTSC = (1ULL << 4),
   89|      1|         SSE2 = (1ULL << 26),
   90|      1|         CLMUL = (1ULL << 33),
   91|      1|         SSSE3 = (1ULL << 41),
   92|      1|         AESNI = (1ULL << 57),
   93|      1|         OSXSAVE = (1ULL << 59),
   94|      1|         AVX = (1ULL << 60),
   95|      1|         RDRAND = (1ULL << 62)
   96|      1|      };
   97|       |
   98|      1|      if(flags0 & x86_CPUID_1_bits::RDTSC) {
  ------------------
  |  Branch (98:10): [True: 1, False: 0]
  ------------------
   99|      1|         features_detected |= CPUID::CPUID_RDTSC_BIT;
  100|      1|      }
  101|      1|      if(flags0 & x86_CPUID_1_bits::SSE2) {
  ------------------
  |  Branch (101:10): [True: 1, False: 0]
  ------------------
  102|      1|         features_detected |= CPUID::CPUID_SSE2_BIT;
  103|      1|      }
  104|      1|      if(flags0 & x86_CPUID_1_bits::CLMUL) {
  ------------------
  |  Branch (104:10): [True: 1, False: 0]
  ------------------
  105|      1|         features_detected |= CPUID::CPUID_CLMUL_BIT;
  106|      1|      }
  107|      1|      if(flags0 & x86_CPUID_1_bits::SSSE3) {
  ------------------
  |  Branch (107:10): [True: 1, False: 0]
  ------------------
  108|      1|         features_detected |= CPUID::CPUID_SSSE3_BIT;
  109|      1|      }
  110|      1|      if(flags0 & x86_CPUID_1_bits::AESNI) {
  ------------------
  |  Branch (110:10): [True: 1, False: 0]
  ------------------
  111|      1|         features_detected |= CPUID::CPUID_AESNI_BIT;
  112|      1|      }
  113|      1|      if(flags0 & x86_CPUID_1_bits::RDRAND) {
  ------------------
  |  Branch (113:10): [True: 1, False: 0]
  ------------------
  114|      1|         features_detected |= CPUID::CPUID_RDRAND_BIT;
  115|      1|      }
  116|       |
  117|      1|      if((flags0 & x86_CPUID_1_bits::AVX) && (flags0 & x86_CPUID_1_bits::OSXSAVE)) {
  ------------------
  |  Branch (117:10): [True: 1, False: 0]
  |  Branch (117:46): [True: 1, False: 0]
  ------------------
  118|      1|         const uint64_t xcr_flags = xgetbv();
  119|      1|         if((xcr_flags & 0x6) == 0x6) {
  ------------------
  |  Branch (119:13): [True: 1, False: 0]
  ------------------
  120|      1|            has_os_ymm_support = true;
  121|      1|            has_os_zmm_support = (xcr_flags & 0xE0) == 0xE0;
  122|      1|         }
  123|      1|      }
  124|      1|   }
  125|       |
  126|      1|   if(max_supported_sublevel >= 7) {
  ------------------
  |  Branch (126:7): [True: 1, False: 0]
  ------------------
  127|      1|      clear_mem(cpuid, 4);
  128|      1|      invoke_cpuid_sublevel(7, 0, cpuid);
  129|       |
  130|      1|      enum x86_CPUID_7_bits : uint64_t {
  131|      1|         BMI1 = (1ULL << 3),
  132|      1|         AVX2 = (1ULL << 5),
  133|      1|         BMI2 = (1ULL << 8),
  134|      1|         AVX512_F = (1ULL << 16),
  135|      1|         AVX512_DQ = (1ULL << 17),
  136|      1|         RDSEED = (1ULL << 18),
  137|      1|         ADX = (1ULL << 19),
  138|      1|         AVX512_IFMA = (1ULL << 21),
  139|      1|         SHA = (1ULL << 29),
  140|      1|         AVX512_BW = (1ULL << 30),
  141|      1|         AVX512_VL = (1ULL << 31),
  142|      1|         AVX512_VBMI = (1ULL << 33),
  143|      1|         AVX512_VBMI2 = (1ULL << 38),
  144|      1|         AVX512_VAES = (1ULL << 41),
  145|      1|         AVX512_VCLMUL = (1ULL << 42),
  146|      1|         AVX512_VBITALG = (1ULL << 44),
  147|      1|      };
  148|       |
  149|      1|      const uint64_t flags7 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[1];
  150|       |
  151|      1|      if((flags7 & x86_CPUID_7_bits::AVX2) && has_os_ymm_support) {
  ------------------
  |  Branch (151:10): [True: 1, False: 0]
  |  Branch (151:47): [True: 1, False: 0]
  ------------------
  152|      1|         features_detected |= CPUID::CPUID_AVX2_BIT;
  153|      1|      }
  154|      1|      if(flags7 & x86_CPUID_7_bits::RDSEED) {
  ------------------
  |  Branch (154:10): [True: 1, False: 0]
  ------------------
  155|      1|         features_detected |= CPUID::CPUID_RDSEED_BIT;
  156|      1|      }
  157|      1|      if(flags7 & x86_CPUID_7_bits::ADX) {
  ------------------
  |  Branch (157:10): [True: 1, False: 0]
  ------------------
  158|      1|         features_detected |= CPUID::CPUID_ADX_BIT;
  159|      1|      }
  160|      1|      if(flags7 & x86_CPUID_7_bits::SHA) {
  ------------------
  |  Branch (160:10): [True: 0, False: 1]
  ------------------
  161|      0|         features_detected |= CPUID::CPUID_SHA_BIT;
  162|      0|      }
  163|       |
  164|       |      /*
  165|       |      We only set the BMI bit if both BMI1 and BMI2 are supported, since
  166|       |      typically we want to use both extensions in the same code.
  167|       |      */
  168|      1|      if((flags7 & x86_CPUID_7_bits::BMI1) && (flags7 & x86_CPUID_7_bits::BMI2)) {
  ------------------
  |  Branch (168:10): [True: 1, False: 0]
  |  Branch (168:47): [True: 1, False: 0]
  ------------------
  169|      1|         features_detected |= CPUID::CPUID_BMI_BIT;
  170|      1|      }
  171|       |
  172|      1|      if((flags7 & x86_CPUID_7_bits::AVX512_F) && has_os_zmm_support) {
  ------------------
  |  Branch (172:10): [True: 0, False: 1]
  |  Branch (172:51): [True: 0, False: 0]
  ------------------
  173|      0|         const uint64_t AVX512_PROFILE_FLAGS = x86_CPUID_7_bits::AVX512_F | x86_CPUID_7_bits::AVX512_DQ |
  174|      0|                                               x86_CPUID_7_bits::AVX512_IFMA | x86_CPUID_7_bits::AVX512_BW |
  175|      0|                                               x86_CPUID_7_bits::AVX512_VL | x86_CPUID_7_bits::AVX512_VBMI |
  176|      0|                                               x86_CPUID_7_bits::AVX512_VBMI2 | x86_CPUID_7_bits::AVX512_VBITALG;
  177|       |
  178|       |         /*
  179|       |         We only enable AVX512 support if all of the above flags are available
  180|       |
  181|       |         This is more than we strictly need for most uses, however it also has
  182|       |         the effect of preventing execution of AVX512 codepaths on cores that
  183|       |         have serious downclocking problems when AVX512 code executes,
  184|       |         especially Intel Skylake.
  185|       |
  186|       |         VBMI2/VBITALG are the key flags here as they restrict us to Intel Ice
  187|       |         Lake/Rocket Lake, or AMD Zen4, all of which do not have penalties for
  188|       |         executing AVX512.
  189|       |
  190|       |         There is nothing stopping some future processor from supporting the
  191|       |         above flags and having AVX512 penalties, but maybe you should not have
  192|       |         bought such a processor.
  193|       |         */
  194|      0|         if((flags7 & AVX512_PROFILE_FLAGS) == AVX512_PROFILE_FLAGS) {
  ------------------
  |  Branch (194:13): [True: 0, False: 0]
  ------------------
  195|      0|            features_detected |= CPUID::CPUID_AVX512_BIT;
  196|       |
  197|      0|            if(flags7 & x86_CPUID_7_bits::AVX512_VAES) {
  ------------------
  |  Branch (197:16): [True: 0, False: 0]
  ------------------
  198|      0|               features_detected |= CPUID::CPUID_AVX512_AES_BIT;
  199|      0|            }
  200|      0|            if(flags7 & x86_CPUID_7_bits::AVX512_VCLMUL) {
  ------------------
  |  Branch (200:16): [True: 0, False: 0]
  ------------------
  201|      0|               features_detected |= CPUID::CPUID_AVX512_CLMUL_BIT;
  202|      0|            }
  203|      0|         }
  204|      0|      }
  205|      1|   }
  206|       |
  207|       |   /*
  208|       |   * If we don't have access to CPUID, we can still safely assume that
  209|       |   * any x86-64 processor has SSE2 and RDTSC
  210|       |   */
  211|      1|   #if defined(BOTAN_TARGET_ARCH_IS_X86_64)
  212|      1|   if(features_detected == 0) {
  ------------------
  |  Branch (212:7): [True: 0, False: 1]
  ------------------
  213|      0|      features_detected |= CPUID::CPUID_SSE2_BIT;
  214|      0|      features_detected |= CPUID::CPUID_RDTSC_BIT;
  215|      0|   }
  216|      1|   #endif
  217|       |
  218|      1|   return features_detected;
  219|      1|}
cpuid_x86.cpp:_ZN5Botan12_GLOBAL__N_112invoke_cpuidEjPj:
   33|      2|void invoke_cpuid(uint32_t type, uint32_t out[4]) {
   34|       |   #if defined(BOTAN_BUILD_COMPILER_IS_MSVC) || defined(BOTAN_BUILD_COMPILER_IS_INTEL)
   35|       |   __cpuid((int*)out, type);
   36|       |
   37|       |   #elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG)
   38|      2|   __get_cpuid(type, out, out + 1, out + 2, out + 3);
   39|       |
   40|       |   #elif defined(BOTAN_USE_GCC_INLINE_ASM)
   41|       |   asm("cpuid\n\t" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "0"(type));
   42|       |
   43|       |   #else
   44|       |      #warning "No way of calling x86 cpuid instruction for this compiler"
   45|       |   clear_mem(out, 4);
   46|       |   #endif
   47|      2|}
cpuid_x86.cpp:_ZN5Botan12_GLOBAL__N_16xgetbvEv:
   49|      1|BOTAN_FUNC_ISA("xsave") uint64_t xgetbv() {
   50|      1|   return _xgetbv(0);
   51|      1|}
cpuid_x86.cpp:_ZN5Botan12_GLOBAL__N_121invoke_cpuid_sublevelEjjPj:
   53|      1|void invoke_cpuid_sublevel(uint32_t type, uint32_t level, uint32_t out[4]) {
   54|       |   #if defined(BOTAN_BUILD_COMPILER_IS_MSVC)
   55|       |   __cpuidex((int*)out, type, level);
   56|       |
   57|       |   #elif defined(BOTAN_BUILD_COMPILER_IS_GCC) || defined(BOTAN_BUILD_COMPILER_IS_CLANG)
   58|      1|   __cpuid_count(type, level, out[0], out[1], out[2], out[3]);
   59|       |
   60|       |   #elif defined(BOTAN_USE_GCC_INLINE_ASM)
   61|       |   asm("cpuid\n\t" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "0"(type), "2"(level));
   62|       |
   63|       |   #else
   64|       |      #warning "No way of calling x86 cpuid instruction for this compiler"
   65|       |   clear_mem(out, 4);
   66|       |   #endif
   67|      1|}

_ZN5Botan9ExceptionC2ENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
   71|      1|Exception::Exception(std::string_view msg) : m_msg(msg) {}
_ZN5Botan16Invalid_ArgumentC2ENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
   77|      1|Invalid_Argument::Invalid_Argument(std::string_view msg) : Exception(msg) {}

_ZN5Botan19secure_scrub_memoryEPvm:
   87|   220k|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|   220k|   ::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|   220k|}
_ZN5Botan2OS14get_process_idEv:
  116|     53|uint32_t OS::get_process_id() {
  117|     53|#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
  118|     53|   return ::getpid();
  119|       |#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
  120|       |   return ::GetCurrentProcessId();
  121|       |#elif defined(BOTAN_TARGET_OS_IS_LLVM) || defined(BOTAN_TARGET_OS_IS_NONE)
  122|       |   return 0;  // truly no meaningful value
  123|       |#else
  124|       |   #error "Missing get_process_id"
  125|       |#endif
  126|     53|}
_ZN5Botan2OS10get_auxvalEm:
  128|      1|unsigned long OS::get_auxval(unsigned long id) {
  129|      1|#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL)
  130|      1|   return ::getauxval(id);
  131|       |#elif defined(BOTAN_TARGET_OS_IS_ANDROID) && defined(BOTAN_TARGET_ARCH_IS_ARM32)
  132|       |
  133|       |   if(id == 0)
  134|       |      return 0;
  135|       |
  136|       |   char** p = environ;
  137|       |
  138|       |   while(*p++ != nullptr)
  139|       |      ;
  140|       |
  141|       |   Elf32_auxv_t* e = reinterpret_cast<Elf32_auxv_t*>(p);
  142|       |
  143|       |   while(e != nullptr) {
  144|       |      if(e->a_type == id)
  145|       |         return e->a_un.a_val;
  146|       |      e++;
  147|       |   }
  148|       |
  149|       |   return 0;
  150|       |#elif defined(BOTAN_TARGET_OS_HAS_ELF_AUX_INFO)
  151|       |   unsigned long auxinfo = 0;
  152|       |   ::elf_aux_info(static_cast<int>(id), &auxinfo, sizeof(auxinfo));
  153|       |   return auxinfo;
  154|       |#elif defined(BOTAN_TARGET_OS_HAS_AUXINFO)
  155|       |   for(const AuxInfo* auxinfo = static_cast<AuxInfo*>(::_dlauxinfo()); auxinfo != AT_NULL; ++auxinfo) {
  156|       |      if(id == auxinfo->a_type)
  157|       |         return auxinfo->a_v;
  158|       |   }
  159|       |
  160|       |   return 0;
  161|       |#else
  162|       |   BOTAN_UNUSED(id);
  163|       |   return 0;
  164|       |#endif
  165|      1|}
_ZN5Botan2OS27running_in_privileged_stateEv:
  167|      1|bool OS::running_in_privileged_state() {
  168|      1|#if defined(AT_SECURE)
  169|      1|   return OS::get_auxval(AT_SECURE) != 0;
  170|       |#elif defined(BOTAN_TARGET_OS_HAS_POSIX1)
  171|       |   return (::getuid() != ::geteuid()) || (::getgid() != ::getegid());
  172|       |#else
  173|       |   return false;
  174|       |#endif
  175|      1|}
_ZN5Botan2OS17read_env_variableERNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_17basic_string_viewIcS4_EE:
  409|      1|bool OS::read_env_variable(std::string& value_out, std::string_view name_view) {
  410|      1|   value_out = "";
  411|       |
  412|      1|   if(running_in_privileged_state()) {
  ------------------
  |  Branch (412:7): [True: 0, False: 1]
  ------------------
  413|      0|      return false;
  414|      0|   }
  415|       |
  416|       |#if defined(BOTAN_TARGET_OS_HAS_WIN32) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
  417|       |   const std::string name(name_view);
  418|       |   char val[128] = {0};
  419|       |   size_t req_size = 0;
  420|       |   if(getenv_s(&req_size, val, sizeof(val), name.c_str()) == 0) {
  421|       |      // Microsoft's implementation always writes a terminating \0,
  422|       |      // and includes it in the reported length of the environment variable
  423|       |      // if a value exists.
  424|       |      if(req_size > 0 && val[req_size - 1] == '\0') {
  425|       |         value_out = std::string(val);
  426|       |      } else {
  427|       |         value_out = std::string(val, req_size);
  428|       |      }
  429|       |      return true;
  430|       |   }
  431|       |#else
  432|      1|   const std::string name(name_view);
  433|      1|   if(const char* val = std::getenv(name.c_str())) {
  ------------------
  |  Branch (433:19): [True: 0, False: 1]
  ------------------
  434|      0|      value_out = val;
  435|      0|      return true;
  436|      0|   }
  437|      1|#endif
  438|       |
  439|      1|   return false;
  440|      1|}

_ZN5Botan9to_u32bitENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEE:
   32|      1|uint32_t to_u32bit(std::string_view str_view) {
   33|      1|   const std::string str(str_view);
   34|       |
   35|       |   // std::stoul is not strict enough. Ensure that str is digit only [0-9]*
   36|      2|   for(const char chr : str) {
  ------------------
  |  Branch (36:23): [True: 2, False: 1]
  ------------------
   37|      2|      if(chr < '0' || chr > '9') {
  ------------------
  |  Branch (37:10): [True: 0, False: 2]
  |  Branch (37:23): [True: 0, False: 2]
  ------------------
   38|      0|         throw Invalid_Argument("to_u32bit invalid decimal string '" + str + "'");
   39|      0|      }
   40|      2|   }
   41|       |
   42|      1|   const unsigned long int x = std::stoul(str);
   43|       |
   44|      1|   if constexpr(sizeof(unsigned long int) > 4) {
  ------------------
  |  Branch (44:17): [Folded - Ignored]
  ------------------
   45|       |      // x might be uint64
   46|      1|      if(x > std::numeric_limits<uint32_t>::max()) {
  ------------------
  |  Branch (46:10): [True: 0, False: 1]
  ------------------
   47|      0|         throw Invalid_Argument("Integer value of " + str + " exceeds 32 bit range");
   48|      0|      }
   49|      1|   }
   50|       |
   51|      1|   return static_cast<uint32_t>(x);
   52|      1|}

_ZN5Botan9SCAN_NameC2ENSt3__117basic_string_viewIcNS1_11char_traitsIcEEEE:
   58|      2|SCAN_Name::SCAN_Name(std::string_view algo_spec) : m_orig_algo_spec(algo_spec), m_alg_name(), m_args(), m_mode_info() {
   59|      2|   if(algo_spec.empty()) {
  ------------------
  |  Branch (59:7): [True: 0, False: 2]
  ------------------
   60|      0|      throw Invalid_Argument("Expected algorithm name, got empty string");
   61|      0|   }
   62|       |
   63|      2|   std::vector<std::pair<size_t, std::string>> name;
   64|      2|   size_t level = 0;
   65|      2|   std::pair<size_t, std::string> accum = std::make_pair(level, "");
   66|       |
   67|      2|   const std::string decoding_error = "Bad SCAN name '" + m_orig_algo_spec + "': ";
   68|       |
   69|     23|   for(char c : algo_spec) {
  ------------------
  |  Branch (69:15): [True: 23, False: 2]
  ------------------
   70|     23|      if(c == '/' || c == ',' || c == '(' || c == ')') {
  ------------------
  |  Branch (70:10): [True: 0, False: 23]
  |  Branch (70:22): [True: 0, False: 23]
  |  Branch (70:34): [True: 2, False: 21]
  |  Branch (70:46): [True: 2, False: 19]
  ------------------
   71|      4|         if(c == '(') {
  ------------------
  |  Branch (71:13): [True: 2, False: 2]
  ------------------
   72|      2|            ++level;
   73|      2|         } else if(c == ')') {
  ------------------
  |  Branch (73:20): [True: 2, False: 0]
  ------------------
   74|      2|            if(level == 0) {
  ------------------
  |  Branch (74:16): [True: 0, False: 2]
  ------------------
   75|      0|               throw Decoding_Error(decoding_error + "Mismatched parens");
   76|      0|            }
   77|      2|            --level;
   78|      2|         }
   79|       |
   80|      4|         if(c == '/' && level > 0) {
  ------------------
  |  Branch (80:13): [True: 0, False: 4]
  |  Branch (80:25): [True: 0, False: 0]
  ------------------
   81|      0|            accum.second.push_back(c);
   82|      4|         } else {
   83|      4|            if(!accum.second.empty()) {
  ------------------
  |  Branch (83:16): [True: 4, False: 0]
  ------------------
   84|      4|               name.push_back(accum);
   85|      4|            }
   86|      4|            accum = std::make_pair(level, "");
   87|      4|         }
   88|     19|      } else {
   89|     19|         accum.second.push_back(c);
   90|     19|      }
   91|     23|   }
   92|       |
   93|      2|   if(!accum.second.empty()) {
  ------------------
  |  Branch (93:7): [True: 0, False: 2]
  ------------------
   94|      0|      name.push_back(accum);
   95|      0|   }
   96|       |
   97|      2|   if(level != 0) {
  ------------------
  |  Branch (97:7): [True: 0, False: 2]
  ------------------
   98|      0|      throw Decoding_Error(decoding_error + "Missing close paren");
   99|      0|   }
  100|       |
  101|      2|   if(name.empty()) {
  ------------------
  |  Branch (101:7): [True: 0, False: 2]
  ------------------
  102|      0|      throw Decoding_Error(decoding_error + "Empty name");
  103|      0|   }
  104|       |
  105|      2|   m_alg_name = name[0].second;
  106|       |
  107|      2|   bool in_modes = false;
  108|       |
  109|      4|   for(size_t i = 1; i != name.size(); ++i) {
  ------------------
  |  Branch (109:22): [True: 2, False: 2]
  ------------------
  110|      2|      if(name[i].first == 0) {
  ------------------
  |  Branch (110:10): [True: 0, False: 2]
  ------------------
  111|      0|         m_mode_info.push_back(make_arg(name, i));
  112|      0|         in_modes = true;
  113|      2|      } else if(name[i].first == 1 && !in_modes) {
  ------------------
  |  Branch (113:17): [True: 2, False: 0]
  |  Branch (113:39): [True: 2, False: 0]
  ------------------
  114|      2|         m_args.push_back(make_arg(name, i));
  115|      2|      }
  116|      2|   }
  117|      2|}
_ZNK5Botan9SCAN_Name3argEm:
  119|      1|std::string SCAN_Name::arg(size_t i) const {
  120|      1|   if(i >= arg_count()) {
  ------------------
  |  Branch (120:7): [True: 0, False: 1]
  ------------------
  121|      0|      throw Invalid_Argument("SCAN_Name::arg " + std::to_string(i) + " out of range for '" + to_string() + "'");
  122|      0|   }
  123|      1|   return m_args[i];
  124|      1|}
_ZNK5Botan9SCAN_Name14arg_as_integerEmm:
  133|      1|size_t SCAN_Name::arg_as_integer(size_t i, size_t def_value) const {
  134|      1|   if(i >= arg_count()) {
  ------------------
  |  Branch (134:7): [True: 0, False: 1]
  ------------------
  135|      0|      return def_value;
  136|      0|   }
  137|      1|   return to_u32bit(m_args[i]);
  138|      1|}
scan_name.cpp:_ZN5Botan12_GLOBAL__N_18make_argERKNSt3__16vectorINS1_4pairImNS1_12basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEEENS7_ISA_EEEEm:
   17|      2|std::string make_arg(const std::vector<std::pair<size_t, std::string>>& name, size_t start) {
   18|      2|   std::string output = name[start].second;
   19|      2|   size_t level = name[start].first;
   20|       |
   21|      2|   size_t paren_depth = 0;
   22|       |
   23|      2|   for(size_t i = start + 1; i != name.size(); ++i) {
  ------------------
  |  Branch (23:30): [True: 0, False: 2]
  ------------------
   24|      0|      if(name[i].first <= name[start].first) {
  ------------------
  |  Branch (24:10): [True: 0, False: 0]
  ------------------
   25|      0|         break;
   26|      0|      }
   27|       |
   28|      0|      if(name[i].first > level) {
  ------------------
  |  Branch (28:10): [True: 0, False: 0]
  ------------------
   29|      0|         output += "(" + name[i].second;
   30|      0|         ++paren_depth;
   31|      0|      } else if(name[i].first < level) {
  ------------------
  |  Branch (31:17): [True: 0, False: 0]
  ------------------
   32|      0|         for(size_t j = name[i].first; j < level; j++) {
  ------------------
  |  Branch (32:40): [True: 0, False: 0]
  ------------------
   33|      0|            output += ")";
   34|      0|            --paren_depth;
   35|      0|         }
   36|      0|         output += "," + name[i].second;
   37|      0|      } else {
   38|      0|         if(output[output.size() - 1] != '(') {
  ------------------
  |  Branch (38:13): [True: 0, False: 0]
  ------------------
   39|      0|            output += ",";
   40|      0|         }
   41|      0|         output += name[i].second;
   42|      0|      }
   43|       |
   44|      0|      level = name[i].first;
   45|      0|   }
   46|       |
   47|      2|   for(size_t i = 0; i != paren_depth; ++i) {
  ------------------
  |  Branch (47:22): [True: 0, False: 2]
  ------------------
   48|      0|      output += ")";
   49|      0|   }
   50|       |
   51|      2|   return output;
   52|      2|}

