_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEmEET_S2_:
   28|   472k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|   472k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|   472k|   return static_cast<T>(0) - top;
   31|   472k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEmEET_S2_:
   37|   125k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|   125k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|   125k|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEmEET_S2_S2_S2_:
  217|  47.6k|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  218|       |   //return (mask & a) | (~mask & b);
  219|  47.6k|   return (b ^ (mask & (a ^ b)));
  220|  47.6k|}
_ZN5Botan17ct_if_is_zero_retITkNSt3__117unsigned_integralEmEEmT_m:
   45|  32.1k|BOTAN_FORCE_INLINE constexpr size_t ct_if_is_zero_ret(T x, size_t s) {
   46|       |   /*
   47|       |   Similar to `return ct_is_zero(x) & s` but has to account for possibility that
   48|       |   sizeof(T) is smaller than sizeof(size_t) which would lead to incomplete masking
   49|       |   */
   50|  32.1k|   const T a = ~x & (x - 1);
   51|  32.1k|   const size_t a_top = static_cast<size_t>(CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1)));
   52|  32.1k|   const size_t mask = static_cast<size_t>(0) - a_top;
   53|  32.1k|   return mask & s;
   54|  32.1k|}
_ZN5Botan8high_bitITkNSt3__117unsigned_integralEmEEmT_:
   73|  5.36k|BOTAN_FORCE_INLINE constexpr size_t high_bit(T n) {
   74|  5.36k|   size_t hb = 0;
   75|       |
   76|  37.5k|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (76:38): [True: 32.1k, False: 5.36k]
  ------------------
   77|       |      // Equivalent to: ((n >> s) == 0) ? 0 : s;
   78|  32.1k|      const size_t z = s - ct_if_is_zero_ret<T>(n >> s, s);
   79|  32.1k|      hb += z;
   80|  32.1k|      n >>= z;
   81|  32.1k|   }
   82|       |
   83|  5.36k|   hb += static_cast<size_t>(n);
   84|       |
   85|  5.36k|   return hb;
   86|  5.36k|}
_ZN5Botan13is_power_of_2ITkNSt3__117unsigned_integralEmEEbT_:
   62|    521|BOTAN_FORCE_INLINE constexpr bool is_power_of_2(T arg) {
   63|    521|   return (arg != 0) && (arg != 1) && ((arg & static_cast<T>(arg - 1)) == 0);
  ------------------
  |  Branch (63:11): [True: 521, False: 0]
  |  Branch (63:25): [True: 521, False: 0]
  |  Branch (63:39): [True: 5, False: 516]
  ------------------
   64|    521|}
_ZN5Botan13ceil_divisionITkNSt3__117unsigned_integralEmEET_S2_S2_:
  167|  1.74k|BOTAN_FORCE_INLINE constexpr T ceil_division(T a, T b) {
  168|       |   // Same as `(a + b - 1) / b` but avoids possible overflow
  169|  1.74k|   return a / b + ((a % b != 0) ? 1 : 0);
  ------------------
  |  Branch (169:20): [True: 1.70k, False: 44]
  ------------------
  170|  1.74k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEhEET_S2_:
   37|    290|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|    290|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|    290|}
_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEhEET_S2_:
   28|    290|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|    290|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|    290|   return static_cast<T>(0) - top;
   31|    290|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEhEET_S2_S2_S2_:
  217|    290|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  218|       |   //return (mask & a) | (~mask & b);
  219|    290|   return (b ^ (mask & (a ^ b)));
  220|    290|}

_ZN5Botan13reverse_bytesITkNSt3__117unsigned_integralEmQooooooeqstT_Li1EeqstS2_Li2EeqstS2_Li4EeqstS2_Li8EEES2_S2_:
   25|  11.4k|inline constexpr T reverse_bytes(T x) {
   26|       |   if constexpr(sizeof(T) == 1) {
   27|       |      return x;
   28|       |   } else if constexpr(sizeof(T) == 2) {
   29|       |#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_bswap16)
   30|       |      return static_cast<T>(__builtin_bswap16(x));
   31|       |#else
   32|       |      return static_cast<T>((x << 8) | (x >> 8));
   33|       |#endif
   34|       |   } else if constexpr(sizeof(T) == 4) {
   35|       |#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_bswap32)
   36|       |      return static_cast<T>(__builtin_bswap32(x));
   37|       |#else
   38|       |      // MSVC at least recognizes this as a bswap
   39|       |      return static_cast<T>(((x & 0x000000FF) << 24) | ((x & 0x0000FF00) << 8) | ((x & 0x00FF0000) >> 8) |
   40|       |                            ((x & 0xFF000000) >> 24));
   41|       |#endif
   42|  11.4k|   } else if constexpr(sizeof(T) == 8) {
   43|  11.4k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_bswap64)
   44|  11.4k|      return static_cast<T>(__builtin_bswap64(x));
   45|       |#else
   46|       |      uint32_t hi = static_cast<uint32_t>(x >> 32);
   47|       |      uint32_t lo = static_cast<uint32_t>(x);
   48|       |
   49|       |      hi = reverse_bytes(hi);
   50|       |      lo = reverse_bytes(lo);
   51|       |
   52|       |      return (static_cast<T>(lo) << 32) | hi;
   53|       |#endif
   54|  11.4k|   }
   55|  11.4k|}

_ZN5Botan5CPUID3hasENS_10CPUFeatureES1_:
   98|    478|      static bool has(CPUID::Feature feat1, CPUID::Feature feat2) {
   99|    478|         return state().has_bit(feat1.as_u32() | feat2.as_u32());
  100|    478|      }
_ZN5Botan5CPUID5stateEv:
  155|    478|      static CPUID_Data& state() {
  156|    478|         static CPUID::CPUID_Data g_cpuid;
  157|    478|         return g_cpuid;
  158|    478|      }
_ZNK5Botan5CPUID10CPUID_Data7has_bitEj:
  143|    478|            bool has_bit(uint32_t bit) const { return (m_processor_features & bit) == bit; }
_ZN5Botan5CPUID6is_setEjNS_10CPUFeatureE:
  126|      5|      static inline bool is_set(uint32_t allowed, CPUID::Feature bit) {
  127|      5|         const uint32_t feat_bit = bit.as_u32();
  128|      5|         return ((allowed & feat_bit) == feat_bit);
  129|      5|      }
cpuid_x86.cpp:_ZN5Botan5CPUID6if_setIZNS0_10CPUID_Data19detect_cpu_featuresEjE16x86_CPUID_1_bitsEEjmT_NS_10CPUFeatureEj:
  116|      7|      static inline uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed) {
  117|      7|         const uint64_t flag64 = static_cast<uint64_t>(flag);
  118|      7|         if((cpuid & flag64) == flag64) {
  ------------------
  |  Branch (118:13): [True: 7, False: 0]
  ------------------
  119|      7|            return (bit.as_u32() & allowed);
  120|      7|         } else {
  121|      0|            return 0;
  122|      0|         }
  123|      7|      }
cpuid_x86.cpp:_ZN5Botan5CPUID6if_setIZNS0_10CPUID_Data19detect_cpu_featuresEjE16x86_CPUID_7_bitsEEjmT_NS_10CPUFeatureEj:
  116|      8|      static inline uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed) {
  117|      8|         const uint64_t flag64 = static_cast<uint64_t>(flag);
  118|      8|         if((cpuid & flag64) == flag64) {
  ------------------
  |  Branch (118:13): [True: 5, False: 3]
  ------------------
  119|      5|            return (bit.as_u32() & allowed);
  120|      5|         } else {
  121|      3|            return 0;
  122|      3|         }
  123|      8|      }
cpuid_x86.cpp:_ZN5Botan5CPUID6if_setIZNS0_10CPUID_Data19detect_cpu_featuresEjE18x86_CPUID_7_1_bitsEEjmT_NS_10CPUFeatureEj:
  116|      3|      static inline uint32_t if_set(uint64_t cpuid, T flag, CPUID::Feature bit, uint32_t allowed) {
  117|      3|         const uint64_t flag64 = static_cast<uint64_t>(flag);
  118|      3|         if((cpuid & flag64) == flag64) {
  ------------------
  |  Branch (118:13): [True: 0, False: 3]
  ------------------
  119|      0|            return (bit.as_u32() & allowed);
  120|      3|         } else {
  121|      3|            return 0;
  122|      3|         }
  123|      3|      }

_ZNK5Botan10CPUFeature6as_u32Ev:
   56|    973|      uint32_t as_u32() const { return static_cast<uint32_t>(m_bit); }
_ZN5Botan10CPUFeatureC2ENS0_3BitE:
   54|    979|      CPUFeature(Bit b) : m_bit(b) {}  // NOLINT(*-explicit-conversions,*-explicit-constructor)

_ZN5Botan2CT4MaskImE5is_gtEmm:
  458|  66.5k|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  450|   219k|      static constexpr Mask<T> is_lt(T x, T y) {
  451|   219k|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|   219k|         return Mask<T>::expand_top_bit(u);
  453|   219k|      }
_ZN5Botan2CT4MaskImE14expand_top_bitEm:
  415|   346k|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskImEC2Em:
  637|   784k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskImE13if_set_returnEm:
  538|   361k|      constexpr T if_set_return(T x) const { return value() & x; }
_ZNK5Botan2CT4MaskImE5valueEv:
  630|   974k|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZN5Botan2CT4MaskImE6is_gteEmm:
  468|   139k|      static constexpr Mask<T> is_gte(T x, T y) { return ~Mask<T>::is_lt(x, y); }
_ZNK5Botan2CT4MaskImEcoEv:
  533|   152k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZN5Botan2CT4MaskImE7is_zeroEm:
  437|  76.1k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT4MaskImE6expandEm:
  392|  12.9k|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZNK5Botan2CT4MaskImE6selectEmm:
  548|  26.8k|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT8unpoisonImEEvPKT_m:
   67|  25.5k|constexpr inline void unpoison(const T* p, size_t n) {
   68|       |#if defined(BOTAN_HAS_VALGRIND)
   69|       |   if(!std::is_constant_evaluated()) {
   70|       |      VALGRIND_MAKE_MEM_DEFINED(p, n * sizeof(T));
   71|       |   }
   72|       |#endif
   73|       |
   74|  25.5k|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  151|  25.5k|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|  25.5k|}
_ZN5Botan2CT8unpoisonITkNSt3__18integralEmEEvRKT_:
  112|  7.75k|constexpr void unpoison(const T& p) {
  113|  7.75k|   unpoison(&p, 1);
  114|  7.75k|}
_ZNK5Botan2CT4MaskImE16unpoisoned_valueEv:
  598|  2.56k|      constexpr T unpoisoned_value() const {
  599|  2.56k|         T r = value();
  600|  2.56k|         CT::unpoison(r);
  601|  2.56k|         return r;
  602|  2.56k|      }
_ZN5Botan2CTorENS0_4MaskImEES2_:
  528|   163k|      friend constexpr Mask<T> operator|(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() | y.value()); }
_ZN5Botan2CT4MaskImE8is_equalEmm:
  442|  59.4k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|  59.4k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|  59.4k|         return Mask<T>::is_zero(diff);
  445|  59.4k|      }
_ZN5Botan2CT20conditional_copy_memImEENS0_4MaskIT_EES3_PS3_PKS3_S7_m:
  738|    960|constexpr inline Mask<T> conditional_copy_mem(T cnd, T* dest, const T* if_set, const T* if_unset, size_t elems) {
  739|    960|   const auto mask = CT::Mask<T>::expand(cnd);
  740|    960|   return CT::conditional_copy_mem(mask, dest, if_set, if_unset, elems);
  741|    960|}
_ZN5Botan2CT20conditional_copy_memImEENS0_4MaskIT_EES4_PS3_PKS3_S7_m:
  732|    960|constexpr inline Mask<T> conditional_copy_mem(Mask<T> mask, T* dest, const T* if_set, const T* if_unset, size_t elems) {
  733|    960|   mask.select_n(dest, if_set, if_unset, elems);
  734|    960|   return mask;
  735|    960|}
_ZNK5Botan2CT4MaskImE8select_nEPmPKmS5_m:
  565|  3.52k|      constexpr void select_n(T output[], const T x[], const T y[], size_t len) const {
  566|  3.52k|         const T mask = value();
  567|  24.2k|         for(size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (567:28): [True: 20.7k, False: 3.52k]
  ------------------
  568|  20.7k|            output[i] = choose(mask, x[i], y[i]);
  569|  20.7k|         }
  570|  3.52k|      }
_ZNK5Botan2CT4MaskImE7as_boolEv:
  614|  2.56k|      constexpr bool as_bool() const { return unpoisoned_value() != 0; }
_ZNK5Botan2CT4MaskImE11select_maskES2_S2_:
  559|  8.85k|      Mask<T> select_mask(Mask<T> x, Mask<T> y) const { return Mask<T>(select(x.value(), y.value())); }
_ZN5Botan2CT4MaskImEaNES2_:
  494|    230|      Mask<T>& operator&=(Mask<T> o) {
  495|    230|         m_mask &= o.value();
  496|    230|         return (*this);
  497|    230|      }
_ZN5Botan2CT4MaskIhE11expand_boolEb:
  397|    290|      static constexpr Mask<T> expand_bool(bool v) { return Mask<T>::expand(static_cast<T>(v)); }
_ZN5Botan2CT4MaskIhE6expandEh:
  392|    290|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  437|    290|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT4MaskIhEC2Eh:
  637|    580|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhEcoEv:
  533|    290|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskIhE5valueEv:
  630|    580|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskIhE6selectEhh:
  548|    290|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT6poisonImEEvPKT_m:
   56|    854|constexpr inline void poison(const T* p, size_t n) {
   57|       |#if defined(BOTAN_HAS_VALGRIND)
   58|       |   if(!std::is_constant_evaluated()) {
   59|       |      VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T));
   60|       |   }
   61|       |#endif
   62|       |
   63|    854|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  151|    854|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   64|    854|}
_ZN5Botan2CTanENS0_4MaskImEES2_:
  518|  36.2k|      friend constexpr Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CTeoENS0_4MaskImEES2_:
  523|     53|      friend constexpr Mask<T> operator^(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() ^ y.value()); }
_ZN5Botan2CT6poisonITkNS_6ranges14spanable_rangeENSt3__14spanIKmLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS3_11conditionalIXsr21__is_primary_templateINS3_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS3_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS3_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEnt17custom_poisonableISB_EEEvRKSB_:
  121|    854|constexpr void poison(const R& r) {
  122|    854|   const std::span s{r};
  123|    854|   poison(s.data(), s.size());
  124|    854|}
_ZN5Botan2CT8unpoisonITkNS_6ranges14spanable_rangeENSt3__16vectorImNS_16secure_allocatorImEEEEQaasr3stdE23is_trivially_copyable_vINS3_11conditionalIXsr21__is_primary_templateINS3_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS3_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS3_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEnt19custom_unpoisonableISC_EEEvRKSC_:
  128|  2.56k|constexpr void unpoison(const R& r) {
  129|  2.56k|   const std::span s{r};
  130|  2.56k|   unpoison(s.data(), s.size());
  131|  2.56k|}
_ZN5Botan2CT8unpoisonITkNS_6ranges14spanable_rangeENSt3__14spanIKmLm18446744073709551615EEEQaasr3stdE23is_trivially_copyable_vINS3_11conditionalIXsr21__is_primary_templateINS3_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS3_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS3_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEnt19custom_unpoisonableISB_EEEvRKSB_:
  128|    854|constexpr void unpoison(const R& r) {
  129|    854|   const std::span s{r};
  130|    854|   unpoison(s.data(), s.size());
  131|    854|}

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

_ZN5Botan11checked_mulITkNSt3__117unsigned_integralEmEENS1_8optionalIT_EES3_S3_:
   46|  14.3k|constexpr inline std::optional<T> checked_mul(T a, T b) {
   47|       |   // Multiplication by 1U is a hack to work around C's insane
   48|       |   // integer promotion rules.
   49|       |   // https://stackoverflow.com/questions/24795651
   50|  14.3k|   const T r = (1U * a) * b;
   51|       |   // If a == 0 then the multiply certainly did not overflow
   52|       |   // Otherwise r / a == b unless overflow occurred
   53|  14.3k|   if(a != 0 && r / a != b) {
  ------------------
  |  Branch (53:7): [True: 14.3k, False: 0]
  |  Branch (53:17): [True: 0, False: 14.3k]
  ------------------
   54|      0|      return {};
   55|      0|   }
   56|  14.3k|   return r;
   57|  14.3k|}

_ZN5Botan7load_beImJNSt3__14spanIKhLm8EEEEEEDaDpOT0_:
  504|  10.2k|inline constexpr auto load_be(ParamTs&&... params) {
  505|  10.2k|   return detail::load_any<std::endian::big, OutT>(std::forward<ParamTs>(params)...);
  506|  10.2k|}
_ZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEENS2_4spanIKhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_:
  278|  10.2k|inline constexpr WrappedOutT load_any(InR&& in_range) {
  279|  10.2k|   using OutT = detail::wrapped_type<WrappedOutT>;
  280|  10.2k|   ranges::assert_exact_byte_length<sizeof(OutT)>(in_range);
  281|       |
  282|  10.2k|   return detail::wrap_strong_type_or_enum<WrappedOutT>([&]() -> OutT {
  283|       |      // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  284|       |      // internally to copy ranges on a byte-by-byte basis, which is not allowed
  285|       |      // in a `constexpr` context.
  286|  10.2k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  287|  10.2k|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  10.2k|      } else {
  289|  10.2k|         const std::span in{in_range};
  290|  10.2k|         if constexpr(sizeof(OutT) == 1) {
  291|  10.2k|            return static_cast<OutT>(in[0]);
  292|  10.2k|         } else if constexpr(endianness == std::endian::native) {
  293|  10.2k|            return typecast_copy<OutT>(in);
  294|  10.2k|         } else {
  295|  10.2k|            static_assert(opposite(endianness) == std::endian::native);
  296|  10.2k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  10.2k|         }
  298|  10.2k|      }
  299|  10.2k|   }());
  300|  10.2k|}
_ZN5Botan6detail24wrap_strong_type_or_enumITkNS0_20unsigned_integralishEmTkNSt3__117unsigned_integralEmEEDaT0_:
  200|  11.4k|constexpr auto wrap_strong_type_or_enum(T t) {
  201|       |   if constexpr(std::is_enum_v<OutT>) {
  202|       |      return static_cast<OutT>(t);
  203|  11.4k|   } else {
  204|  11.4k|      return Botan::wrap_strong_type<OutT>(t);
  205|  11.4k|   }
  206|  11.4k|}
_ZZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEENS2_4spanIKhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_ENKUlvE_clEv:
  282|  10.2k|   return detail::wrap_strong_type_or_enum<WrappedOutT>([&]() -> OutT {
  283|       |      // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  284|       |      // internally to copy ranges on a byte-by-byte basis, which is not allowed
  285|       |      // in a `constexpr` context.
  286|  10.2k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (286:10): [Folded, False: 10.2k]
  ------------------
  287|      0|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  10.2k|      } else {
  289|  10.2k|         const std::span in{in_range};
  290|       |         if constexpr(sizeof(OutT) == 1) {
  291|       |            return static_cast<OutT>(in[0]);
  292|       |         } else if constexpr(endianness == std::endian::native) {
  293|       |            return typecast_copy<OutT>(in);
  294|  10.2k|         } else {
  295|  10.2k|            static_assert(opposite(endianness) == std::endian::native);
  296|  10.2k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  10.2k|         }
  298|  10.2k|      }
  299|  10.2k|   }());
_ZN5Botan7load_beImJRNSt3__15arrayIhLm8EEEEEEDaDpOT0_:
  504|  1.21k|inline constexpr auto load_be(ParamTs&&... params) {
  505|  1.21k|   return detail::load_any<std::endian::big, OutT>(std::forward<ParamTs>(params)...);
  506|  1.21k|}
_ZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEERNS2_5arrayIhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_:
  278|  1.21k|inline constexpr WrappedOutT load_any(InR&& in_range) {
  279|  1.21k|   using OutT = detail::wrapped_type<WrappedOutT>;
  280|  1.21k|   ranges::assert_exact_byte_length<sizeof(OutT)>(in_range);
  281|       |
  282|  1.21k|   return detail::wrap_strong_type_or_enum<WrappedOutT>([&]() -> OutT {
  283|       |      // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  284|       |      // internally to copy ranges on a byte-by-byte basis, which is not allowed
  285|       |      // in a `constexpr` context.
  286|  1.21k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  287|  1.21k|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  1.21k|      } else {
  289|  1.21k|         const std::span in{in_range};
  290|  1.21k|         if constexpr(sizeof(OutT) == 1) {
  291|  1.21k|            return static_cast<OutT>(in[0]);
  292|  1.21k|         } else if constexpr(endianness == std::endian::native) {
  293|  1.21k|            return typecast_copy<OutT>(in);
  294|  1.21k|         } else {
  295|  1.21k|            static_assert(opposite(endianness) == std::endian::native);
  296|  1.21k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  1.21k|         }
  298|  1.21k|      }
  299|  1.21k|   }());
  300|  1.21k|}
_ZZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEERNS2_5arrayIhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_ENKUlvE_clEv:
  282|  1.21k|   return detail::wrap_strong_type_or_enum<WrappedOutT>([&]() -> OutT {
  283|       |      // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  284|       |      // internally to copy ranges on a byte-by-byte basis, which is not allowed
  285|       |      // in a `constexpr` context.
  286|  1.21k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (286:10): [Folded, False: 1.21k]
  ------------------
  287|      0|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  1.21k|      } else {
  289|  1.21k|         const std::span in{in_range};
  290|       |         if constexpr(sizeof(OutT) == 1) {
  291|       |            return static_cast<OutT>(in[0]);
  292|       |         } else if constexpr(endianness == std::endian::native) {
  293|       |            return typecast_copy<OutT>(in);
  294|  1.21k|         } else {
  295|  1.21k|            static_assert(opposite(endianness) == std::endian::native);
  296|  1.21k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  1.21k|         }
  298|  1.21k|      }
  299|  1.21k|   }());

_ZN5Botan14zeroize_bufferITkNSt3__117unsigned_integralEmEEvPT_m:
   37|  2.57k|inline void zeroize_buffer(T buf[], size_t n) {
   38|  2.57k|   if(n > 0) {
  ------------------
  |  Branch (38:7): [True: 2.57k, False: 0]
  ------------------
   39|  2.57k|      std::memset(buf, 0, sizeof(T) * n);
   40|  2.57k|   }
   41|  2.57k|}

_ZN5Botan10word_madd2ITkNS_8WordTypeEmEET_S1_S1_PS1_:
   90|   247k|inline constexpr auto word_madd2(W a, W b, W* c) -> W {
   91|   247k|#if defined(BOTAN_MP_USE_X86_64_ASM)
   92|   247k|   if constexpr(std::same_as<W, uint64_t>) {
   93|   247k|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (93:10): [True: 247k, Folded]
  ------------------
   94|   247k|         asm(R"(
   95|   247k|            mulq %[b]
   96|   247k|            addq %[c],%[a]
   97|   247k|            adcq $0,%[carry]
   98|   247k|            )"
   99|   247k|             : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c)
  100|   247k|             : "0"(a), "1"(b), [c] "g"(*c)
  101|   247k|             : "cc");
  102|       |
  103|   247k|         return a;
  104|   247k|      }
  105|   247k|   }
  106|       |#elif defined(BOTAN_MP_USE_AARCH64_ASM)
  107|       |   if constexpr(std::same_as<W, uint64_t>) {
  108|       |      if(!std::is_constant_evaluated()) {
  109|       |         W lo = 0;
  110|       |         W hi = 0;
  111|       |         asm(R"(
  112|       |            mul  %[lo], %[a], %[b]
  113|       |            umulh %[hi], %[a], %[b]
  114|       |            adds %[lo], %[lo], %[c]
  115|       |            adc  %[hi], %[hi], xzr
  116|       |            )"
  117|       |             : [lo] "=&r"(lo), [hi] "=&r"(hi)
  118|       |             : [a] "r"(a), [b] "r"(b), [c] "r"(*c)
  119|       |             : "cc");
  120|       |
  121|       |         *c = hi;
  122|       |         return lo;
  123|       |      }
  124|       |   }
  125|       |#endif
  126|       |
  127|      0|   typedef typename WordInfo<W>::dword dword;
  128|   247k|   const dword s = dword(a) * b + *c;
  129|   247k|   *c = static_cast<W>(s >> WordInfo<W>::bits);
  130|   247k|   return static_cast<W>(s);
  131|   247k|}
_ZN5Botan10word8_add2ITkNS_8WordTypeEmEET_PS1_PKS1_S1_:
  276|    242|inline constexpr auto word8_add2(W x[8], const W y[8], W carry) -> W {
  277|    242|#if defined(BOTAN_MP_USE_X86_64_ASM)
  278|    242|   if constexpr(std::same_as<W, uint64_t>) {
  279|    242|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (279:10): [True: 242, Folded]
  ------------------
  280|    242|         asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcq"))
  281|    242|                      : [carry] "=r"(carry)
  282|    242|                      : [x] "r"(x), [y] "r"(y), "0"(carry)
  283|    242|                      : "cc", "memory");
  284|    242|         return carry;
  285|    242|      }
  286|    242|   }
  287|      0|#endif
  288|       |
  289|      0|   x[0] = word_add(x[0], y[0], &carry);
  290|    242|   x[1] = word_add(x[1], y[1], &carry);
  291|    242|   x[2] = word_add(x[2], y[2], &carry);
  292|    242|   x[3] = word_add(x[3], y[3], &carry);
  293|    242|   x[4] = word_add(x[4], y[4], &carry);
  294|    242|   x[5] = word_add(x[5], y[5], &carry);
  295|    242|   x[6] = word_add(x[6], y[6], &carry);
  296|    242|   x[7] = word_add(x[7], y[7], &carry);
  297|    242|   return carry;
  298|    242|}
_ZN5Botan8word_addITkNS_8WordTypeEmEET_S1_S1_PS1_:
  239|   203k|inline constexpr auto word_add(W x, W y, W* carry) -> W {
  240|   203k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_addc)
  241|   203k|   if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (241:7): [True: 203k, Folded]
  ------------------
  242|       |      if constexpr(std::same_as<W, unsigned int>) {
  243|       |         return __builtin_addc(x, y, *carry & 1, carry);
  244|   203k|      } else if constexpr(std::same_as<W, unsigned long>) {
  245|   203k|         return __builtin_addcl(x, y, *carry & 1, carry);
  246|       |      } else if constexpr(std::same_as<W, unsigned long long>) {
  247|       |         return __builtin_addcll(x, y, *carry & 1, carry);
  248|       |      }
  249|   203k|   }
  250|      0|#endif
  251|       |
  252|       |   if constexpr(WordInfo<W>::dword_is_native && use_dword_for_word_add) {
  253|       |      /*
  254|       |      TODO(Botan4) this is largely a performance hack for GCCs that don't
  255|       |      support __builtin_addc, if we increase the minimum supported version of
  256|       |      GCC to GCC 14 then we can remove this and not worry about it
  257|       |      */
  258|       |      const W cb = *carry & 1;
  259|       |      const auto s = typename WordInfo<W>::dword(x) + y + cb;
  260|       |      *carry = static_cast<W>(s >> WordInfo<W>::bits);
  261|       |      return static_cast<W>(s);
  262|   203k|   } else {
  263|   203k|      const W cb = *carry & 1;
  264|   203k|      W z = x + y;
  265|   203k|      W c1 = (z < x);
  266|   203k|      z += cb;
  267|   203k|      *carry = c1 | (z < cb);
  268|   203k|      return z;
  269|   203k|   }
  270|   203k|}
_ZN5Botan10word8_sub2ITkNS_8WordTypeEmEET_PS1_PKS1_S1_:
  357|    267|inline constexpr auto word8_sub2(W x[8], const W y[8], W carry) -> W {
  358|    267|#if defined(BOTAN_MP_USE_X86_64_ASM)
  359|    267|   if constexpr(std::same_as<W, uint64_t>) {
  360|    267|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (360:10): [True: 267, Folded]
  ------------------
  361|    267|         asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbq"))
  362|    267|                      : [carry] "=r"(carry)
  363|    267|                      : [x] "r"(x), [y] "r"(y), "0"(carry)
  364|    267|                      : "cc", "memory");
  365|    267|         return carry;
  366|    267|      }
  367|    267|   }
  368|      0|#endif
  369|       |
  370|      0|   x[0] = word_sub(x[0], y[0], &carry);
  371|    267|   x[1] = word_sub(x[1], y[1], &carry);
  372|    267|   x[2] = word_sub(x[2], y[2], &carry);
  373|    267|   x[3] = word_sub(x[3], y[3], &carry);
  374|    267|   x[4] = word_sub(x[4], y[4], &carry);
  375|    267|   x[5] = word_sub(x[5], y[5], &carry);
  376|    267|   x[6] = word_sub(x[6], y[6], &carry);
  377|    267|   x[7] = word_sub(x[7], y[7], &carry);
  378|    267|   return carry;
  379|    267|}
_ZN5Botan8word_subITkNS_8WordTypeEmEET_S1_S1_PS1_:
  332|   224k|inline constexpr auto word_sub(W x, W y, W* carry) -> W {
  333|   224k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_subc)
  334|   224k|   if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (334:7): [True: 224k, Folded]
  ------------------
  335|       |      if constexpr(std::same_as<W, unsigned int>) {
  336|       |         return __builtin_subc(x, y, *carry & 1, carry);
  337|   224k|      } else if constexpr(std::same_as<W, unsigned long>) {
  338|   224k|         return __builtin_subcl(x, y, *carry & 1, carry);
  339|       |      } else if constexpr(std::same_as<W, unsigned long long>) {
  340|       |         return __builtin_subcll(x, y, *carry & 1, carry);
  341|       |      }
  342|   224k|   }
  343|      0|#endif
  344|       |
  345|      0|   const W cb = *carry & 1;
  346|   224k|   W t0 = x - y;
  347|   224k|   W c1 = (t0 > x);
  348|   224k|   W z = t0 - cb;
  349|   224k|   *carry = c1 | (z > t0);
  350|   224k|   return z;
  351|   224k|}
_ZN5Botan10word8_sub3ITkNS_8WordTypeEmEET_PS1_PKS1_S4_S1_:
  385|  1.39k|inline constexpr auto word8_sub3(W z[8], const W x[8], const W y[8], W carry) -> W {
  386|  1.39k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  387|  1.39k|   if constexpr(std::same_as<W, uint64_t>) {
  388|  1.39k|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (388:10): [True: 1.39k, Folded]
  ------------------
  389|  1.39k|         asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq"))
  390|  1.39k|                      : [carry] "=r"(carry)
  391|  1.39k|                      : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry)
  392|  1.39k|                      : "cc", "memory");
  393|  1.39k|         return carry;
  394|  1.39k|      }
  395|  1.39k|   }
  396|      0|#endif
  397|       |
  398|      0|   z[0] = word_sub(x[0], y[0], &carry);
  399|  1.39k|   z[1] = word_sub(x[1], y[1], &carry);
  400|  1.39k|   z[2] = word_sub(x[2], y[2], &carry);
  401|  1.39k|   z[3] = word_sub(x[3], y[3], &carry);
  402|  1.39k|   z[4] = word_sub(x[4], y[4], &carry);
  403|  1.39k|   z[5] = word_sub(x[5], y[5], &carry);
  404|  1.39k|   z[6] = word_sub(x[6], y[6], &carry);
  405|  1.39k|   z[7] = word_sub(x[7], y[7], &carry);
  406|  1.39k|   return carry;
  407|  1.39k|}
_ZN5Botan10word8_add3ITkNS_8WordTypeEmEET_PS1_PKS1_S4_S1_:
  304|    242|inline constexpr auto word8_add3(W z[8], const W x[8], const W y[8], W carry) -> W {
  305|    242|#if defined(BOTAN_MP_USE_X86_64_ASM)
  306|    242|   if constexpr(std::same_as<W, uint64_t>) {
  307|    242|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (307:10): [True: 242, Folded]
  ------------------
  308|    242|         asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcq"))
  309|    242|                      : [carry] "=r"(carry)
  310|    242|                      : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry)
  311|    242|                      : "cc", "memory");
  312|    242|         return carry;
  313|    242|      }
  314|    242|   }
  315|      0|#endif
  316|       |
  317|      0|   z[0] = word_add(x[0], y[0], &carry);
  318|    242|   z[1] = word_add(x[1], y[1], &carry);
  319|    242|   z[2] = word_add(x[2], y[2], &carry);
  320|    242|   z[3] = word_add(x[3], y[3], &carry);
  321|    242|   z[4] = word_add(x[4], y[4], &carry);
  322|    242|   z[5] = word_add(x[5], y[5], &carry);
  323|    242|   z[6] = word_add(x[6], y[6], &carry);
  324|    242|   z[7] = word_add(x[7], y[7], &carry);
  325|    242|   return carry;
  326|    242|}
_ZN5Botan11word8_madd3ITkNS_8WordTypeEmEET_PS1_PKS1_S1_S1_:
  441|  10.8k|inline constexpr auto word8_madd3(W z[8], const W x[8], W y, W carry) -> W {
  442|  10.8k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  443|  10.8k|   if constexpr(std::same_as<W, uint64_t>) {
  444|  10.8k|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (444:10): [True: 10.8k, Folded]
  ------------------
  445|  10.8k|         asm volatile(DO_8_TIMES(MULADD_OP, "")
  446|  10.8k|                      : [carry] "=r"(carry)
  447|  10.8k|                      : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry)
  448|  10.8k|                      : "cc", "%rax", "%rdx", "memory");
  449|  10.8k|         return carry;
  450|  10.8k|      }
  451|  10.8k|   }
  452|      0|#endif
  453|       |
  454|      0|   z[0] = word_madd3(x[0], y, z[0], &carry);
  455|  10.8k|   z[1] = word_madd3(x[1], y, z[1], &carry);
  456|  10.8k|   z[2] = word_madd3(x[2], y, z[2], &carry);
  457|  10.8k|   z[3] = word_madd3(x[3], y, z[3], &carry);
  458|  10.8k|   z[4] = word_madd3(x[4], y, z[4], &carry);
  459|  10.8k|   z[5] = word_madd3(x[5], y, z[5], &carry);
  460|  10.8k|   z[6] = word_madd3(x[6], y, z[6], &carry);
  461|  10.8k|   z[7] = word_madd3(x[7], y, z[7], &carry);
  462|  10.8k|   return carry;
  463|  10.8k|}
_ZN5Botan10word_madd3ITkNS_8WordTypeEmEET_S1_S1_S1_PS1_:
  137|  20.6k|inline constexpr auto word_madd3(W a, W b, W c, W* d) -> W {
  138|  20.6k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  139|  20.6k|   if constexpr(std::same_as<W, uint64_t>) {
  140|  20.6k|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (140:10): [True: 20.6k, Folded]
  ------------------
  141|  20.6k|         asm(R"(
  142|  20.6k|            mulq %[b]
  143|  20.6k|
  144|  20.6k|            addq %[c],%[a]
  145|  20.6k|            adcq $0,%[carry]
  146|  20.6k|
  147|  20.6k|            addq %[d],%[a]
  148|  20.6k|            adcq $0,%[carry]
  149|  20.6k|            )"
  150|  20.6k|             : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d)
  151|  20.6k|             : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d)
  152|  20.6k|             : "cc");
  153|       |
  154|  20.6k|         return a;
  155|  20.6k|      }
  156|  20.6k|   }
  157|       |#elif defined(BOTAN_MP_USE_AARCH64_ASM)
  158|       |   if constexpr(std::same_as<W, uint64_t>) {
  159|       |      if(!std::is_constant_evaluated()) {
  160|       |         W lo = 0;
  161|       |         W hi = 0;
  162|       |         asm(R"(
  163|       |            mul  %[lo], %[a], %[b]
  164|       |            umulh %[hi], %[a], %[b]
  165|       |            adds %[lo], %[lo], %[c]
  166|       |            adc  %[hi], %[hi], xzr
  167|       |            adds %[lo], %[lo], %[d]
  168|       |            adc  %[hi], %[hi], xzr
  169|       |            )"
  170|       |             : [lo] "=&r"(lo), [hi] "=&r"(hi)
  171|       |             : [a] "r"(a), [b] "r"(b), [c] "r"(c), [d] "r"(*d)
  172|       |             : "cc");
  173|       |
  174|       |         *d = hi;
  175|       |         return lo;
  176|       |      }
  177|       |   }
  178|       |#endif
  179|       |
  180|      0|   typedef typename WordInfo<W>::dword dword;
  181|  20.6k|   const dword s = dword(a) * b + c + *d;
  182|  20.6k|   *d = static_cast<W>(s >> WordInfo<W>::bits);
  183|  20.6k|   return static_cast<W>(s);
  184|  20.6k|}
_ZN5Botan5word3ImEC2Ev:
  478|     38|      constexpr word3() : m_w(0) {}
_ZN5Botan5word3ImE3mulEmm:
  480|  14.5k|      inline constexpr void mul(W x, W y) { m_w += static_cast<W3>(x) * y; }
_ZN5Botan5word3ImE7extractEv:
  486|  1.45k|      inline constexpr W extract() {
  487|  1.45k|         W r = static_cast<W>(m_w);
  488|  1.45k|         m_w >>= WordInfo<W>::bits;
  489|  1.45k|         return r;
  490|  1.45k|      }

_ZNK5Botan14divide_precompImE14divmod_2to1_ctEmm:
  731|  12.1k|      inline constexpr std::pair<W, W> divmod_2to1_ct(W n1, W n0) const {
  732|       |         /*
  733|       |         * Scale the numerator to match the normalized divisor; the scaling cancels
  734|       |         * in the quotient and is removed from the remainder by the final shift.
  735|       |         */
  736|  12.1k|         n1 <<= m_shift;
  737|  12.1k|         const size_t rshift = WordInfo<W>::bits - m_shift;
  738|       |         /*
  739|       |         * We can't just `n0 >> rshift` because m_shift may be 0 (high bit divisor)
  740|       |         * in which case rshift will be the maximum bit length, and >> by the maximum
  741|       |         * bitlength is undefined behavior despite having an entirely obvious meaning.
  742|       |         *
  743|       |         * However we know m_shift is not equal to the bit length of the word, because
  744|       |         * that would imply that the divisor is 0. Thus rshift must be >= 1. So split
  745|       |         * the shift into two phases (first rshift-1, then 1)
  746|       |         */
  747|  12.1k|         n1 |= (n0 >> 1) >> (rshift - 1);
  748|  12.1k|         n0 <<= m_shift;
  749|       |
  750|  12.1k|         const auto [q, scaled_r] = div2by1_preinv(n1, n0, m_norm_divisor, m_reciprocal);
  751|  12.1k|         const W r = scaled_r >> m_shift;
  752|  12.1k|         return std::make_pair(q, r);
  753|  12.1k|      }
_ZN5Botan14divide_precompImE14div2by1_preinvEmmmm:
  782|  12.1k|      static constexpr std::pair<W, W> div2by1_preinv(W u1, W u0, W D, W v) {
  783|       |         // Steps 1-3: <q1,q0> = v*u1; <q1,q0> += <u1,u0>; q1 += 1
  784|  12.1k|         W q1 = u0;
  785|  12.1k|         const W q0 = word_madd2(u1, v, &q1);  // <q1,q0> = u1*v + u0
  786|  12.1k|         q1 += u1 + 1;
  787|       |
  788|       |         // Step 4
  789|  12.1k|         W r = u0 - q1 * D;
  790|       |
  791|       |         // Steps 5-7: If r >= q0 { q1 -= 1; r += d; }
  792|  12.1k|         const auto fix_down = CT::Mask<W>::is_gt(r, q0);
  793|  12.1k|         q1 -= fix_down.if_set_return(1);
  794|  12.1k|         r += fix_down.if_set_return(D);
  795|       |
  796|       |         // Steps 8-10: if r >= D { q1 += 1; r -= D; }
  797|  12.1k|         const auto fix_up = CT::Mask<W>::is_gte(r, D);
  798|  12.1k|         q1 += fix_up.if_set_return(1);
  799|  12.1k|         r -= fix_up.if_set_return(D);
  800|       |
  801|       |         // Step 11
  802|  12.1k|         return std::make_pair(q1, r);
  803|  12.1k|      }
_ZN5Botan18reciprocal_word_ctITkNS_8WordTypeEmEET_S1_:
  649|  1.99k|constexpr W reciprocal_word_ct(W D) {
  650|  1.99k|   BOTAN_DEBUG_ASSERT((D & WordInfo<W>::top_bit) != 0);
  ------------------
  |  |  137|  1.99k|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  138|  1.99k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (138:15): [Folded, False: 1.99k]
  |  |  ------------------
  ------------------
  651|       |
  652|       |   // Bit serial long division of ((~D) || (2^b - 1)) / D, with all of the
  653|       |   // conditional logic computed via masks
  654|  1.99k|   W remainder = static_cast<W>(~D);
  655|  1.99k|   W quotient = 0;
  656|       |
  657|   129k|   for(size_t i = 0; i != WordInfo<W>::bits; ++i) {
  ------------------
  |  Branch (657:22): [True: 127k, False: 1.99k]
  ------------------
  658|   127k|      const auto carry = CT::Mask<W>::expand_top_bit(remainder);
  659|   127k|      remainder = static_cast<W>((remainder << 1) | 1);
  660|   127k|      quotient <<= 1;
  661|       |
  662|   127k|      const auto sub = carry | CT::Mask<W>::is_gte(remainder, D);
  663|   127k|      remainder -= sub.if_set_return(D);
  664|   127k|      quotient |= sub.if_set_return(1);
  665|   127k|   }
  666|       |
  667|  1.99k|   return quotient;
  668|  1.99k|}
_ZN5Botan14divide_precompImE5setupEm:
  694|  1.99k|      static constexpr divide_precomp setup(W divisor) {
  695|  1.99k|         const size_t shift = WordInfo<W>::bits - high_bit(divisor);
  696|  1.99k|         const W norm_divisor = divisor << shift;
  697|  1.99k|         const W reciprocal = reciprocal_word_ct(norm_divisor);
  698|  1.99k|         return divide_precomp(divisor, shift, norm_divisor, reciprocal);
  699|  1.99k|      }
_ZN5Botan11bigint_add2ITkNS_8WordTypeEmEET_PS1_mPKS1_m:
   97|    159|inline constexpr auto bigint_add2(W x[], size_t x_size, const W y[], size_t y_size) -> W {
   98|    159|   W carry = 0;
   99|       |
  100|    159|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   71|    159|   do {                                                                                 \
  |  |   72|    159|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|    159|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 159]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|    159|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 159]
  |  |  ------------------
  ------------------
  101|       |
  102|    159|   const size_t blocks = y_size - (y_size % 8);
  103|       |
  104|    401|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (104:22): [True: 242, False: 159]
  ------------------
  105|    242|      carry = word8_add2(x + i, y + i, carry);
  106|    242|   }
  107|       |
  108|    417|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (108:27): [True: 258, False: 159]
  ------------------
  109|    258|      x[i] = word_add(x[i], y[i], &carry);
  110|    258|   }
  111|       |
  112|  2.14k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (112:27): [True: 1.98k, False: 159]
  ------------------
  113|  1.98k|      x[i] = word_add(x[i], static_cast<W>(0), &carry);
  114|  1.98k|   }
  115|       |
  116|    159|   return carry;
  117|    159|}
_ZN5Botan10bigint_cmpITkNS_8WordTypeEmEEiPKT_mS3_m:
  462|    854|inline constexpr int32_t bigint_cmp(const W x[], size_t x_size, const W y[], size_t y_size) {
  463|    854|   static_assert(sizeof(W) >= sizeof(uint32_t), "Size assumption");
  464|       |
  465|    854|   const W LT = static_cast<W>(-1);
  466|    854|   const W EQ = 0;
  467|    854|   const W GT = 1;
  468|       |
  469|    854|   const size_t common_elems = std::min(x_size, y_size);
  470|       |
  471|    854|   W result = EQ;  // until found otherwise
  472|       |
  473|  5.31k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (473:22): [True: 4.45k, False: 854]
  ------------------
  474|  4.45k|      const auto is_eq = CT::Mask<W>::is_equal(x[i], y[i]);
  475|  4.45k|      const auto is_lt = CT::Mask<W>::is_lt(x[i], y[i]);
  476|       |
  477|  4.45k|      result = is_eq.select(result, is_lt.select(LT, GT));
  478|  4.45k|   }
  479|       |
  480|    854|   if(x_size < y_size) {
  ------------------
  |  Branch (480:7): [True: 0, False: 854]
  ------------------
  481|      0|      W mask = 0;
  482|      0|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (482:30): [True: 0, False: 0]
  ------------------
  483|      0|         mask |= y[i];
  484|      0|      }
  485|       |
  486|       |      // If any bits were set in high part of y, then x < y
  487|      0|      result = CT::Mask<W>::is_zero(mask).select(result, LT);
  488|    854|   } else if(y_size < x_size) {
  ------------------
  |  Branch (488:14): [True: 0, False: 854]
  ------------------
  489|      0|      W mask = 0;
  490|      0|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (490:30): [True: 0, False: 0]
  ------------------
  491|      0|         mask |= x[i];
  492|      0|      }
  493|       |
  494|       |      // If any bits were set in high part of x, then x > y
  495|      0|      result = CT::Mask<W>::is_zero(mask).select(result, GT);
  496|      0|   }
  497|       |
  498|    854|   CT::unpoison(result);
  499|    854|   BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ);
  ------------------
  |  |  137|    854|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  138|    854|      } while(0)
  |  |  ------------------
  |  |  |  Branch (138:15): [Folded, False: 854]
  |  |  ------------------
  ------------------
  500|    854|   return static_cast<int32_t>(result);
  501|    854|}
_ZN5Botan11bigint_sub2ITkNS_8WordTypeEmEET_PS1_mPKS1_m:
  151|    854|inline constexpr auto bigint_sub2(W x[], size_t x_size, const W y[], size_t y_size) -> W {
  152|    854|   W borrow = 0;
  153|       |
  154|    854|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   71|    854|   do {                                                                                 \
  |  |   72|    854|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|    854|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 854]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|    854|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 854]
  |  |  ------------------
  ------------------
  155|       |
  156|    854|   const size_t blocks = y_size - (y_size % 8);
  157|       |
  158|  1.12k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (158:22): [True: 267, False: 854]
  ------------------
  159|    267|      borrow = word8_sub2(x + i, y + i, borrow);
  160|    267|   }
  161|       |
  162|  4.02k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (162:27): [True: 3.17k, False: 854]
  ------------------
  163|  3.17k|      x[i] = word_sub(x[i], y[i], &borrow);
  164|  3.17k|   }
  165|       |
  166|    854|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (166:27): [True: 0, False: 854]
  ------------------
  167|      0|      x[i] = word_sub(x[i], static_cast<W>(0), &borrow);
  168|      0|   }
  169|       |
  170|    854|   return borrow;
  171|    854|}
_ZN5Botan11bigint_sub3ITkNS_8WordTypeEmEET_PS1_PKS1_mS4_m:
  195|  1.70k|inline constexpr auto bigint_sub3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W {
  196|  1.70k|   W borrow = 0;
  197|       |
  198|  1.70k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   71|  1.70k|   do {                                                                                 \
  |  |   72|  1.70k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|  1.70k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 1.70k]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|  1.70k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 1.70k]
  |  |  ------------------
  ------------------
  199|       |
  200|  1.70k|   const size_t blocks = y_size - (y_size % 8);
  201|       |
  202|  2.18k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (202:22): [True: 472, False: 1.70k]
  ------------------
  203|    472|      borrow = word8_sub3(z + i, x + i, y + i, borrow);
  204|    472|   }
  205|       |
  206|  5.13k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (206:27): [True: 3.43k, False: 1.70k]
  ------------------
  207|  3.43k|      z[i] = word_sub(x[i], y[i], &borrow);
  208|  3.43k|   }
  209|       |
  210|  3.41k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (210:27): [True: 1.70k, False: 1.70k]
  ------------------
  211|  1.70k|      z[i] = word_sub(x[i], static_cast<W>(0), &borrow);
  212|  1.70k|   }
  213|       |
  214|  1.70k|   return borrow;
  215|  1.70k|}
_ZN5Botan11bigint_add3ITkNS_8WordTypeEmEET_PS1_PKS1_mS4_m:
  123|     53|inline constexpr auto bigint_add3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W {
  124|     53|   if(x_size < y_size) {
  ------------------
  |  Branch (124:7): [True: 0, False: 53]
  ------------------
  125|      0|      return bigint_add3(z, y, y_size, x, x_size);
  126|      0|   }
  127|       |
  128|     53|   W carry = 0;
  129|       |
  130|     53|   const size_t blocks = y_size - (y_size % 8);
  131|       |
  132|    295|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (132:22): [True: 242, False: 53]
  ------------------
  133|    242|      carry = word8_add3(z + i, x + i, y + i, carry);
  134|    242|   }
  135|       |
  136|    205|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (136:27): [True: 152, False: 53]
  ------------------
  137|    152|      z[i] = word_add(x[i], y[i], &carry);
  138|    152|   }
  139|       |
  140|     53|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (140:27): [True: 0, False: 53]
  ------------------
  141|      0|      z[i] = word_add(x[i], static_cast<W>(0), &carry);
  142|      0|   }
  143|       |
  144|     53|   return carry;
  145|     53|}
_ZN5Botan14bigint_cnd_addITkNS_8WordTypeEmEET_S1_PS1_PKS1_m:
   48|  9.11k|inline constexpr W bigint_cnd_add(W cnd, W x[], const W y[], size_t size) {
   49|  9.11k|   const auto mask = CT::Mask<W>::expand(cnd).value();
   50|       |
   51|  9.11k|   W carry = 0;
   52|       |
   53|   210k|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (53:22): [True: 201k, False: 9.11k]
  ------------------
   54|   201k|      x[i] = word_add(x[i], y[i] & mask, &carry);
   55|   201k|   }
   56|       |
   57|  9.11k|   return (mask & carry);
   58|  9.11k|}
_ZN5Botan14bigint_linmul3ITkNS_8WordTypeEmEEvPT_PKS1_mS1_:
  419|    535|inline constexpr void bigint_linmul3(W z[], const W x[], size_t x_size, W y) {
  420|    535|   const size_t blocks = x_size - (x_size % 8);
  421|       |
  422|    535|   W carry = 0;
  423|       |
  424|    535|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (424:22): [True: 0, False: 535]
  ------------------
  425|      0|      carry = word8_linmul3(z + i, x + i, y, carry);
  426|      0|   }
  427|       |
  428|  1.60k|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (428:27): [True: 1.07k, False: 535]
  ------------------
  429|  1.07k|      z[i] = word_madd2(x[i], y, &carry);
  430|  1.07k|   }
  431|       |
  432|    535|   z[x_size] = carry;
  433|    535|}
_ZN5Botan14divide_precompImE13setup_vartimeEm:
  686|    516|      static constexpr divide_precomp setup_vartime(W divisor) {
  687|    516|         const size_t shift = WordInfo<W>::bits - high_bit(divisor);
  688|    516|         const W norm_divisor = divisor << shift;
  689|    516|         const W reciprocal = reciprocal_word(norm_divisor);
  690|    516|         return divide_precomp(divisor, shift, norm_divisor, reciprocal);
  691|    516|      }
_ZN5Botan15reciprocal_wordITkNS_8WordTypeEmEET_S1_:
  577|    516|constexpr W reciprocal_word(W D) {
  578|    516|   BOTAN_DEBUG_ASSERT((D & WordInfo<W>::top_bit) != 0);
  ------------------
  |  |  137|    516|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  138|    516|      } while(0)
  |  |  ------------------
  |  |  |  Branch (138:15): [Folded, False: 516]
  |  |  ------------------
  ------------------
  579|       |
  580|       |   /*
  581|       |   * Subtracting 2^b*D from the numerator gives
  582|       |   * v = floor(((~D)*2^b + (2^b - 1)) / D). Since D is normalized, ~D < D
  583|       |   * and the quotient fits in a word. See the first part of Section III A
  584|       |   * in the paper.
  585|       |   */
  586|       |   if constexpr(sizeof(W) == 4) {
  587|       |      const auto nD = ~D;  // Work around spurious MSVC warning
  588|       |      const typename WordInfo<W>::dword n =
  589|       |         (static_cast<typename WordInfo<W>::dword>(nD) << WordInfo<W>::bits) | WordInfo<W>::max;
  590|       |      return static_cast<W>(n / D);
  591|    516|   } else {
  592|    516|      if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (592:10): [True: 516, Folded]
  ------------------
  593|    516|#if defined(BOTAN_MP_USE_X86_64_ASM)
  594|    516|         W quotient = 0;
  595|    516|         W remainder = 0;
  596|       |         // NOLINTNEXTLINE(*-no-assembler)
  597|    516|         asm("divq %[d]"
  598|    516|             : "=a"(quotient), "=d"(remainder)
  599|    516|             : [d] "r"(D), "a"(WordInfo<W>::max), "d"(static_cast<W>(~D))
  600|    516|             : "cc");
  601|    516|         return quotient;
  602|       |#elif !defined(BOTAN_BUILD_COMPILER_IS_CLANGCL)
  603|       |         /* clang-cl has a bug where on encountering a 128/64 division it emits
  604|       |         * a call to __udivti3() but then fails to link the relevant builtin into
  605|       |         * the binary, causing a link failure. Work around this by simply omitting
  606|       |         * such code for clang-cl
  607|       |         *
  608|       |         * See https://github.com/llvm/llvm-project/issues/25679
  609|       |         */
  610|       |         if constexpr(WordInfo<W>::dword_is_native) {
  611|       |            typename WordInfo<W>::dword n =
  612|       |               (static_cast<typename WordInfo<W>::dword>(~D) << WordInfo<W>::bits) | WordInfo<W>::max;
  613|       |            return static_cast<W>(n / D);
  614|       |         }
  615|       |#endif
  616|    516|      }
  617|       |
  618|       |      // Algorithm 2 of Möller and Granlund
  619|      0|      const W d0 = D & 1;
  620|      0|      const W d9 = D >> 55;
  621|      0|      const W d40 = (D >> 24) + 1;
  622|      0|      const W d63 = (D >> 1) + d0;  // ceil(D/2)
  623|       |
  624|       |      // This division is done with a table lookup in the paper
  625|      0|      const W v0 = ((W(1) << 19) - (W(3) << 8)) / d9;
  626|      0|      const W v1 = (v0 << 11) - ((v0 * v0 * d40) >> 40) - 1;
  627|      0|      const W v2 = (v1 << 13) + ((v1 * ((W(1) << 60) - v1 * d40)) >> 47);
  628|       |
  629|      0|      const W e = W(0) - v2 * d63 + (v2 >> 1) * d0;
  630|       |
  631|      0|      W product_hi = 0;
  632|      0|      word_madd2(v2, e, &product_hi);
  633|      0|      const W v3 = (v2 << 31) + (product_hi >> 1);
  634|       |
  635|       |      // Compute floor((v3 + 2^64 + 1) * D / 2^64) modulo 2^64
  636|      0|      product_hi = D;
  637|      0|      word_madd2(v3, D, &product_hi);
  638|      0|      return v3 - D - product_hi;
  639|    516|   }
  640|    516|}
_ZN5Botan14divide_precompImEC2Emmmm:
  771|  2.50k|            m_divisor(divisor), m_shift(shift), m_norm_divisor(norm_divisor), m_reciprocal(reciprocal) {}
_ZNK5Botan14divide_precompImE8mod_2to1Emm:
  767|    750|      inline constexpr W mod_2to1(W n1, W n0) const { return this->divmod_2to1_vartime(n1, n0).second; }
_ZNK5Botan14divide_precompImE19divmod_2to1_vartimeEmm:
  709|    750|      inline constexpr std::pair<W, W> divmod_2to1_vartime(W n1, W n0) const {
  710|    750|         if(m_divisor == WordInfo<W>::max) {
  ------------------
  |  Branch (710:13): [True: 31, False: 719]
  ------------------
  711|     31|            const W q = div_2to1_max_d(n1, n0);
  712|     31|            const W r = static_cast<W>(n0 + q);
  713|     31|            return std::make_pair(q, r);
  714|     31|         }
  715|       |
  716|    719|         if(m_divisor == WordInfo<W>::top_bit) {
  ------------------
  |  Branch (716:13): [True: 0, False: 719]
  ------------------
  717|       |            // Simply a shift by N-1 bits
  718|      0|            const W q = (n1 << 1) | (n0 >> (WordInfo<W>::bits - 1));
  719|      0|            const W r = static_cast<W>(n0 & (WordInfo<W>::top_bit - 1));
  720|      0|            return std::make_pair(q, r);
  721|      0|         }
  722|       |
  723|    719|         return divmod_2to1_ct(n1, n0);
  724|    719|      }
_ZN5Botan14divide_precompImE14div_2to1_max_dEmm:
  809|     31|      static inline constexpr W div_2to1_max_d(W n1, W n0) {
  810|       |         /*
  811|       |         Use k to refer to WordInfo<W>::bits
  812|       |
  813|       |         We are dividing n = (n1 * 2^k) + n0 by 2^k - 1
  814|       |
  815|       |         Recall that 2^k = 1 (mod 2^k - 1)
  816|       |
  817|       |         Rewrite n = n1*2^k + n0 as n1*(2^k - 1) + n1 + n0
  818|       |
  819|       |         The result of dividing n by (2^k - 1) will be equal to
  820|       |         (n1*(2^k-1) + n1 + n0) / (2^k-1) =
  821|       |         n1 + ((n1 + n0) / (2^k-1)
  822|       |
  823|       |         Use c to refer to ((n1 + n0) / (2^k-1))
  824|       |
  825|       |         If (n1 + n0) < (2^k - 1) then c is 0
  826|       |         If (n1 + n0) >= (2^k - 1) then c is 1
  827|       |
  828|       |         Since n1 < 2^k - 1 [*] and n0 <= 2^k - 1 it is impossible for (n1 + n0) / (2^k -1)
  829|       |         to be greater than 1.
  830|       |
  831|       |         [*] We require n1 be strictly less than the divisor to ensure that the
  832|       |         output fits in a single word; this is checked at the start of divmod_2to1.
  833|       |
  834|       |         And since n1 + 1 <= 2^k - 1, c == 1 exactly when n0 + (n1 + 1) carries out.
  835|       |         */
  836|       |
  837|     31|         const W s = n0 + n1 + 1;
  838|     31|         const W c = CT::Mask<W>::is_lt(s, n0).if_set_return(1);
  839|     31|         return n1 + c;
  840|     31|      }
_ZN5Botan15bigint_ct_is_eqITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPKS3_mS6_m:
  542|  1.70k|inline constexpr auto bigint_ct_is_eq(const W x[], size_t x_size, const W y[], size_t y_size) -> CT::Mask<W> {
  543|  1.70k|   const size_t common_elems = std::min(x_size, y_size);
  544|       |
  545|  1.70k|   W diff = 0;
  546|       |
  547|  12.3k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (547:22): [True: 10.6k, False: 1.70k]
  ------------------
  548|  10.6k|      diff |= (x[i] ^ y[i]);
  549|  10.6k|   }
  550|       |
  551|       |   // If any bits were set in high part of x/y, then they are not equal
  552|  1.70k|   if(x_size < y_size) {
  ------------------
  |  Branch (552:7): [True: 339, False: 1.36k]
  ------------------
  553|  4.55k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (553:30): [True: 4.21k, False: 339]
  ------------------
  554|  4.21k|         diff |= y[i];
  555|  4.21k|      }
  556|  1.36k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (556:14): [True: 1.04k, False: 321]
  ------------------
  557|  6.17k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (557:30): [True: 5.12k, False: 1.04k]
  ------------------
  558|  5.12k|         diff |= x[i];
  559|  5.12k|      }
  560|  1.04k|   }
  561|       |
  562|  1.70k|   return CT::Mask<W>::is_zero(diff);
  563|  1.70k|}
_ZN5Botan15bigint_ct_is_ltITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPKS3_mS6_mb:
  510|    854|   -> CT::Mask<W> {
  511|    854|   const size_t common_elems = std::min(x_size, y_size);
  512|       |
  513|    854|   auto is_lt = CT::Mask<W>::expand(lt_or_equal);
  514|       |
  515|  9.71k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (515:22): [True: 8.85k, False: 854]
  ------------------
  516|  8.85k|      const auto eq = CT::Mask<W>::is_equal(x[i], y[i]);
  517|  8.85k|      const auto lt = CT::Mask<W>::is_lt(x[i], y[i]);
  518|  8.85k|      is_lt = eq.select_mask(is_lt, lt);
  519|  8.85k|   }
  520|       |
  521|    854|   if(x_size < y_size) {
  ------------------
  |  Branch (521:7): [True: 0, False: 854]
  ------------------
  522|      0|      W mask = 0;
  523|      0|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (523:30): [True: 0, False: 0]
  ------------------
  524|      0|         mask |= y[i];
  525|      0|      }
  526|       |      // If any bits were set in high part of y, then is_lt should be forced true
  527|      0|      is_lt |= CT::Mask<W>::expand(mask);
  528|    854|   } else if(y_size < x_size) {
  ------------------
  |  Branch (528:14): [True: 230, False: 624]
  ------------------
  529|    230|      W mask = 0;
  530|  3.60k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (530:30): [True: 3.37k, False: 230]
  ------------------
  531|  3.37k|         mask |= x[i];
  532|  3.37k|      }
  533|       |
  534|       |      // If any bits were set in high part of x, then is_lt should be false
  535|    230|      is_lt &= CT::Mask<W>::is_zero(mask);
  536|    230|   }
  537|       |
  538|    854|   return is_lt;
  539|    854|}
_ZN5Botan13bigint_submulITkNS_8WordTypeEmEET_PS1_PKS1_mS1_:
  442|  9.06k|inline constexpr auto bigint_submul(W z[], const W y[], size_t N, W q) -> W {
  443|  9.06k|   W mul_carry = 0;
  444|  9.06k|   W borrow = 0;
  445|       |
  446|   207k|   for(size_t i = 0; i != N; ++i) {
  ------------------
  |  Branch (446:22): [True: 198k, False: 9.06k]
  ------------------
  447|   198k|      const W t = word_madd2(y[i], q, &mul_carry);
  448|   198k|      z[i] = word_sub(z[i], t, &borrow);
  449|   198k|   }
  450|       |
  451|       |   // Both mul_carry <= W_max - 1 and borrow <= 1, so this cannot overflow
  452|  9.06k|   return mul_carry + borrow;
  453|  9.06k|}
_ZN5Botan14bigint_sub_absITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPS3_PKS3_S7_mS5_:
  282|    960|inline constexpr auto bigint_sub_abs(W z[], const W x[], const W y[], size_t N, W ws[]) -> CT::Mask<W> {
  283|       |   // Subtract in both direction then conditional copy out the result
  284|       |
  285|    960|   W* ws0 = ws;
  286|    960|   W* ws1 = ws + N;
  287|       |
  288|    960|   W borrow0 = 0;
  289|    960|   W borrow1 = 0;
  290|       |
  291|    960|   const size_t blocks = N - (N % 8);
  292|       |
  293|  1.42k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (293:22): [True: 462, False: 960]
  ------------------
  294|    462|      borrow0 = word8_sub3(ws0 + i, x + i, y + i, borrow0);
  295|    462|      borrow1 = word8_sub3(ws1 + i, y + i, x + i, borrow1);
  296|    462|   }
  297|       |
  298|  3.80k|   for(size_t i = blocks; i != N; ++i) {
  ------------------
  |  Branch (298:27): [True: 2.84k, False: 960]
  ------------------
  299|  2.84k|      ws0[i] = word_sub(x[i], y[i], &borrow0);
  300|  2.84k|      ws1[i] = word_sub(y[i], x[i], &borrow1);
  301|  2.84k|   }
  302|       |
  303|    960|   return CT::conditional_copy_mem(borrow0, z, ws1, ws0, N);
  304|    960|}
_ZN5Botan14bigint_cnd_subITkNS_8WordTypeEmEET_S1_PS1_PKS1_m:
   65|     53|inline constexpr auto bigint_cnd_sub(W cnd, W x[], const W y[], size_t size) -> W {
   66|     53|   const auto mask = CT::Mask<W>::expand(cnd).value();
   67|       |
   68|     53|   W carry = 0;
   69|       |
   70|  3.18k|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (70:22): [True: 3.13k, False: 53]
  ------------------
   71|  3.13k|      x[i] = word_sub(x[i], y[i] & mask, &carry);
   72|  3.13k|   }
   73|       |
   74|     53|   return (mask & carry);
   75|     53|}

_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEmQntsr3stdE7same_asIbT_EEES3_S3_:
   43|  1.70M|constexpr inline T value_barrier(T x) {
   44|  1.70M|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 1.70M]
  ------------------
   45|      0|      return x;
   46|  1.70M|   } else {
   47|  1.70M|#if defined(BOTAN_CT_VALUE_BARRIER_USE_ASM)
   48|       |      /*
   49|       |      * We may want a "stronger" statement such as
   50|       |      *     asm volatile("" : "+r,m"(x) : : "memory);
   51|       |      * (see https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html)
   52|       |      * however the current approach seems sufficient with current compilers,
   53|       |      * and is minimally damaging with regards to degrading code generation.
   54|       |      */
   55|  1.70M|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|  1.70M|      return x;
   57|       |#elif defined(BOTAN_CT_VALUE_BARRIER_USE_VOLATILE)
   58|       |      volatile T vx = x;
   59|       |      return vx;
   60|       |#else
   61|       |      return x;
   62|       |#endif
   63|  1.70M|   }
   64|  1.70M|}
_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEhQntsr3stdE7same_asIbT_EEES3_S3_:
   43|  1.45k|constexpr inline T value_barrier(T x) {
   44|  1.45k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 1.45k]
  ------------------
   45|      0|      return x;
   46|  1.45k|   } else {
   47|  1.45k|#if defined(BOTAN_CT_VALUE_BARRIER_USE_ASM)
   48|       |      /*
   49|       |      * We may want a "stronger" statement such as
   50|       |      *     asm volatile("" : "+r,m"(x) : : "memory);
   51|       |      * (see https://theunixzoo.co.uk/blog/2021-10-14-preventing-optimisations.html)
   52|       |      * however the current approach seems sufficient with current compilers,
   53|       |      * and is minimally damaging with regards to degrading code generation.
   54|       |      */
   55|  1.45k|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|  1.45k|      return x;
   57|       |#elif defined(BOTAN_CT_VALUE_BARRIER_USE_VOLATILE)
   58|       |      volatile T vx = x;
   59|       |      return vx;
   60|       |#else
   61|       |      return x;
   62|       |#endif
   63|  1.45k|   }
   64|  1.45k|}

_ZN5Botan13ignore_paramsIJPKmmEEEvDpRKT_:
  149|  26.4k|constexpr void ignore_params([[maybe_unused]] const T&... args) {}

_ZNK5Botan6BigInt7is_zeroEv:
  510|  2.01k|      bool is_zero() const { return sig_words() == 0; }
_ZNK5Botan6BigInt9sig_wordsEv:
  687|  24.5k|      size_t sig_words() const { return m_data.sig_words(); }
_ZNK5Botan6BigInt4Data9sig_wordsEv:
 1163|  24.5k|            size_t sig_words() const {
 1164|  24.5k|               if(m_sig_words == sig_words_npos) {
  ------------------
  |  Branch (1164:19): [True: 3.46k, False: 21.0k]
  ------------------
 1165|  3.46k|                  m_sig_words = calc_sig_words();
 1166|  3.46k|               }
 1167|  24.5k|               return m_sig_words;
 1168|  24.5k|            }
_ZN5BotanneERKNS_6BigIntES2_:
 1323|  1.70k|inline bool operator!=(const BigInt& a, const BigInt& b) {
 1324|  1.70k|   return !a.is_equal(b);
 1325|  1.70k|}
_ZN5Botan6BigIntD2Ev:
  185|  14.4k|      ~BigInt() { _const_time_unpoison(); }
_ZN5Botan6BigInt4zeroEv:
   50|     24|      static BigInt zero() { return BigInt(); }
_ZN5Botan6BigIntC2EOS0_:
  183|    870|      BigInt(BigInt&& other) noexcept { this->swap(other); }
_ZN5Botan6BigIntaSEOS0_:
  190|  4.60k|      BigInt& operator=(BigInt&& other) noexcept {
  191|  4.60k|         if(this != &other) {
  ------------------
  |  Branch (191:13): [True: 4.60k, False: 0]
  ------------------
  192|  4.60k|            this->swap(other);
  193|  4.60k|         }
  194|       |
  195|  4.60k|         return (*this);
  196|  4.60k|      }
_ZN5Botan6BigInt4swapERS0_:
  207|  5.47k|      void swap(BigInt& other) noexcept {
  208|  5.47k|         m_data.swap(other.m_data);
  209|  5.47k|         std::swap(m_signedness, other.m_signedness);
  210|  5.47k|      }
_ZN5Botan6BigInt5clearEv:
  441|  1.74k|      void clear() {
  442|  1.74k|         m_data.set_to_zero();
  443|  1.74k|         m_signedness = Positive;
  444|  1.74k|      }
_ZNK5Botan6BigInt6signumEv:
  493|  11.9k|      int signum() const {
  494|  11.9k|         if(sig_words() == 0) {
  ------------------
  |  Branch (494:13): [True: 50, False: 11.9k]
  ------------------
  495|     50|            return 0;
  496|     50|         }
  497|  11.9k|         return (sign() == Negative) ? -1 : 1;
  ------------------
  |  Branch (497:17): [True: 0, False: 11.9k]
  ------------------
  498|  11.9k|      }
_ZN5Botan6BigInt7set_bitEm:
  516|    870|      void set_bit(size_t n) { conditionally_set_bit(n, true); }
_ZN5Botan6BigInt21conditionally_set_bitEmb:
  526|    870|      void conditionally_set_bit(size_t n, bool set_it) {
  527|    870|         const size_t which = n / (sizeof(word) * 8);
  528|    870|         const word mask = static_cast<word>(set_it) << (n % (sizeof(word) * 8));
  529|    870|         m_data.set_word_at(which, word_at(which) | mask);
  530|    870|      }
_ZNK5Botan6BigInt7word_atEm:
  601|  3.02k|      word word_at(size_t n) const { return m_data.get_word_at(n); }
_ZN5Botan6BigInt11set_word_atEmm:
  608|    529|      BOTAN_DEPRECATED("Deprecated no replacement") void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
_ZNK5Botan6BigInt4signEv:
  641|  16.7k|      Sign sign() const { return (m_signedness); }
_ZN5Botan6BigInt8set_signENS0_4SignE:
  663|    314|      void set_sign(Sign sign) {
  664|    314|         if(sign == Negative && is_zero()) {
  ------------------
  |  Branch (664:13): [True: 0, False: 314]
  |  Branch (664:33): [True: 0, False: 0]
  ------------------
  665|      0|            sign = Positive;
  666|      0|         }
  667|       |
  668|    314|         m_signedness = sign;
  669|    314|      }
_ZNK5Botan6BigInt4sizeEv:
  681|  6.83k|      size_t size() const { return m_data.size(); }
_ZNK5Botan6BigInt7grow_toEm:
  738|  2.59k|      BOTAN_DEPRECATED("Deprecated no replacement") void grow_to(size_t n) const { m_data.grow_to(n); }
_ZN5Botan6BigInt10power_of_2Em:
  906|    870|      static BigInt power_of_2(size_t n) {
  907|    870|         BigInt b;
  908|    870|         b.set_bit(n);
  909|    870|         return b;
  910|    870|      }
_ZNK5Botan6BigInt8_as_spanEv:
 1023|    854|      std::span<const word> _as_span() const { return m_data.const_span(); }
_ZNK5Botan6BigInt5_dataEv:
 1033|  39.7k|      const word* _data() const { return m_data.const_data(); }
_ZN5Botan6BigInt11_from_wordsERNSt3__16vectorImNS_16secure_allocatorImEEEE:
 1052|  4.83k|      static BigInt _from_words(secure_vector<word>& words) {
 1053|  4.83k|         BigInt bn;
 1054|  4.83k|         bn.m_data.swap(words);
 1055|  4.83k|         return bn;
 1056|  4.83k|      }
_ZNK5Botan6BigInt4Data10const_dataEv:
 1088|  54.1k|            const word* const_data() const { return m_reg.data(); }
_ZNK5Botan6BigInt4Data10const_spanEv:
 1090|    854|            std::span<const word> const_span() const { return std::span{m_reg}; }
_ZNK5Botan6BigInt4Data11get_word_atEm:
 1099|  3.02k|            word get_word_at(size_t n) const {
 1100|  3.02k|               if(n < m_reg.size()) {
  ------------------
  |  Branch (1100:19): [True: 2.15k, False: 870]
  ------------------
 1101|  2.15k|                  return m_reg[n];
 1102|  2.15k|               }
 1103|    870|               return 0;
 1104|  3.02k|            }
_ZN5Botan6BigInt4Data11set_word_atEmm:
 1106|  1.39k|            void set_word_at(size_t i, word w) {
 1107|  1.39k|               invalidate_sig_words();
 1108|  1.39k|               if(i >= m_reg.size()) {
  ------------------
  |  Branch (1108:19): [True: 1.39k, False: 0]
  ------------------
 1109|  1.39k|                  if(w == 0) {
  ------------------
  |  Branch (1109:22): [True: 22, False: 1.37k]
  ------------------
 1110|     22|                     return;
 1111|     22|                  }
 1112|  1.37k|                  grow_to(i + 1);
 1113|  1.37k|               }
 1114|  1.37k|               m_reg[i] = w;
 1115|  1.37k|            }
_ZNK5Botan6BigInt4Data7grow_toEm:
 1126|  3.97k|            void grow_to(size_t n) const {
 1127|  3.97k|               if(n > size()) {
  ------------------
  |  Branch (1127:19): [True: 3.11k, False: 858]
  ------------------
 1128|  3.11k|                  if(n <= m_reg.capacity()) {
  ------------------
  |  Branch (1128:22): [True: 0, False: 3.11k]
  ------------------
 1129|      0|                     m_reg.resize(n);
 1130|  3.11k|                  } else {
 1131|  3.11k|                     m_reg.resize(n + (8 - (n % 8)));
 1132|  3.11k|                  }
 1133|  3.11k|               }
 1134|  3.97k|            }
_ZNK5Botan6BigInt4Data4sizeEv:
 1136|  25.2k|            size_t size() const { return m_reg.size(); }
_ZN5Botan6BigInt4Data4swapERS1_:
 1151|  5.47k|            void swap(Data& other) noexcept {
 1152|  5.47k|               m_reg.swap(other.m_reg);
 1153|  5.47k|               std::swap(m_sig_words, other.m_sig_words);
 1154|  5.47k|            }
_ZN5Botan6BigInt4Data4swapERNSt3__16vectorImNS_16secure_allocatorImEEEE:
 1156|  6.57k|            void swap(secure_vector<word>& reg) noexcept {
 1157|  6.57k|               m_reg.swap(reg);
 1158|  6.57k|               invalidate_sig_words();
 1159|  6.57k|            }
_ZNK5Botan6BigInt4Data20invalidate_sig_wordsEv:
 1161|  7.97k|            void invalidate_sig_words() const noexcept { m_sig_words = sig_words_npos; }
_ZN5BotanltERKNS_6BigIntES2_:
 1353|    854|inline bool operator<(const BigInt& a, const BigInt& b) {
 1354|    854|   return a.is_less_than(b);
 1355|    854|}
_ZN5Botan6BigIntC2ERKS0_:
   88|    929|      BigInt(const BigInt& other) = default;
_ZN5Botan6BigIntC2Ev:
   45|  12.6k|      BigInt() = default;

_ZN5Botan11clear_bytesEPvm:
  101|  3.45k|inline constexpr void clear_bytes(void* ptr, size_t bytes) {
  102|  3.45k|   if(bytes > 0) {
  ------------------
  |  Branch (102:7): [True: 1.71k, False: 1.74k]
  ------------------
  103|  1.71k|      std::memset(ptr, 0, bytes);
  104|  1.71k|   }
  105|  3.45k|}
_ZN5Botan9clear_memImEEvPT_m:
  118|  2.59k|inline constexpr void clear_mem(T* ptr, size_t n) {
  119|  2.59k|   clear_bytes(ptr, sizeof(T) * n);
  120|  2.59k|}
_ZN5Botan8copy_memImQsr3stdE12is_trivial_vIu7__decayIT_EEEEvPS1_PKS1_m:
  144|    864|inline constexpr void copy_mem(T* out, const T* in, size_t n) {
  145|    864|   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
  ------------------
  |  |  110|    864|   do {                                                                                          \
  |  |  111|    864|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                              \
  |  |  112|  1.72k|      if((expr1) && !(expr2)) {                                                                  \
  |  |  ------------------
  |  |  |  Branch (112:10): [True: 864, False: 0]
  |  |  |  Branch (112:23): [True: 864, False: 0]
  |  |  |  Branch (112:23): [True: 864, False: 0]
  |  |  ------------------
  |  |  113|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                                     \
  |  |  114|      0|         Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, __LINE__); \
  |  |  115|      0|      }                                                                                          \
  |  |  116|    864|   } while(0)
  |  |  ------------------
  |  |  |  Branch (116:12): [Folded, False: 864]
  |  |  ------------------
  ------------------
  146|       |
  147|    864|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (147:7): [True: 864, False: 0]
  |  Branch (147:24): [True: 864, False: 0]
  |  Branch (147:42): [True: 864, False: 0]
  ------------------
  148|    864|      std::memmove(out, in, sizeof(T) * n);
  149|    864|   }
  150|    864|}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeENSt3__14spanIKhLm8EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS6_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEEES6_RKSB_:
  210|  10.2k|inline constexpr ToT typecast_copy(const FromR& src) {
  211|  10.2k|   ToT dst;  // NOLINT(*-member-init)
  212|  10.2k|   typecast_copy(dst, src);
  213|  10.2k|   return dst;
  214|  10.2k|}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeENSt3__14spanIKhLm8EEEQaaaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISD_EESE_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIT_Entsr3std6rangesE5rangeISK_EEEvRSK_RKSA_:
  188|  10.2k|inline constexpr void typecast_copy(ToT& out, const FromR& in) {
  189|  10.2k|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|  10.2k|}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanImLm1EEETkNS1_16contiguous_rangeENS3_IKhLm8EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS7_IXsr21__is_primary_templateINS8_Iu14__remove_cvrefIDTclL_ZNSA_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSG_ISO_EESP_E4type10value_typeEEEEvOSL_RKSB_:
  176|  10.2k|inline constexpr void typecast_copy(ToR&& out /* NOLINT(*-std-forward) */, const FromR& in) {
  177|  10.2k|   ranges::assert_equal_byte_lengths(out, in);
  178|  10.2k|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|  10.2k|}
_ZN5Botan8copy_memITkNS_6ranges23contiguous_output_rangeENSt3__14spanIhLm18446744073709551615EEETkNS1_16contiguous_rangeENS3_IKhLm18446744073709551615EEEQaasr3stdE9is_same_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeENS7_IXsr21__is_primary_templateINS8_Iu14__remove_cvrefIDTclL_ZNSA_5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENSG_ISO_EESP_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIST_EEEvOSB_RKSL_:
  160|  1.21k|inline constexpr void copy_mem(OutR&& out /* NOLINT(*-std-forward) */, const InR& in) {
  161|  1.21k|   ranges::assert_equal_byte_lengths(out, in);
  162|  1.21k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (162:7): [Folded, False: 1.21k]
  ------------------
  163|      0|      std::copy(std::ranges::begin(in), std::ranges::end(in), std::ranges::begin(out));
  164|  1.21k|   } else if(ranges::size_bytes(out) > 0) {
  ------------------
  |  Branch (164:14): [True: 1.21k, False: 0]
  ------------------
  165|  1.21k|      std::memmove(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  166|  1.21k|   }
  167|  1.21k|}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeENSt3__14spanIhLm8EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS5_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISD_EESE_E4type10value_typeEEEES5_RKSA_:
  210|  1.21k|inline constexpr ToT typecast_copy(const FromR& src) {
  211|  1.21k|   ToT dst;  // NOLINT(*-member-init)
  212|  1.21k|   typecast_copy(dst, src);
  213|  1.21k|   return dst;
  214|  1.21k|}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeENSt3__14spanIhLm8EEEQaaaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISC_EESD_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIT_Entsr3std6rangesE5rangeISJ_EEEvRSJ_RKS9_:
  188|  1.21k|inline constexpr void typecast_copy(ToT& out, const FromR& in) {
  189|  1.21k|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|  1.21k|}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanImLm1EEETkNS1_16contiguous_rangeENS3_IhLm8EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISD_EESE_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS6_IXsr21__is_primary_templateINS7_Iu14__remove_cvrefIDTclL_ZNS9_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSF_ISN_EESO_E4type10value_typeEEEEvOSK_RKSA_:
  176|  1.21k|inline constexpr void typecast_copy(ToR&& out /* NOLINT(*-std-forward) */, const FromR& in) {
  177|  1.21k|   ranges::assert_equal_byte_lengths(out, in);
  178|  1.21k|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|  1.21k|}
_ZN5Botan9clear_memITkNS_6ranges23contiguous_output_rangeENSt3__14spanImLm18446744073709551615EEEEEvOT_Qsr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRS5_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISD_EESE_E4type10value_typeEE:
  132|    854|{
  133|    854|   clear_bytes(std::ranges::data(mem), ranges::size_bytes(mem));
  134|    854|}
_ZN5Botan9clear_memIjEEvPT_m:
  118|      6|inline constexpr void clear_mem(T* ptr, size_t n) {
  119|      6|   clear_bytes(ptr, sizeof(T) * n);
  120|      6|}

_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeENSt3__14spanIhLm18446744073709551615EEETpTkNS0_14spanable_rangeEJNS3_IKhLm18446744073709551615EEEEEEvRKT_DpRKT0_QgtsZT0_Li0E:
  100|  1.21k|{
  101|  1.21k|   const std::span s0{r0};
  102|       |
  103|       |   if constexpr(statically_spanable_range<R0>) {
  104|       |      constexpr size_t expected_size = s0.size_bytes();
  105|       |      (assert_exact_byte_length<expected_size>(rs), ...);
  106|  1.21k|   } else {
  107|  1.21k|      const size_t expected_size = s0.size_bytes();
  108|  1.21k|      const bool correct_size =
  109|  1.21k|         ((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...);
  110|       |
  111|  1.21k|      if(!correct_size) {
  ------------------
  |  Branch (111:10): [True: 0, False: 1.21k]
  ------------------
  112|      0|         memory_region_size_violation();
  113|      0|      }
  114|  1.21k|   }
  115|  1.21k|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeENSt3__14spanIhLm8EEEEEvRKT0_:
   77|  1.21k|inline constexpr void assert_exact_byte_length(const R& r) {
   78|  1.21k|   const std::span s{r};
   79|  1.21k|   if constexpr(statically_spanable_range<R>) {
   80|  1.21k|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   81|       |   } else {
   82|       |      if(s.size_bytes() != expected) {
   83|       |         memory_region_size_violation();
   84|       |      }
   85|       |   }
   86|  1.21k|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeENSt3__14spanIKhLm8EEEEEvRKT0_:
   77|  20.4k|inline constexpr void assert_exact_byte_length(const R& r) {
   78|  20.4k|   const std::span s{r};
   79|  20.4k|   if constexpr(statically_spanable_range<R>) {
   80|  20.4k|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   81|       |   } else {
   82|       |      if(s.size_bytes() != expected) {
   83|       |         memory_region_size_violation();
   84|       |      }
   85|       |   }
   86|  20.4k|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeENSt3__14spanImLm1EEETpTkNS0_14spanable_rangeEJNS3_IKhLm8EEEEEEvRKT_DpRKT0_QgtsZT0_Li0E:
  100|  10.2k|{
  101|  10.2k|   const std::span s0{r0};
  102|       |
  103|  10.2k|   if constexpr(statically_spanable_range<R0>) {
  104|  10.2k|      constexpr size_t expected_size = s0.size_bytes();
  105|  10.2k|      (assert_exact_byte_length<expected_size>(rs), ...);
  106|       |   } else {
  107|       |      const size_t expected_size = s0.size_bytes();
  108|       |      const bool correct_size =
  109|       |         ((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...);
  110|       |
  111|       |      if(!correct_size) {
  112|       |         memory_region_size_violation();
  113|       |      }
  114|       |   }
  115|  10.2k|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeENSt3__14spanImLm1EEEEEmRKT_:
   59|  11.4k|inline constexpr size_t size_bytes(const spanable_range auto& r) {
   60|  11.4k|   return std::span{r}.size_bytes();
   61|  11.4k|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeENSt3__14spanIhLm18446744073709551615EEEEEmRKT_:
   59|  2.43k|inline constexpr size_t size_bytes(const spanable_range auto& r) {
   60|  2.43k|   return std::span{r}.size_bytes();
   61|  2.43k|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeENSt3__15arrayIhLm8EEEEEvRKT0_:
   77|  1.21k|inline constexpr void assert_exact_byte_length(const R& r) {
   78|  1.21k|   const std::span s{r};
   79|  1.21k|   if constexpr(statically_spanable_range<R>) {
   80|  1.21k|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
   81|       |   } else {
   82|       |      if(s.size_bytes() != expected) {
   83|       |         memory_region_size_violation();
   84|       |      }
   85|       |   }
   86|  1.21k|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeENSt3__14spanImLm1EEETpTkNS0_14spanable_rangeEJNS3_IhLm8EEEEEEvRKT_DpRKT0_QgtsZT0_Li0E:
  100|  1.21k|{
  101|  1.21k|   const std::span s0{r0};
  102|       |
  103|  1.21k|   if constexpr(statically_spanable_range<R0>) {
  104|  1.21k|      constexpr size_t expected_size = s0.size_bytes();
  105|  1.21k|      (assert_exact_byte_length<expected_size>(rs), ...);
  106|       |   } else {
  107|       |      const size_t expected_size = s0.size_bytes();
  108|       |      const bool correct_size =
  109|       |         ((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...);
  110|       |
  111|       |      if(!correct_size) {
  112|       |         memory_region_size_violation();
  113|       |      }
  114|       |   }
  115|  1.21k|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeENSt3__14spanImLm18446744073709551615EEEEEmRKT_:
   59|    854|inline constexpr size_t size_bytes(const spanable_range auto& r) {
   60|    854|   return std::span{r}.size_bytes();
   61|    854|}

_ZN5Botan16secure_allocatorImE10deallocateEPmm:
  102|  14.3k|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorImE8allocateEm:
   95|  14.3k|      T* allocate(std::size_t n) { return static_cast<T*>(allocate_memory(n, sizeof(T))); }

_ZN5Botan16wrap_strong_typeImRmQoosr3stdE18constructible_fromIT_T0_Eaasr8conceptsE11strong_typeIS2_Esr3stdE18constructible_fromINS2_12wrapped_typeES3_EEEDcOS3_:
  144|  11.4k|[[nodiscard]] constexpr decltype(auto) wrap_strong_type(ParamT&& t) {
  145|  11.4k|   if constexpr(std::same_as<std::remove_cvref_t<ParamT>, T>) {
  146|       |      // Noop, if the parameter type already is the desired return type.
  147|  11.4k|      return std::forward<ParamT>(t);
  148|       |   } else if constexpr(std::constructible_from<T, ParamT>) {
  149|       |      // Implicit conversion from the parameter type to the return type.
  150|       |      return T{std::forward<ParamT>(t)};
  151|       |   } else {
  152|       |      // Explicitly calling the wrapped type's constructor to support
  153|       |      // implicit conversions on types that mark their constructors as explicit.
  154|       |      static_assert(concepts::strong_type<T> && std::constructible_from<typename T::wrapped_type, ParamT>);
  155|       |      return T{typename T::wrapped_type{std::forward<ParamT>(t)}};
  156|       |   }
  157|  11.4k|}

_Z4fuzzNSt3__14spanIKhLm18446744073709551615EEE:
   13|    893|void fuzz(std::span<const uint8_t> in) {
   14|    893|   static const size_t max_bits = 4096;
   15|       |
   16|    893|   if(in.size() <= 4) {
  ------------------
  |  Branch (16:7): [True: 4, False: 889]
  ------------------
   17|      4|      return;
   18|      4|   }
   19|       |
   20|    889|   if(in.size() > 2 * (max_bits / 8)) {
  ------------------
  |  Branch (20:7): [True: 17, False: 872]
  ------------------
   21|     17|      return;
   22|     17|   }
   23|       |
   24|    872|   const size_t x_len = 2 * in.size() / 3;
   25|       |
   26|    872|   const Botan::BigInt x = Botan::BigInt::from_bytes(in.subspan(0, x_len));
   27|    872|   const Botan::BigInt p = Botan::BigInt::from_bytes(in.subspan(x_len, in.size() - x_len));
   28|       |
   29|    872|   if(p.is_zero()) {
  ------------------
  |  Branch (29:7): [True: 2, False: 870]
  ------------------
   30|      2|      return;
   31|      2|   }
   32|       |
   33|    870|   try {
   34|    870|      const auto mod_p = Botan::Barrett_Reduction::for_public_modulus(p);
   35|    870|      const Botan::BigInt z = mod_p.reduce(x);
   36|       |
   37|    870|      const Botan::BigInt ref = x % p;
   38|    870|      const Botan::BigInt ct = ct_modulo(x, p);
   39|       |
   40|    870|      if(ref != z || ref != ct) {
  ------------------
  |  Branch (40:10): [True: 16, False: 854]
  |  Branch (40:22): [True: 0, False: 854]
  ------------------
   41|      0|         FUZZER_WRITE_AND_CRASH("X = " << x.to_hex_string() << "\n"
  ------------------
  |  |   70|      0|   do {                                                                                                       \
  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |   72|      0|      abort();                                                                                                \
  |  |   73|      0|   } while(0)
  |  |  ------------------
  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
   42|      0|                                       << "P = " << p.to_hex_string() << "\n"
   43|      0|                                       << "Barrett = " << z.to_hex_string() << "\n"
   44|      0|                                       << "Ct = " << ct.to_hex_string() << "\n"
   45|      0|                                       << "Ref = " << ref.to_hex_string() << "\n");
   46|      0|      }
   47|    870|   } catch(const Botan::Invalid_Argument&) {}
   48|    870|}

LLVMFuzzerInitialize:
   28|      2|extern "C" int LLVMFuzzerInitialize(int* /*argc*/, char*** /*argv*/) {
   29|       |   /*
   30|       |   * This disables the mlock pool, as overwrites within the pool are
   31|       |   * opaque to ASan or other instrumentation.
   32|       |   */
   33|      2|   ::setenv("BOTAN_MLOCK_POOL_SIZE", "0", 1);
   34|      2|   return 0;
   35|      2|}
LLVMFuzzerTestOneInput:
   39|    902|extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) {
   40|    902|   if(len <= max_fuzzer_input_size) {
  ------------------
  |  Branch (40:7): [True: 893, False: 9]
  ------------------
   41|    893|      try {
   42|    893|         fuzz(std::span<const uint8_t>(in, len));
   43|    893|      } catch(const std::exception& e) {
   44|      0|         std::cerr << "Uncaught exception from fuzzer driver " << e.what() << "\n";
   45|      0|         abort();
   46|      0|      } catch(...) {
   47|      0|         std::cerr << "Uncaught exception from fuzzer driver (unknown type)\n";
   48|      0|         abort();
   49|      0|      }
   50|    893|   }
   51|    902|   return 0;
   52|    902|}

_ZN5BotanrmERKNS_6BigIntES2_:
  134|    854|BigInt operator%(const BigInt& n, const BigInt& mod) {
  135|    854|   if(mod.is_zero()) {
  ------------------
  |  Branch (135:7): [True: 0, False: 854]
  ------------------
  136|      0|      throw Invalid_Argument("BigInt::operator% divide by zero");
  137|      0|   }
  138|    854|   if(mod.signum() < 0) {
  ------------------
  |  Branch (138:7): [True: 0, False: 854]
  ------------------
  139|      0|      throw Invalid_Argument("BigInt::operator% modulus must be > 0");
  140|      0|   }
  141|    854|   if(n.signum() >= 0 && mod.signum() >= 0 && n < mod) {
  ------------------
  |  Branch (141:7): [True: 854, False: 0]
  |  Branch (141:26): [True: 854, False: 0]
  |  Branch (141:47): [True: 35, False: 819]
  ------------------
  142|     35|      return n;
  143|     35|   }
  144|       |
  145|    819|   if(mod.sig_words() == 1) {
  ------------------
  |  Branch (145:7): [True: 529, False: 290]
  ------------------
  146|    529|      return BigInt::from_word(n % mod.word_at(0));
  147|    529|   }
  148|       |
  149|    290|   BigInt q;
  150|    290|   BigInt r;
  151|    290|   ct_divide(n, mod, q, r);
  152|    290|   return r;
  153|    819|}
_ZN5BotanrmERKNS_6BigIntEm:
  158|    529|word operator%(const BigInt& n, word mod) {
  159|    529|   if(mod == 0) {
  ------------------
  |  Branch (159:7): [True: 0, False: 529]
  ------------------
  160|      0|      throw Invalid_Argument("BigInt::operator% divide by zero");
  161|      0|   }
  162|       |
  163|    529|   if(mod == 1) {
  ------------------
  |  Branch (163:7): [True: 8, False: 521]
  ------------------
  164|      8|      return 0;
  165|      8|   }
  166|       |
  167|    521|   word remainder = 0;
  168|       |
  169|    521|   if(n.signum() >= 0 && is_power_of_2(mod)) {
  ------------------
  |  Branch (169:7): [True: 521, False: 0]
  |  Branch (169:26): [True: 5, False: 516]
  ------------------
  170|      5|      remainder = (n.word_at(0) & (mod - 1));
  171|    516|   } else {
  172|    516|      const auto redc_mod = divide_precomp<word>::setup_vartime(mod);
  173|    516|      const size_t sw = n.sig_words();
  174|  1.26k|      for(size_t i = sw; i > 0; --i) {
  ------------------
  |  Branch (174:26): [True: 750, False: 516]
  ------------------
  175|    750|         remainder = redc_mod.mod_2to1(remainder, n.word_at(i - 1));
  176|    750|      }
  177|    516|   }
  178|       |
  179|    521|   if(remainder != 0 && n.sign() == BigInt::Negative) {
  ------------------
  |  Branch (179:7): [True: 507, False: 14]
  |  Branch (179:25): [True: 0, False: 507]
  ------------------
  180|      0|      return mod - remainder;
  181|      0|   }
  182|    521|   return remainder;
  183|    521|}

_ZN5Botan6BigInt9from_wordEm:
   33|    529|BigInt BigInt::from_word(word n) {
   34|    529|   BigInt bn;
   35|    529|   bn.set_word_at(0, n);
   36|    529|   return bn;
   37|    529|}
_ZN5Botan6BigInt10from_bytesENSt3__14spanIKhLm18446744073709551615EEE:
   81|  1.74k|BigInt BigInt::from_bytes(std::span<const uint8_t> input) {
   82|  1.74k|   BigInt r;
   83|  1.74k|   r.assign_from_bytes(input);
   84|  1.74k|   return r;
   85|  1.74k|}
_ZNK5Botan6BigInt8is_equalERKS0_:
  154|  1.70k|bool BigInt::is_equal(const BigInt& other) const {
  155|  1.70k|   if(this->sign() != other.sign()) {
  ------------------
  |  Branch (155:7): [True: 0, False: 1.70k]
  ------------------
  156|      0|      return false;
  157|      0|   }
  158|       |
  159|  1.70k|   return bigint_ct_is_eq(this->_data(), this->size(), other._data(), other.size()).as_bool();
  160|  1.70k|}
_ZNK5Botan6BigInt12is_less_thanERKS0_:
  162|    854|bool BigInt::is_less_than(const BigInt& other) const {
  163|    854|   if(this->signum() < 0 && other.signum() >= 0) {
  ------------------
  |  Branch (163:7): [True: 0, False: 854]
  |  Branch (163:29): [True: 0, False: 0]
  ------------------
  164|      0|      return true;
  165|      0|   }
  166|       |
  167|    854|   if(this->signum() >= 0 && other.signum() < 0) {
  ------------------
  |  Branch (167:7): [True: 854, False: 0]
  |  Branch (167:30): [True: 0, False: 854]
  ------------------
  168|      0|      return false;
  169|      0|   }
  170|       |
  171|    854|   if(other.signum() < 0 && this->signum() < 0) {
  ------------------
  |  Branch (171:7): [True: 0, False: 854]
  |  Branch (171:29): [True: 0, False: 0]
  ------------------
  172|      0|      return bigint_ct_is_lt(other._data(), other.size(), this->_data(), this->size()).as_bool();
  173|      0|   }
  174|       |
  175|    854|   return bigint_ct_is_lt(this->_data(), this->size(), other._data(), other.size()).as_bool();
  176|    854|}
_ZN5Botan6BigInt4Data11set_to_zeroEv:
  189|  1.74k|void BigInt::Data::set_to_zero() {
  190|  1.74k|   m_reg.resize(m_reg.capacity());
  191|  1.74k|   clear_mem(m_reg.data(), m_reg.size());
  192|  1.74k|   m_sig_words = 0;
  193|  1.74k|}
_ZNK5Botan6BigInt4Data14calc_sig_wordsEv:
  213|  3.46k|size_t BigInt::Data::calc_sig_words() const {
  214|  3.46k|   const size_t sz = m_reg.size();
  215|  3.46k|   size_t sig = sz;
  216|       |
  217|  3.46k|   word sub = 1;
  218|       |
  219|  53.0k|   for(size_t i = 0; i != sz; ++i) {
  ------------------
  |  Branch (219:22): [True: 49.6k, False: 3.46k]
  ------------------
  220|  49.6k|      const word w = m_reg[sz - i - 1];
  221|  49.6k|      sub &= ct_is_zero(w);
  222|  49.6k|      sig -= sub;
  223|  49.6k|   }
  224|       |
  225|       |   /*
  226|       |   * This depends on the data so is poisoned, but unpoison it here as
  227|       |   * later conditionals are made on the size.
  228|       |   */
  229|  3.46k|   CT::unpoison(sig);
  230|       |
  231|  3.46k|   return sig;
  232|  3.46k|}
_ZNK5Botan6BigInt13top_bits_freeEv:
  296|    870|size_t BigInt::top_bits_free() const {
  297|    870|   const size_t words = sig_words();
  298|       |
  299|    870|   const word top_word = word_at(words - 1);
  300|    870|   const size_t bits_used = high_bit(CT::value_barrier(top_word));
  301|    870|   CT::unpoison(bits_used);
  302|    870|   return WordInfo<word>::bits - bits_used;
  303|    870|}
_ZNK5Botan6BigInt4bitsEv:
  305|    870|size_t BigInt::bits() const {
  306|    870|   const size_t words = sig_words();
  307|       |
  308|    870|   if(words == 0) {
  ------------------
  |  Branch (308:7): [True: 0, False: 870]
  ------------------
  309|      0|      return 0;
  310|      0|   }
  311|       |
  312|    870|   const size_t full_words = (words - 1) * WordInfo<word>::bits;
  313|    870|   const size_t top_bits = WordInfo<word>::bits - top_bits_free();
  314|       |
  315|    870|   return full_words + top_bits;
  316|    870|}
_ZNK5Botan6BigInt3absEv:
  384|     24|BigInt BigInt::abs() const {
  385|     24|   BigInt x = (*this);
  386|     24|   x.set_sign(Positive);
  387|     24|   return x;
  388|     24|}
_ZN5Botan6BigInt17assign_from_bytesENSt3__14spanIKhLm18446744073709551615EEE:
  423|  1.74k|void BigInt::assign_from_bytes(std::span<const uint8_t> bytes) {
  424|  1.74k|   clear();
  425|       |
  426|  1.74k|   const size_t length = bytes.size();
  427|  1.74k|   const size_t full_words = length / sizeof(word);
  428|  1.74k|   const size_t extra_bytes = length % sizeof(word);
  429|       |
  430|  1.74k|   const size_t total_words = full_words + (extra_bytes > 0 ? 1 : 0);
  ------------------
  |  Branch (430:45): [True: 1.21k, False: 526]
  ------------------
  431|       |
  432|  1.74k|   secure_vector<word> reg(8 * ceil_division<size_t>(total_words, 8));
  433|       |
  434|  11.9k|   for(size_t i = 0; i != full_words; ++i) {
  ------------------
  |  Branch (434:22): [True: 10.2k, False: 1.74k]
  ------------------
  435|  10.2k|      reg[i] = load_be<word>(bytes.last<sizeof(word)>());
  436|  10.2k|      bytes = bytes.first(bytes.size() - sizeof(word));
  437|  10.2k|   }
  438|       |
  439|  1.74k|   if(!bytes.empty()) {
  ------------------
  |  Branch (439:7): [True: 1.21k, False: 526]
  ------------------
  440|  1.21k|      BOTAN_ASSERT_NOMSG(extra_bytes == bytes.size());
  ------------------
  |  |   84|  1.21k|   do {                                                                     \
  |  |   85|  1.21k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.21k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.21k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.21k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.21k]
  |  |  ------------------
  ------------------
  441|  1.21k|      std::array<uint8_t, sizeof(word)> last_partial_word = {0};
  442|  1.21k|      copy_mem(std::span{last_partial_word}.last(extra_bytes), bytes);
  443|  1.21k|      reg[full_words] = load_be<word>(last_partial_word);
  444|  1.21k|   }
  445|       |
  446|  1.74k|   m_data.swap(reg);
  447|  1.74k|}
_ZN5Botan6BigInt14cond_flip_signEb:
  521|    290|void BigInt::cond_flip_sign(bool predicate) {
  522|       |   // This code is assuming Negative == 0, Positive == 1
  523|       |
  524|    290|   const auto mask = CT::Mask<uint8_t>::expand_bool(predicate);
  525|       |
  526|    290|   const uint8_t current_sign = static_cast<uint8_t>(sign());
  527|       |
  528|    290|   const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign);
  529|       |
  530|    290|   set_sign(static_cast<Sign>(new_sign));
  531|    290|}
_ZNK5Botan6BigInt20_const_time_unpoisonEv:
  559|  14.4k|void BigInt::_const_time_unpoison() const {
  560|  14.4k|   CT::unpoison(m_data.const_data(), m_data.size());
  561|  14.4k|}

_ZN5Botan9ct_divideERKNS_6BigIntES2_RS0_S3_:
  180|    290|void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) {
  181|    290|   if(y.is_zero()) {
  ------------------
  |  Branch (181:7): [True: 0, False: 290]
  ------------------
  182|      0|      throw Invalid_Argument("ct_divide: cannot divide by zero");
  183|      0|   }
  184|       |
  185|    290|   BigInt q;
  186|    290|   BigInt r;
  187|    290|   ct_divide_impl(q, r, x, y);
  188|       |
  189|    290|   sign_fixup(x, y, q, r);
  190|    290|   r_out = std::move(r);
  191|    290|   q_out = std::move(q);
  192|    290|}
_ZN5Botan15ct_divide_pow2kEmRKNS_6BigIntE:
  194|    870|BigInt ct_divide_pow2k(size_t k, const BigInt& y) {
  195|    870|   BOTAN_ARG_CHECK(y.signum() != 0, "Cannot divide by zero");
  ------------------
  |  |   35|    870|   do {                                                          \
  |  |   36|    870|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|    870|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 870]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|    870|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 870]
  |  |  ------------------
  ------------------
  196|    870|   BOTAN_ARG_CHECK(y.signum() >= 0, "Negative divisor not supported");
  ------------------
  |  |   35|    870|   do {                                                          \
  |  |   36|    870|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|    870|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 870]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|    870|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 870]
  |  |  ------------------
  ------------------
  197|    870|   BOTAN_ARG_CHECK(k > 1, "Invalid k");
  ------------------
  |  |   35|    870|   do {                                                          \
  |  |   36|    870|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|    870|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 870]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|    870|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 870]
  |  |  ------------------
  ------------------
  198|       |
  199|    870|   BigInt q;
  200|    870|   BigInt r;
  201|    870|   ct_divide_impl(q, r, BigInt::power_of_2(k), y);
  202|    870|   return q;
  203|    870|}
_ZN5Botan9ct_moduloERKNS_6BigIntES2_:
  262|    854|BigInt ct_modulo(const BigInt& x, const BigInt& y) {
  263|    854|   if(y.signum() <= 0) {
  ------------------
  |  Branch (263:7): [True: 0, False: 854]
  ------------------
  264|      0|      throw Invalid_Argument("ct_modulo requires y > 0");
  265|      0|   }
  266|       |
  267|    854|   BigInt q;
  268|    854|   BigInt r;
  269|    854|   ct_divide_impl(q, r, x, y);
  270|       |
  271|    854|   if(x.signum() < 0) {
  ------------------
  |  Branch (271:7): [True: 0, False: 854]
  ------------------
  272|      0|      if(r.signum() != 0) {
  ------------------
  |  Branch (272:10): [True: 0, False: 0]
  ------------------
  273|      0|         r = y - r;
  274|      0|      }
  275|      0|   }
  276|       |
  277|    854|   return r;
  278|    854|}
divide.cpp:_ZN5Botan12_GLOBAL__N_114ct_divide_implERNS_6BigIntES2_RKS1_S4_:
   66|  2.01k|void ct_divide_impl(BigInt& q_out, BigInt& r_out, const BigInt& x, const BigInt& y) {
   67|  2.01k|   constexpr size_t WB = WordInfo<word>::bits;
   68|       |
   69|  2.01k|   const size_t x_words = x.sig_words();
   70|  2.01k|   const size_t y_words = y.sig_words();
   71|  2.01k|   BOTAN_ASSERT_NOMSG(y_words > 0);
  ------------------
  |  |   84|  2.01k|   do {                                                                     \
  |  |   85|  2.01k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  2.01k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 2.01k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  2.01k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 2.01k]
  |  |  ------------------
  ------------------
   72|       |
   73|  2.01k|   if(x_words < y_words) {
  ------------------
  |  Branch (73:7): [True: 24, False: 1.99k]
  ------------------
   74|       |      // Here |x| < |y| so q = 0 and r = |x|
   75|     24|      r_out = x.abs();
   76|     24|      q_out = BigInt::zero();
   77|     24|      return;
   78|     24|   }
   79|       |
   80|  1.99k|   const size_t r_words = x_words + 1;
   81|  1.99k|   const size_t q_words = x_words - y_words + 1;
   82|       |
   83|       |   // The number of leading zero bits of y, in [0,WB)
   84|  1.99k|   const word s = static_cast<word>(WB) - static_cast<word>(high_bit(CT::value_barrier(y._data()[y_words - 1])));
   85|  1.99k|   const auto s_mask = CT::Mask<word>::expand(s);
   86|  1.99k|   const word s_comp = s_mask.if_set_return(static_cast<word>(WB) - s);
   87|       |
   88|  1.99k|   secure_vector<word> yn(y_words);
   89|  1.99k|   secure_vector<word> rw(r_words);
   90|  1.99k|   secure_vector<word> qw(q_words);
   91|       |
   92|       |   // Normalize: yn = |y| << s (which sets the top bit of yn) and rw = |x| << s;
   93|       |   // shifting y stays within y_words words, shifting x adds at most one word
   94|  1.99k|   word carry = 0;
   95|  11.8k|   for(size_t i = 0; i != y_words; ++i) {
  ------------------
  |  Branch (95:22): [True: 9.87k, False: 1.99k]
  ------------------
   96|  9.87k|      const word w = y._data()[i];
   97|  9.87k|      yn[i] = (w << s) | carry;
   98|  9.87k|      carry = s_mask.if_set_return(w >> s_comp);
   99|  9.87k|   }
  100|       |
  101|  1.99k|   carry = 0;
  102|  21.3k|   for(size_t i = 0; i != x_words; ++i) {
  ------------------
  |  Branch (102:22): [True: 19.3k, False: 1.99k]
  ------------------
  103|  19.3k|      const word w = x._data()[i];
  104|  19.3k|      rw[i] = (w << s) | carry;
  105|  19.3k|      carry = s_mask.if_set_return(w >> s_comp);
  106|  19.3k|   }
  107|  1.99k|   rw[x_words] = carry;
  108|       |
  109|  1.99k|   const auto div_by_yn = divide_precomp<word>::setup(CT::value_barrier(yn[y_words - 1]));
  110|       |
  111|  1.99k|   if(y_words == 1) {
  ------------------
  |  Branch (111:7): [True: 1.07k, False: 917]
  ------------------
  112|       |      /*
  113|       |      * 2/1 word-serial division. The initial remainder is the shift-out
  114|       |      * carry, which is less than 2^s and so less than the divisor.
  115|       |      */
  116|  1.07k|      word r = rw[x_words];
  117|  3.46k|      for(size_t i = x_words; i > 0; --i) {
  ------------------
  |  Branch (117:31): [True: 2.39k, False: 1.07k]
  ------------------
  118|  2.39k|         const auto [qi, ri] = div_by_yn.divmod_2to1_ct(r, rw[i - 1]);
  119|  2.39k|         qw[i - 1] = qi;
  120|  2.39k|         r = ri;
  121|  2.39k|      }
  122|       |
  123|  1.07k|      rw[0] = r >> s;
  124|  1.07k|   } else {
  125|    917|      const word yn1 = yn[y_words - 1];
  126|    917|      const word yn2 = yn[y_words - 2];
  127|       |
  128|  9.98k|      for(size_t i = q_words; i > 0; --i) {
  ------------------
  |  Branch (128:31): [True: 9.06k, False: 917]
  ------------------
  129|  9.06k|         const size_t j = i - 1;  // current window is rw[j ... j + y_words]
  130|       |
  131|  9.06k|         const word u2 = rw[j + y_words];
  132|  9.06k|         const word u1 = rw[j + y_words - 1];
  133|  9.06k|         const word u0 = rw[j + y_words - 2];
  134|       |
  135|       |         /*
  136|       |         * Estimate the quotient digit from the top two words of the window.
  137|       |         * The window invariant gives u2 <= yn1; if u2 == yn1 the 2/1
  138|       |         * division precondition does not hold, and instead the digit
  139|       |         * estimate is the maximum word value.
  140|       |         */
  141|  9.06k|         const auto top_eq = CT::Mask<word>::is_equal(u2, yn1);
  142|  9.06k|         const word q_est = div_by_yn.divmod_2to1_ct(u2, u1).first;
  143|  9.06k|         word qhat = top_eq.select(WordInfo<word>::max, q_est);
  144|       |
  145|       |         // Per HAC 14.23, this correction is required at most twice
  146|  9.06k|         qhat -= division_check_ct(qhat, yn1, yn2, u2, u1, u0).if_set_return(1);
  147|  9.06k|         qhat -= division_check_ct(qhat, yn1, yn2, u2, u1, u0).if_set_return(1);
  148|       |
  149|       |         // Subtract qhat * yn from the window
  150|  9.06k|         const word bw = bigint_submul(&rw[j], yn.data(), y_words, qhat);
  151|  9.06k|         word borrow = 0;
  152|  9.06k|         rw[j + y_words] = word_sub(u2, bw, &borrow);
  153|       |
  154|       |         // If the digit was still one too large, the subtraction
  155|       |         // underflowed; add back and decrement the digit
  156|  9.06k|         const word cb = bigint_cnd_add(borrow, &rw[j], yn.data(), y_words);
  157|  9.06k|         rw[j + y_words] += cb;
  158|  9.06k|         qhat -= borrow;
  159|       |
  160|  9.06k|         qw[j] = qhat;
  161|  9.06k|      }
  162|       |
  163|       |      // The remainder is in rw[0:y_words], still shifted left by s, and
  164|       |      // rw[y_words] is zero
  165|  9.72k|      for(size_t i = 0; i != y_words; ++i) {
  ------------------
  |  Branch (165:25): [True: 8.80k, False: 917]
  ------------------
  166|  8.80k|         rw[i] = (rw[i] >> s) | s_mask.if_set_return(CT::value_barrier(rw[i + 1]) << s_comp);
  167|  8.80k|      }
  168|    917|   }
  169|       |
  170|  1.99k|   BigInt q = BigInt::_from_words(qw);
  171|  1.99k|   rw.resize(y_words);
  172|  1.99k|   BigInt r = BigInt::_from_words(rw);
  173|       |
  174|  1.99k|   r_out = std::move(r);
  175|  1.99k|   q_out = std::move(q);
  176|  1.99k|}
divide.cpp:_ZN5Botan12_GLOBAL__N_117division_check_ctEmmmmmm:
   39|  18.1k|inline CT::Mask<word> division_check_ct(word q, word y2, word y1, word x3, word x2, word x1) {
   40|  18.1k|   word y3 = 0;
   41|  18.1k|   y1 = word_madd2(q, y1, &y3);
   42|  18.1k|   y2 = word_madd2(q, y2, &y3);
   43|       |
   44|  18.1k|   const auto gt3 = CT::Mask<word>::is_gt(y3, x3);
   45|  18.1k|   const auto eq3 = CT::Mask<word>::is_equal(y3, x3);
   46|  18.1k|   const auto gt2 = CT::Mask<word>::is_gt(y2, x2);
   47|  18.1k|   const auto eq2 = CT::Mask<word>::is_equal(y2, x2);
   48|  18.1k|   const auto gt1 = CT::Mask<word>::is_gt(y1, x1);
   49|       |
   50|  18.1k|   return gt3 | (eq3 & (gt2 | (eq2 & gt1)));
   51|  18.1k|}
divide.cpp:_ZN5Botan12_GLOBAL__N_110sign_fixupERKNS_6BigIntES3_RS1_S4_:
   22|    290|void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) {
   23|    290|   q.cond_flip_sign(x.sign() != y.sign());
   24|       |
   25|    290|   if(x.signum() < 0 && r.signum() != 0) {
  ------------------
  |  Branch (25:7): [True: 0, False: 290]
  |  Branch (25:25): [True: 0, False: 0]
  ------------------
   26|      0|      if(y.signum() > 0) {
  ------------------
  |  Branch (26:10): [True: 0, False: 0]
  ------------------
   27|      0|         q -= 1;
   28|      0|      } else {
   29|      0|         q += 1;
   30|      0|      }
   31|      0|      r = y.abs() - r;
   32|      0|   }
   33|    290|}

_ZN5Botan17bigint_comba_mul4EPmPKmS2_:
   54|    195|void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) {
   55|    195|#if defined(BOTAN_HAS_MP_MULX)
   56|    195|   if(CPUID::has(CPUID::Feature::BMI, CPUID::Feature::ADX)) {
  ------------------
  |  Branch (56:7): [True: 195, False: 0]
  ------------------
   57|    195|      return bigint_mulx_mul4(z, x, y);
   58|    195|   }
   59|      0|#endif
   60|       |
   61|      0|   word3<word> accum;
   62|       |
   63|      0|   accum.mul(x[0], y[0]);
   64|      0|   z[0] = accum.extract();
   65|      0|   accum.mul(x[0], y[1]);
   66|      0|   accum.mul(x[1], y[0]);
   67|      0|   z[1] = accum.extract();
   68|      0|   accum.mul(x[0], y[2]);
   69|      0|   accum.mul(x[1], y[1]);
   70|      0|   accum.mul(x[2], y[0]);
   71|      0|   z[2] = accum.extract();
   72|      0|   accum.mul(x[0], y[3]);
   73|      0|   accum.mul(x[1], y[2]);
   74|      0|   accum.mul(x[2], y[1]);
   75|      0|   accum.mul(x[3], y[0]);
   76|      0|   z[3] = accum.extract();
   77|      0|   accum.mul(x[1], y[3]);
   78|      0|   accum.mul(x[2], y[2]);
   79|      0|   accum.mul(x[3], y[1]);
   80|      0|   z[4] = accum.extract();
   81|      0|   accum.mul(x[2], y[3]);
   82|      0|   accum.mul(x[3], y[2]);
   83|      0|   z[5] = accum.extract();
   84|      0|   accum.mul(x[3], y[3]);
   85|      0|   z[6] = accum.extract();
   86|      0|   z[7] = accum.extract();
   87|      0|}
_ZN5Botan17bigint_comba_mul6EPmPKmS2_:
  139|    255|void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) {
  140|    255|#if defined(BOTAN_HAS_MP_MULX)
  141|    255|   if(CPUID::has(CPUID::Feature::BMI, CPUID::Feature::ADX)) {
  ------------------
  |  Branch (141:7): [True: 255, False: 0]
  ------------------
  142|    255|      return bigint_mulx_mul6(z, x, y);
  143|    255|   }
  144|      0|#endif
  145|       |
  146|      0|   word3<word> accum;
  147|       |
  148|      0|   accum.mul(x[0], y[0]);
  149|      0|   z[0] = accum.extract();
  150|      0|   accum.mul(x[0], y[1]);
  151|      0|   accum.mul(x[1], y[0]);
  152|      0|   z[1] = accum.extract();
  153|      0|   accum.mul(x[0], y[2]);
  154|      0|   accum.mul(x[1], y[1]);
  155|      0|   accum.mul(x[2], y[0]);
  156|      0|   z[2] = accum.extract();
  157|      0|   accum.mul(x[0], y[3]);
  158|      0|   accum.mul(x[1], y[2]);
  159|      0|   accum.mul(x[2], y[1]);
  160|      0|   accum.mul(x[3], y[0]);
  161|      0|   z[3] = accum.extract();
  162|      0|   accum.mul(x[0], y[4]);
  163|      0|   accum.mul(x[1], y[3]);
  164|      0|   accum.mul(x[2], y[2]);
  165|      0|   accum.mul(x[3], y[1]);
  166|      0|   accum.mul(x[4], y[0]);
  167|      0|   z[4] = accum.extract();
  168|      0|   accum.mul(x[0], y[5]);
  169|      0|   accum.mul(x[1], y[4]);
  170|      0|   accum.mul(x[2], y[3]);
  171|      0|   accum.mul(x[3], y[2]);
  172|      0|   accum.mul(x[4], y[1]);
  173|      0|   accum.mul(x[5], y[0]);
  174|      0|   z[5] = accum.extract();
  175|      0|   accum.mul(x[1], y[5]);
  176|      0|   accum.mul(x[2], y[4]);
  177|      0|   accum.mul(x[3], y[3]);
  178|      0|   accum.mul(x[4], y[2]);
  179|      0|   accum.mul(x[5], y[1]);
  180|      0|   z[6] = accum.extract();
  181|      0|   accum.mul(x[2], y[5]);
  182|      0|   accum.mul(x[3], y[4]);
  183|      0|   accum.mul(x[4], y[3]);
  184|      0|   accum.mul(x[5], y[2]);
  185|      0|   z[7] = accum.extract();
  186|      0|   accum.mul(x[3], y[5]);
  187|      0|   accum.mul(x[4], y[4]);
  188|      0|   accum.mul(x[5], y[3]);
  189|      0|   z[8] = accum.extract();
  190|      0|   accum.mul(x[4], y[5]);
  191|      0|   accum.mul(x[5], y[4]);
  192|      0|   z[9] = accum.extract();
  193|      0|   accum.mul(x[5], y[5]);
  194|      0|   z[10] = accum.extract();
  195|      0|   z[11] = accum.extract();
  196|      0|}
_ZN5Botan17bigint_comba_mul8EPmPKmS2_:
  388|     18|void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) {
  389|     18|#if defined(BOTAN_HAS_MP_MULX)
  390|     18|   if(CPUID::has(CPUID::Feature::BMI, CPUID::Feature::ADX)) {
  ------------------
  |  Branch (390:7): [True: 18, False: 0]
  ------------------
  391|     18|      return bigint_mulx_mul8(z, x, y);
  392|     18|   }
  393|      0|#endif
  394|       |
  395|      0|   word3<word> accum;
  396|       |
  397|      0|   accum.mul(x[0], y[0]);
  398|      0|   z[0] = accum.extract();
  399|      0|   accum.mul(x[0], y[1]);
  400|      0|   accum.mul(x[1], y[0]);
  401|      0|   z[1] = accum.extract();
  402|      0|   accum.mul(x[0], y[2]);
  403|      0|   accum.mul(x[1], y[1]);
  404|      0|   accum.mul(x[2], y[0]);
  405|      0|   z[2] = accum.extract();
  406|      0|   accum.mul(x[0], y[3]);
  407|      0|   accum.mul(x[1], y[2]);
  408|      0|   accum.mul(x[2], y[1]);
  409|      0|   accum.mul(x[3], y[0]);
  410|      0|   z[3] = accum.extract();
  411|      0|   accum.mul(x[0], y[4]);
  412|      0|   accum.mul(x[1], y[3]);
  413|      0|   accum.mul(x[2], y[2]);
  414|      0|   accum.mul(x[3], y[1]);
  415|      0|   accum.mul(x[4], y[0]);
  416|      0|   z[4] = accum.extract();
  417|      0|   accum.mul(x[0], y[5]);
  418|      0|   accum.mul(x[1], y[4]);
  419|      0|   accum.mul(x[2], y[3]);
  420|      0|   accum.mul(x[3], y[2]);
  421|      0|   accum.mul(x[4], y[1]);
  422|      0|   accum.mul(x[5], y[0]);
  423|      0|   z[5] = accum.extract();
  424|      0|   accum.mul(x[0], y[6]);
  425|      0|   accum.mul(x[1], y[5]);
  426|      0|   accum.mul(x[2], y[4]);
  427|      0|   accum.mul(x[3], y[3]);
  428|      0|   accum.mul(x[4], y[2]);
  429|      0|   accum.mul(x[5], y[1]);
  430|      0|   accum.mul(x[6], y[0]);
  431|      0|   z[6] = accum.extract();
  432|      0|   accum.mul(x[0], y[7]);
  433|      0|   accum.mul(x[1], y[6]);
  434|      0|   accum.mul(x[2], y[5]);
  435|      0|   accum.mul(x[3], y[4]);
  436|      0|   accum.mul(x[4], y[3]);
  437|      0|   accum.mul(x[5], y[2]);
  438|      0|   accum.mul(x[6], y[1]);
  439|      0|   accum.mul(x[7], y[0]);
  440|      0|   z[7] = accum.extract();
  441|      0|   accum.mul(x[1], y[7]);
  442|      0|   accum.mul(x[2], y[6]);
  443|      0|   accum.mul(x[3], y[5]);
  444|      0|   accum.mul(x[4], y[4]);
  445|      0|   accum.mul(x[5], y[3]);
  446|      0|   accum.mul(x[6], y[2]);
  447|      0|   accum.mul(x[7], y[1]);
  448|      0|   z[8] = accum.extract();
  449|      0|   accum.mul(x[2], y[7]);
  450|      0|   accum.mul(x[3], y[6]);
  451|      0|   accum.mul(x[4], y[5]);
  452|      0|   accum.mul(x[5], y[4]);
  453|      0|   accum.mul(x[6], y[3]);
  454|      0|   accum.mul(x[7], y[2]);
  455|      0|   z[9] = accum.extract();
  456|      0|   accum.mul(x[3], y[7]);
  457|      0|   accum.mul(x[4], y[6]);
  458|      0|   accum.mul(x[5], y[5]);
  459|      0|   accum.mul(x[6], y[4]);
  460|      0|   accum.mul(x[7], y[3]);
  461|      0|   z[10] = accum.extract();
  462|      0|   accum.mul(x[4], y[7]);
  463|      0|   accum.mul(x[5], y[6]);
  464|      0|   accum.mul(x[6], y[5]);
  465|      0|   accum.mul(x[7], y[4]);
  466|      0|   z[11] = accum.extract();
  467|      0|   accum.mul(x[5], y[7]);
  468|      0|   accum.mul(x[6], y[6]);
  469|      0|   accum.mul(x[7], y[5]);
  470|      0|   z[12] = accum.extract();
  471|      0|   accum.mul(x[6], y[7]);
  472|      0|   accum.mul(x[7], y[6]);
  473|      0|   z[13] = accum.extract();
  474|      0|   accum.mul(x[7], y[7]);
  475|      0|   z[14] = accum.extract();
  476|      0|   z[15] = accum.extract();
  477|      0|}
_ZN5Botan17bigint_comba_mul9EPmPKmS2_:
  559|     10|void bigint_comba_mul9(word z[18], const word x[9], const word y[9]) {
  560|     10|#if defined(BOTAN_HAS_MP_MULX)
  561|     10|   if(CPUID::has(CPUID::Feature::BMI, CPUID::Feature::ADX)) {
  ------------------
  |  Branch (561:7): [True: 10, False: 0]
  ------------------
  562|     10|      return bigint_mulx_mul9(z, x, y);
  563|     10|   }
  564|      0|#endif
  565|       |
  566|      0|   word3<word> accum;
  567|       |
  568|      0|   accum.mul(x[0], y[0]);
  569|      0|   z[0] = accum.extract();
  570|      0|   accum.mul(x[0], y[1]);
  571|      0|   accum.mul(x[1], y[0]);
  572|      0|   z[1] = accum.extract();
  573|      0|   accum.mul(x[0], y[2]);
  574|      0|   accum.mul(x[1], y[1]);
  575|      0|   accum.mul(x[2], y[0]);
  576|      0|   z[2] = accum.extract();
  577|      0|   accum.mul(x[0], y[3]);
  578|      0|   accum.mul(x[1], y[2]);
  579|      0|   accum.mul(x[2], y[1]);
  580|      0|   accum.mul(x[3], y[0]);
  581|      0|   z[3] = accum.extract();
  582|      0|   accum.mul(x[0], y[4]);
  583|      0|   accum.mul(x[1], y[3]);
  584|      0|   accum.mul(x[2], y[2]);
  585|      0|   accum.mul(x[3], y[1]);
  586|      0|   accum.mul(x[4], y[0]);
  587|      0|   z[4] = accum.extract();
  588|      0|   accum.mul(x[0], y[5]);
  589|      0|   accum.mul(x[1], y[4]);
  590|      0|   accum.mul(x[2], y[3]);
  591|      0|   accum.mul(x[3], y[2]);
  592|      0|   accum.mul(x[4], y[1]);
  593|      0|   accum.mul(x[5], y[0]);
  594|      0|   z[5] = accum.extract();
  595|      0|   accum.mul(x[0], y[6]);
  596|      0|   accum.mul(x[1], y[5]);
  597|      0|   accum.mul(x[2], y[4]);
  598|      0|   accum.mul(x[3], y[3]);
  599|      0|   accum.mul(x[4], y[2]);
  600|      0|   accum.mul(x[5], y[1]);
  601|      0|   accum.mul(x[6], y[0]);
  602|      0|   z[6] = accum.extract();
  603|      0|   accum.mul(x[0], y[7]);
  604|      0|   accum.mul(x[1], y[6]);
  605|      0|   accum.mul(x[2], y[5]);
  606|      0|   accum.mul(x[3], y[4]);
  607|      0|   accum.mul(x[4], y[3]);
  608|      0|   accum.mul(x[5], y[2]);
  609|      0|   accum.mul(x[6], y[1]);
  610|      0|   accum.mul(x[7], y[0]);
  611|      0|   z[7] = accum.extract();
  612|      0|   accum.mul(x[0], y[8]);
  613|      0|   accum.mul(x[1], y[7]);
  614|      0|   accum.mul(x[2], y[6]);
  615|      0|   accum.mul(x[3], y[5]);
  616|      0|   accum.mul(x[4], y[4]);
  617|      0|   accum.mul(x[5], y[3]);
  618|      0|   accum.mul(x[6], y[2]);
  619|      0|   accum.mul(x[7], y[1]);
  620|      0|   accum.mul(x[8], y[0]);
  621|      0|   z[8] = accum.extract();
  622|      0|   accum.mul(x[1], y[8]);
  623|      0|   accum.mul(x[2], y[7]);
  624|      0|   accum.mul(x[3], y[6]);
  625|      0|   accum.mul(x[4], y[5]);
  626|      0|   accum.mul(x[5], y[4]);
  627|      0|   accum.mul(x[6], y[3]);
  628|      0|   accum.mul(x[7], y[2]);
  629|      0|   accum.mul(x[8], y[1]);
  630|      0|   z[9] = accum.extract();
  631|      0|   accum.mul(x[2], y[8]);
  632|      0|   accum.mul(x[3], y[7]);
  633|      0|   accum.mul(x[4], y[6]);
  634|      0|   accum.mul(x[5], y[5]);
  635|      0|   accum.mul(x[6], y[4]);
  636|      0|   accum.mul(x[7], y[3]);
  637|      0|   accum.mul(x[8], y[2]);
  638|      0|   z[10] = accum.extract();
  639|      0|   accum.mul(x[3], y[8]);
  640|      0|   accum.mul(x[4], y[7]);
  641|      0|   accum.mul(x[5], y[6]);
  642|      0|   accum.mul(x[6], y[5]);
  643|      0|   accum.mul(x[7], y[4]);
  644|      0|   accum.mul(x[8], y[3]);
  645|      0|   z[11] = accum.extract();
  646|      0|   accum.mul(x[4], y[8]);
  647|      0|   accum.mul(x[5], y[7]);
  648|      0|   accum.mul(x[6], y[6]);
  649|      0|   accum.mul(x[7], y[5]);
  650|      0|   accum.mul(x[8], y[4]);
  651|      0|   z[12] = accum.extract();
  652|      0|   accum.mul(x[5], y[8]);
  653|      0|   accum.mul(x[6], y[7]);
  654|      0|   accum.mul(x[7], y[6]);
  655|      0|   accum.mul(x[8], y[5]);
  656|      0|   z[13] = accum.extract();
  657|      0|   accum.mul(x[6], y[8]);
  658|      0|   accum.mul(x[7], y[7]);
  659|      0|   accum.mul(x[8], y[6]);
  660|      0|   z[14] = accum.extract();
  661|      0|   accum.mul(x[7], y[8]);
  662|      0|   accum.mul(x[8], y[7]);
  663|      0|   z[15] = accum.extract();
  664|      0|   accum.mul(x[8], y[8]);
  665|      0|   z[16] = accum.extract();
  666|      0|   z[17] = accum.extract();
  667|      0|}
_ZN5Botan18bigint_comba_mul16EPmPKmS2_:
  848|     23|void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) {
  849|     23|   word3<word> accum;
  850|       |
  851|     23|   accum.mul(x[0], y[0]);
  852|     23|   z[0] = accum.extract();
  853|     23|   accum.mul(x[0], y[1]);
  854|     23|   accum.mul(x[1], y[0]);
  855|     23|   z[1] = accum.extract();
  856|     23|   accum.mul(x[0], y[2]);
  857|     23|   accum.mul(x[1], y[1]);
  858|     23|   accum.mul(x[2], y[0]);
  859|     23|   z[2] = accum.extract();
  860|     23|   accum.mul(x[0], y[3]);
  861|     23|   accum.mul(x[1], y[2]);
  862|     23|   accum.mul(x[2], y[1]);
  863|     23|   accum.mul(x[3], y[0]);
  864|     23|   z[3] = accum.extract();
  865|     23|   accum.mul(x[0], y[4]);
  866|     23|   accum.mul(x[1], y[3]);
  867|     23|   accum.mul(x[2], y[2]);
  868|     23|   accum.mul(x[3], y[1]);
  869|     23|   accum.mul(x[4], y[0]);
  870|     23|   z[4] = accum.extract();
  871|     23|   accum.mul(x[0], y[5]);
  872|     23|   accum.mul(x[1], y[4]);
  873|     23|   accum.mul(x[2], y[3]);
  874|     23|   accum.mul(x[3], y[2]);
  875|     23|   accum.mul(x[4], y[1]);
  876|     23|   accum.mul(x[5], y[0]);
  877|     23|   z[5] = accum.extract();
  878|     23|   accum.mul(x[0], y[6]);
  879|     23|   accum.mul(x[1], y[5]);
  880|     23|   accum.mul(x[2], y[4]);
  881|     23|   accum.mul(x[3], y[3]);
  882|     23|   accum.mul(x[4], y[2]);
  883|     23|   accum.mul(x[5], y[1]);
  884|     23|   accum.mul(x[6], y[0]);
  885|     23|   z[6] = accum.extract();
  886|     23|   accum.mul(x[0], y[7]);
  887|     23|   accum.mul(x[1], y[6]);
  888|     23|   accum.mul(x[2], y[5]);
  889|     23|   accum.mul(x[3], y[4]);
  890|     23|   accum.mul(x[4], y[3]);
  891|     23|   accum.mul(x[5], y[2]);
  892|     23|   accum.mul(x[6], y[1]);
  893|     23|   accum.mul(x[7], y[0]);
  894|     23|   z[7] = accum.extract();
  895|     23|   accum.mul(x[0], y[8]);
  896|     23|   accum.mul(x[1], y[7]);
  897|     23|   accum.mul(x[2], y[6]);
  898|     23|   accum.mul(x[3], y[5]);
  899|     23|   accum.mul(x[4], y[4]);
  900|     23|   accum.mul(x[5], y[3]);
  901|     23|   accum.mul(x[6], y[2]);
  902|     23|   accum.mul(x[7], y[1]);
  903|     23|   accum.mul(x[8], y[0]);
  904|     23|   z[8] = accum.extract();
  905|     23|   accum.mul(x[0], y[9]);
  906|     23|   accum.mul(x[1], y[8]);
  907|     23|   accum.mul(x[2], y[7]);
  908|     23|   accum.mul(x[3], y[6]);
  909|     23|   accum.mul(x[4], y[5]);
  910|     23|   accum.mul(x[5], y[4]);
  911|     23|   accum.mul(x[6], y[3]);
  912|     23|   accum.mul(x[7], y[2]);
  913|     23|   accum.mul(x[8], y[1]);
  914|     23|   accum.mul(x[9], y[0]);
  915|     23|   z[9] = accum.extract();
  916|     23|   accum.mul(x[0], y[10]);
  917|     23|   accum.mul(x[1], y[9]);
  918|     23|   accum.mul(x[2], y[8]);
  919|     23|   accum.mul(x[3], y[7]);
  920|     23|   accum.mul(x[4], y[6]);
  921|     23|   accum.mul(x[5], y[5]);
  922|     23|   accum.mul(x[6], y[4]);
  923|     23|   accum.mul(x[7], y[3]);
  924|     23|   accum.mul(x[8], y[2]);
  925|     23|   accum.mul(x[9], y[1]);
  926|     23|   accum.mul(x[10], y[0]);
  927|     23|   z[10] = accum.extract();
  928|     23|   accum.mul(x[0], y[11]);
  929|     23|   accum.mul(x[1], y[10]);
  930|     23|   accum.mul(x[2], y[9]);
  931|     23|   accum.mul(x[3], y[8]);
  932|     23|   accum.mul(x[4], y[7]);
  933|     23|   accum.mul(x[5], y[6]);
  934|     23|   accum.mul(x[6], y[5]);
  935|     23|   accum.mul(x[7], y[4]);
  936|     23|   accum.mul(x[8], y[3]);
  937|     23|   accum.mul(x[9], y[2]);
  938|     23|   accum.mul(x[10], y[1]);
  939|     23|   accum.mul(x[11], y[0]);
  940|     23|   z[11] = accum.extract();
  941|     23|   accum.mul(x[0], y[12]);
  942|     23|   accum.mul(x[1], y[11]);
  943|     23|   accum.mul(x[2], y[10]);
  944|     23|   accum.mul(x[3], y[9]);
  945|     23|   accum.mul(x[4], y[8]);
  946|     23|   accum.mul(x[5], y[7]);
  947|     23|   accum.mul(x[6], y[6]);
  948|     23|   accum.mul(x[7], y[5]);
  949|     23|   accum.mul(x[8], y[4]);
  950|     23|   accum.mul(x[9], y[3]);
  951|     23|   accum.mul(x[10], y[2]);
  952|     23|   accum.mul(x[11], y[1]);
  953|     23|   accum.mul(x[12], y[0]);
  954|     23|   z[12] = accum.extract();
  955|     23|   accum.mul(x[0], y[13]);
  956|     23|   accum.mul(x[1], y[12]);
  957|     23|   accum.mul(x[2], y[11]);
  958|     23|   accum.mul(x[3], y[10]);
  959|     23|   accum.mul(x[4], y[9]);
  960|     23|   accum.mul(x[5], y[8]);
  961|     23|   accum.mul(x[6], y[7]);
  962|     23|   accum.mul(x[7], y[6]);
  963|     23|   accum.mul(x[8], y[5]);
  964|     23|   accum.mul(x[9], y[4]);
  965|     23|   accum.mul(x[10], y[3]);
  966|     23|   accum.mul(x[11], y[2]);
  967|     23|   accum.mul(x[12], y[1]);
  968|     23|   accum.mul(x[13], y[0]);
  969|     23|   z[13] = accum.extract();
  970|     23|   accum.mul(x[0], y[14]);
  971|     23|   accum.mul(x[1], y[13]);
  972|     23|   accum.mul(x[2], y[12]);
  973|     23|   accum.mul(x[3], y[11]);
  974|     23|   accum.mul(x[4], y[10]);
  975|     23|   accum.mul(x[5], y[9]);
  976|     23|   accum.mul(x[6], y[8]);
  977|     23|   accum.mul(x[7], y[7]);
  978|     23|   accum.mul(x[8], y[6]);
  979|     23|   accum.mul(x[9], y[5]);
  980|     23|   accum.mul(x[10], y[4]);
  981|     23|   accum.mul(x[11], y[3]);
  982|     23|   accum.mul(x[12], y[2]);
  983|     23|   accum.mul(x[13], y[1]);
  984|     23|   accum.mul(x[14], y[0]);
  985|     23|   z[14] = accum.extract();
  986|     23|   accum.mul(x[0], y[15]);
  987|     23|   accum.mul(x[1], y[14]);
  988|     23|   accum.mul(x[2], y[13]);
  989|     23|   accum.mul(x[3], y[12]);
  990|     23|   accum.mul(x[4], y[11]);
  991|     23|   accum.mul(x[5], y[10]);
  992|     23|   accum.mul(x[6], y[9]);
  993|     23|   accum.mul(x[7], y[8]);
  994|     23|   accum.mul(x[8], y[7]);
  995|     23|   accum.mul(x[9], y[6]);
  996|     23|   accum.mul(x[10], y[5]);
  997|     23|   accum.mul(x[11], y[4]);
  998|     23|   accum.mul(x[12], y[3]);
  999|     23|   accum.mul(x[13], y[2]);
 1000|     23|   accum.mul(x[14], y[1]);
 1001|     23|   accum.mul(x[15], y[0]);
 1002|     23|   z[15] = accum.extract();
 1003|     23|   accum.mul(x[1], y[15]);
 1004|     23|   accum.mul(x[2], y[14]);
 1005|     23|   accum.mul(x[3], y[13]);
 1006|     23|   accum.mul(x[4], y[12]);
 1007|     23|   accum.mul(x[5], y[11]);
 1008|     23|   accum.mul(x[6], y[10]);
 1009|     23|   accum.mul(x[7], y[9]);
 1010|     23|   accum.mul(x[8], y[8]);
 1011|     23|   accum.mul(x[9], y[7]);
 1012|     23|   accum.mul(x[10], y[6]);
 1013|     23|   accum.mul(x[11], y[5]);
 1014|     23|   accum.mul(x[12], y[4]);
 1015|     23|   accum.mul(x[13], y[3]);
 1016|     23|   accum.mul(x[14], y[2]);
 1017|     23|   accum.mul(x[15], y[1]);
 1018|     23|   z[16] = accum.extract();
 1019|     23|   accum.mul(x[2], y[15]);
 1020|     23|   accum.mul(x[3], y[14]);
 1021|     23|   accum.mul(x[4], y[13]);
 1022|     23|   accum.mul(x[5], y[12]);
 1023|     23|   accum.mul(x[6], y[11]);
 1024|     23|   accum.mul(x[7], y[10]);
 1025|     23|   accum.mul(x[8], y[9]);
 1026|     23|   accum.mul(x[9], y[8]);
 1027|     23|   accum.mul(x[10], y[7]);
 1028|     23|   accum.mul(x[11], y[6]);
 1029|     23|   accum.mul(x[12], y[5]);
 1030|     23|   accum.mul(x[13], y[4]);
 1031|     23|   accum.mul(x[14], y[3]);
 1032|     23|   accum.mul(x[15], y[2]);
 1033|     23|   z[17] = accum.extract();
 1034|     23|   accum.mul(x[3], y[15]);
 1035|     23|   accum.mul(x[4], y[14]);
 1036|     23|   accum.mul(x[5], y[13]);
 1037|     23|   accum.mul(x[6], y[12]);
 1038|     23|   accum.mul(x[7], y[11]);
 1039|     23|   accum.mul(x[8], y[10]);
 1040|     23|   accum.mul(x[9], y[9]);
 1041|     23|   accum.mul(x[10], y[8]);
 1042|     23|   accum.mul(x[11], y[7]);
 1043|     23|   accum.mul(x[12], y[6]);
 1044|     23|   accum.mul(x[13], y[5]);
 1045|     23|   accum.mul(x[14], y[4]);
 1046|     23|   accum.mul(x[15], y[3]);
 1047|     23|   z[18] = accum.extract();
 1048|     23|   accum.mul(x[4], y[15]);
 1049|     23|   accum.mul(x[5], y[14]);
 1050|     23|   accum.mul(x[6], y[13]);
 1051|     23|   accum.mul(x[7], y[12]);
 1052|     23|   accum.mul(x[8], y[11]);
 1053|     23|   accum.mul(x[9], y[10]);
 1054|     23|   accum.mul(x[10], y[9]);
 1055|     23|   accum.mul(x[11], y[8]);
 1056|     23|   accum.mul(x[12], y[7]);
 1057|     23|   accum.mul(x[13], y[6]);
 1058|     23|   accum.mul(x[14], y[5]);
 1059|     23|   accum.mul(x[15], y[4]);
 1060|     23|   z[19] = accum.extract();
 1061|     23|   accum.mul(x[5], y[15]);
 1062|     23|   accum.mul(x[6], y[14]);
 1063|     23|   accum.mul(x[7], y[13]);
 1064|     23|   accum.mul(x[8], y[12]);
 1065|     23|   accum.mul(x[9], y[11]);
 1066|     23|   accum.mul(x[10], y[10]);
 1067|     23|   accum.mul(x[11], y[9]);
 1068|     23|   accum.mul(x[12], y[8]);
 1069|     23|   accum.mul(x[13], y[7]);
 1070|     23|   accum.mul(x[14], y[6]);
 1071|     23|   accum.mul(x[15], y[5]);
 1072|     23|   z[20] = accum.extract();
 1073|     23|   accum.mul(x[6], y[15]);
 1074|     23|   accum.mul(x[7], y[14]);
 1075|     23|   accum.mul(x[8], y[13]);
 1076|     23|   accum.mul(x[9], y[12]);
 1077|     23|   accum.mul(x[10], y[11]);
 1078|     23|   accum.mul(x[11], y[10]);
 1079|     23|   accum.mul(x[12], y[9]);
 1080|     23|   accum.mul(x[13], y[8]);
 1081|     23|   accum.mul(x[14], y[7]);
 1082|     23|   accum.mul(x[15], y[6]);
 1083|     23|   z[21] = accum.extract();
 1084|     23|   accum.mul(x[7], y[15]);
 1085|     23|   accum.mul(x[8], y[14]);
 1086|     23|   accum.mul(x[9], y[13]);
 1087|     23|   accum.mul(x[10], y[12]);
 1088|     23|   accum.mul(x[11], y[11]);
 1089|     23|   accum.mul(x[12], y[10]);
 1090|     23|   accum.mul(x[13], y[9]);
 1091|     23|   accum.mul(x[14], y[8]);
 1092|     23|   accum.mul(x[15], y[7]);
 1093|     23|   z[22] = accum.extract();
 1094|     23|   accum.mul(x[8], y[15]);
 1095|     23|   accum.mul(x[9], y[14]);
 1096|     23|   accum.mul(x[10], y[13]);
 1097|     23|   accum.mul(x[11], y[12]);
 1098|     23|   accum.mul(x[12], y[11]);
 1099|     23|   accum.mul(x[13], y[10]);
 1100|     23|   accum.mul(x[14], y[9]);
 1101|     23|   accum.mul(x[15], y[8]);
 1102|     23|   z[23] = accum.extract();
 1103|     23|   accum.mul(x[9], y[15]);
 1104|     23|   accum.mul(x[10], y[14]);
 1105|     23|   accum.mul(x[11], y[13]);
 1106|     23|   accum.mul(x[12], y[12]);
 1107|     23|   accum.mul(x[13], y[11]);
 1108|     23|   accum.mul(x[14], y[10]);
 1109|     23|   accum.mul(x[15], y[9]);
 1110|     23|   z[24] = accum.extract();
 1111|     23|   accum.mul(x[10], y[15]);
 1112|     23|   accum.mul(x[11], y[14]);
 1113|     23|   accum.mul(x[12], y[13]);
 1114|     23|   accum.mul(x[13], y[12]);
 1115|     23|   accum.mul(x[14], y[11]);
 1116|     23|   accum.mul(x[15], y[10]);
 1117|     23|   z[25] = accum.extract();
 1118|     23|   accum.mul(x[11], y[15]);
 1119|     23|   accum.mul(x[12], y[14]);
 1120|     23|   accum.mul(x[13], y[13]);
 1121|     23|   accum.mul(x[14], y[12]);
 1122|     23|   accum.mul(x[15], y[11]);
 1123|     23|   z[26] = accum.extract();
 1124|     23|   accum.mul(x[12], y[15]);
 1125|     23|   accum.mul(x[13], y[14]);
 1126|     23|   accum.mul(x[14], y[13]);
 1127|     23|   accum.mul(x[15], y[12]);
 1128|     23|   z[27] = accum.extract();
 1129|     23|   accum.mul(x[13], y[15]);
 1130|     23|   accum.mul(x[14], y[14]);
 1131|     23|   accum.mul(x[15], y[13]);
 1132|     23|   z[28] = accum.extract();
 1133|     23|   accum.mul(x[14], y[15]);
 1134|     23|   accum.mul(x[15], y[14]);
 1135|     23|   z[29] = accum.extract();
 1136|     23|   accum.mul(x[15], y[15]);
 1137|     23|   z[30] = accum.extract();
 1138|     23|   z[31] = accum.extract();
 1139|     23|}
_ZN5Botan18bigint_comba_mul24EPmPKmS2_:
 1500|     15|void bigint_comba_mul24(word z[48], const word x[24], const word y[24]) {
 1501|     15|   word3<word> accum;
 1502|       |
 1503|     15|   accum.mul(x[0], y[0]);
 1504|     15|   z[0] = accum.extract();
 1505|     15|   accum.mul(x[0], y[1]);
 1506|     15|   accum.mul(x[1], y[0]);
 1507|     15|   z[1] = accum.extract();
 1508|     15|   accum.mul(x[0], y[2]);
 1509|     15|   accum.mul(x[1], y[1]);
 1510|     15|   accum.mul(x[2], y[0]);
 1511|     15|   z[2] = accum.extract();
 1512|     15|   accum.mul(x[0], y[3]);
 1513|     15|   accum.mul(x[1], y[2]);
 1514|     15|   accum.mul(x[2], y[1]);
 1515|     15|   accum.mul(x[3], y[0]);
 1516|     15|   z[3] = accum.extract();
 1517|     15|   accum.mul(x[0], y[4]);
 1518|     15|   accum.mul(x[1], y[3]);
 1519|     15|   accum.mul(x[2], y[2]);
 1520|     15|   accum.mul(x[3], y[1]);
 1521|     15|   accum.mul(x[4], y[0]);
 1522|     15|   z[4] = accum.extract();
 1523|     15|   accum.mul(x[0], y[5]);
 1524|     15|   accum.mul(x[1], y[4]);
 1525|     15|   accum.mul(x[2], y[3]);
 1526|     15|   accum.mul(x[3], y[2]);
 1527|     15|   accum.mul(x[4], y[1]);
 1528|     15|   accum.mul(x[5], y[0]);
 1529|     15|   z[5] = accum.extract();
 1530|     15|   accum.mul(x[0], y[6]);
 1531|     15|   accum.mul(x[1], y[5]);
 1532|     15|   accum.mul(x[2], y[4]);
 1533|     15|   accum.mul(x[3], y[3]);
 1534|     15|   accum.mul(x[4], y[2]);
 1535|     15|   accum.mul(x[5], y[1]);
 1536|     15|   accum.mul(x[6], y[0]);
 1537|     15|   z[6] = accum.extract();
 1538|     15|   accum.mul(x[0], y[7]);
 1539|     15|   accum.mul(x[1], y[6]);
 1540|     15|   accum.mul(x[2], y[5]);
 1541|     15|   accum.mul(x[3], y[4]);
 1542|     15|   accum.mul(x[4], y[3]);
 1543|     15|   accum.mul(x[5], y[2]);
 1544|     15|   accum.mul(x[6], y[1]);
 1545|     15|   accum.mul(x[7], y[0]);
 1546|     15|   z[7] = accum.extract();
 1547|     15|   accum.mul(x[0], y[8]);
 1548|     15|   accum.mul(x[1], y[7]);
 1549|     15|   accum.mul(x[2], y[6]);
 1550|     15|   accum.mul(x[3], y[5]);
 1551|     15|   accum.mul(x[4], y[4]);
 1552|     15|   accum.mul(x[5], y[3]);
 1553|     15|   accum.mul(x[6], y[2]);
 1554|     15|   accum.mul(x[7], y[1]);
 1555|     15|   accum.mul(x[8], y[0]);
 1556|     15|   z[8] = accum.extract();
 1557|     15|   accum.mul(x[0], y[9]);
 1558|     15|   accum.mul(x[1], y[8]);
 1559|     15|   accum.mul(x[2], y[7]);
 1560|     15|   accum.mul(x[3], y[6]);
 1561|     15|   accum.mul(x[4], y[5]);
 1562|     15|   accum.mul(x[5], y[4]);
 1563|     15|   accum.mul(x[6], y[3]);
 1564|     15|   accum.mul(x[7], y[2]);
 1565|     15|   accum.mul(x[8], y[1]);
 1566|     15|   accum.mul(x[9], y[0]);
 1567|     15|   z[9] = accum.extract();
 1568|     15|   accum.mul(x[0], y[10]);
 1569|     15|   accum.mul(x[1], y[9]);
 1570|     15|   accum.mul(x[2], y[8]);
 1571|     15|   accum.mul(x[3], y[7]);
 1572|     15|   accum.mul(x[4], y[6]);
 1573|     15|   accum.mul(x[5], y[5]);
 1574|     15|   accum.mul(x[6], y[4]);
 1575|     15|   accum.mul(x[7], y[3]);
 1576|     15|   accum.mul(x[8], y[2]);
 1577|     15|   accum.mul(x[9], y[1]);
 1578|     15|   accum.mul(x[10], y[0]);
 1579|     15|   z[10] = accum.extract();
 1580|     15|   accum.mul(x[0], y[11]);
 1581|     15|   accum.mul(x[1], y[10]);
 1582|     15|   accum.mul(x[2], y[9]);
 1583|     15|   accum.mul(x[3], y[8]);
 1584|     15|   accum.mul(x[4], y[7]);
 1585|     15|   accum.mul(x[5], y[6]);
 1586|     15|   accum.mul(x[6], y[5]);
 1587|     15|   accum.mul(x[7], y[4]);
 1588|     15|   accum.mul(x[8], y[3]);
 1589|     15|   accum.mul(x[9], y[2]);
 1590|     15|   accum.mul(x[10], y[1]);
 1591|     15|   accum.mul(x[11], y[0]);
 1592|     15|   z[11] = accum.extract();
 1593|     15|   accum.mul(x[0], y[12]);
 1594|     15|   accum.mul(x[1], y[11]);
 1595|     15|   accum.mul(x[2], y[10]);
 1596|     15|   accum.mul(x[3], y[9]);
 1597|     15|   accum.mul(x[4], y[8]);
 1598|     15|   accum.mul(x[5], y[7]);
 1599|     15|   accum.mul(x[6], y[6]);
 1600|     15|   accum.mul(x[7], y[5]);
 1601|     15|   accum.mul(x[8], y[4]);
 1602|     15|   accum.mul(x[9], y[3]);
 1603|     15|   accum.mul(x[10], y[2]);
 1604|     15|   accum.mul(x[11], y[1]);
 1605|     15|   accum.mul(x[12], y[0]);
 1606|     15|   z[12] = accum.extract();
 1607|     15|   accum.mul(x[0], y[13]);
 1608|     15|   accum.mul(x[1], y[12]);
 1609|     15|   accum.mul(x[2], y[11]);
 1610|     15|   accum.mul(x[3], y[10]);
 1611|     15|   accum.mul(x[4], y[9]);
 1612|     15|   accum.mul(x[5], y[8]);
 1613|     15|   accum.mul(x[6], y[7]);
 1614|     15|   accum.mul(x[7], y[6]);
 1615|     15|   accum.mul(x[8], y[5]);
 1616|     15|   accum.mul(x[9], y[4]);
 1617|     15|   accum.mul(x[10], y[3]);
 1618|     15|   accum.mul(x[11], y[2]);
 1619|     15|   accum.mul(x[12], y[1]);
 1620|     15|   accum.mul(x[13], y[0]);
 1621|     15|   z[13] = accum.extract();
 1622|     15|   accum.mul(x[0], y[14]);
 1623|     15|   accum.mul(x[1], y[13]);
 1624|     15|   accum.mul(x[2], y[12]);
 1625|     15|   accum.mul(x[3], y[11]);
 1626|     15|   accum.mul(x[4], y[10]);
 1627|     15|   accum.mul(x[5], y[9]);
 1628|     15|   accum.mul(x[6], y[8]);
 1629|     15|   accum.mul(x[7], y[7]);
 1630|     15|   accum.mul(x[8], y[6]);
 1631|     15|   accum.mul(x[9], y[5]);
 1632|     15|   accum.mul(x[10], y[4]);
 1633|     15|   accum.mul(x[11], y[3]);
 1634|     15|   accum.mul(x[12], y[2]);
 1635|     15|   accum.mul(x[13], y[1]);
 1636|     15|   accum.mul(x[14], y[0]);
 1637|     15|   z[14] = accum.extract();
 1638|     15|   accum.mul(x[0], y[15]);
 1639|     15|   accum.mul(x[1], y[14]);
 1640|     15|   accum.mul(x[2], y[13]);
 1641|     15|   accum.mul(x[3], y[12]);
 1642|     15|   accum.mul(x[4], y[11]);
 1643|     15|   accum.mul(x[5], y[10]);
 1644|     15|   accum.mul(x[6], y[9]);
 1645|     15|   accum.mul(x[7], y[8]);
 1646|     15|   accum.mul(x[8], y[7]);
 1647|     15|   accum.mul(x[9], y[6]);
 1648|     15|   accum.mul(x[10], y[5]);
 1649|     15|   accum.mul(x[11], y[4]);
 1650|     15|   accum.mul(x[12], y[3]);
 1651|     15|   accum.mul(x[13], y[2]);
 1652|     15|   accum.mul(x[14], y[1]);
 1653|     15|   accum.mul(x[15], y[0]);
 1654|     15|   z[15] = accum.extract();
 1655|     15|   accum.mul(x[0], y[16]);
 1656|     15|   accum.mul(x[1], y[15]);
 1657|     15|   accum.mul(x[2], y[14]);
 1658|     15|   accum.mul(x[3], y[13]);
 1659|     15|   accum.mul(x[4], y[12]);
 1660|     15|   accum.mul(x[5], y[11]);
 1661|     15|   accum.mul(x[6], y[10]);
 1662|     15|   accum.mul(x[7], y[9]);
 1663|     15|   accum.mul(x[8], y[8]);
 1664|     15|   accum.mul(x[9], y[7]);
 1665|     15|   accum.mul(x[10], y[6]);
 1666|     15|   accum.mul(x[11], y[5]);
 1667|     15|   accum.mul(x[12], y[4]);
 1668|     15|   accum.mul(x[13], y[3]);
 1669|     15|   accum.mul(x[14], y[2]);
 1670|     15|   accum.mul(x[15], y[1]);
 1671|     15|   accum.mul(x[16], y[0]);
 1672|     15|   z[16] = accum.extract();
 1673|     15|   accum.mul(x[0], y[17]);
 1674|     15|   accum.mul(x[1], y[16]);
 1675|     15|   accum.mul(x[2], y[15]);
 1676|     15|   accum.mul(x[3], y[14]);
 1677|     15|   accum.mul(x[4], y[13]);
 1678|     15|   accum.mul(x[5], y[12]);
 1679|     15|   accum.mul(x[6], y[11]);
 1680|     15|   accum.mul(x[7], y[10]);
 1681|     15|   accum.mul(x[8], y[9]);
 1682|     15|   accum.mul(x[9], y[8]);
 1683|     15|   accum.mul(x[10], y[7]);
 1684|     15|   accum.mul(x[11], y[6]);
 1685|     15|   accum.mul(x[12], y[5]);
 1686|     15|   accum.mul(x[13], y[4]);
 1687|     15|   accum.mul(x[14], y[3]);
 1688|     15|   accum.mul(x[15], y[2]);
 1689|     15|   accum.mul(x[16], y[1]);
 1690|     15|   accum.mul(x[17], y[0]);
 1691|     15|   z[17] = accum.extract();
 1692|     15|   accum.mul(x[0], y[18]);
 1693|     15|   accum.mul(x[1], y[17]);
 1694|     15|   accum.mul(x[2], y[16]);
 1695|     15|   accum.mul(x[3], y[15]);
 1696|     15|   accum.mul(x[4], y[14]);
 1697|     15|   accum.mul(x[5], y[13]);
 1698|     15|   accum.mul(x[6], y[12]);
 1699|     15|   accum.mul(x[7], y[11]);
 1700|     15|   accum.mul(x[8], y[10]);
 1701|     15|   accum.mul(x[9], y[9]);
 1702|     15|   accum.mul(x[10], y[8]);
 1703|     15|   accum.mul(x[11], y[7]);
 1704|     15|   accum.mul(x[12], y[6]);
 1705|     15|   accum.mul(x[13], y[5]);
 1706|     15|   accum.mul(x[14], y[4]);
 1707|     15|   accum.mul(x[15], y[3]);
 1708|     15|   accum.mul(x[16], y[2]);
 1709|     15|   accum.mul(x[17], y[1]);
 1710|     15|   accum.mul(x[18], y[0]);
 1711|     15|   z[18] = accum.extract();
 1712|     15|   accum.mul(x[0], y[19]);
 1713|     15|   accum.mul(x[1], y[18]);
 1714|     15|   accum.mul(x[2], y[17]);
 1715|     15|   accum.mul(x[3], y[16]);
 1716|     15|   accum.mul(x[4], y[15]);
 1717|     15|   accum.mul(x[5], y[14]);
 1718|     15|   accum.mul(x[6], y[13]);
 1719|     15|   accum.mul(x[7], y[12]);
 1720|     15|   accum.mul(x[8], y[11]);
 1721|     15|   accum.mul(x[9], y[10]);
 1722|     15|   accum.mul(x[10], y[9]);
 1723|     15|   accum.mul(x[11], y[8]);
 1724|     15|   accum.mul(x[12], y[7]);
 1725|     15|   accum.mul(x[13], y[6]);
 1726|     15|   accum.mul(x[14], y[5]);
 1727|     15|   accum.mul(x[15], y[4]);
 1728|     15|   accum.mul(x[16], y[3]);
 1729|     15|   accum.mul(x[17], y[2]);
 1730|     15|   accum.mul(x[18], y[1]);
 1731|     15|   accum.mul(x[19], y[0]);
 1732|     15|   z[19] = accum.extract();
 1733|     15|   accum.mul(x[0], y[20]);
 1734|     15|   accum.mul(x[1], y[19]);
 1735|     15|   accum.mul(x[2], y[18]);
 1736|     15|   accum.mul(x[3], y[17]);
 1737|     15|   accum.mul(x[4], y[16]);
 1738|     15|   accum.mul(x[5], y[15]);
 1739|     15|   accum.mul(x[6], y[14]);
 1740|     15|   accum.mul(x[7], y[13]);
 1741|     15|   accum.mul(x[8], y[12]);
 1742|     15|   accum.mul(x[9], y[11]);
 1743|     15|   accum.mul(x[10], y[10]);
 1744|     15|   accum.mul(x[11], y[9]);
 1745|     15|   accum.mul(x[12], y[8]);
 1746|     15|   accum.mul(x[13], y[7]);
 1747|     15|   accum.mul(x[14], y[6]);
 1748|     15|   accum.mul(x[15], y[5]);
 1749|     15|   accum.mul(x[16], y[4]);
 1750|     15|   accum.mul(x[17], y[3]);
 1751|     15|   accum.mul(x[18], y[2]);
 1752|     15|   accum.mul(x[19], y[1]);
 1753|     15|   accum.mul(x[20], y[0]);
 1754|     15|   z[20] = accum.extract();
 1755|     15|   accum.mul(x[0], y[21]);
 1756|     15|   accum.mul(x[1], y[20]);
 1757|     15|   accum.mul(x[2], y[19]);
 1758|     15|   accum.mul(x[3], y[18]);
 1759|     15|   accum.mul(x[4], y[17]);
 1760|     15|   accum.mul(x[5], y[16]);
 1761|     15|   accum.mul(x[6], y[15]);
 1762|     15|   accum.mul(x[7], y[14]);
 1763|     15|   accum.mul(x[8], y[13]);
 1764|     15|   accum.mul(x[9], y[12]);
 1765|     15|   accum.mul(x[10], y[11]);
 1766|     15|   accum.mul(x[11], y[10]);
 1767|     15|   accum.mul(x[12], y[9]);
 1768|     15|   accum.mul(x[13], y[8]);
 1769|     15|   accum.mul(x[14], y[7]);
 1770|     15|   accum.mul(x[15], y[6]);
 1771|     15|   accum.mul(x[16], y[5]);
 1772|     15|   accum.mul(x[17], y[4]);
 1773|     15|   accum.mul(x[18], y[3]);
 1774|     15|   accum.mul(x[19], y[2]);
 1775|     15|   accum.mul(x[20], y[1]);
 1776|     15|   accum.mul(x[21], y[0]);
 1777|     15|   z[21] = accum.extract();
 1778|     15|   accum.mul(x[0], y[22]);
 1779|     15|   accum.mul(x[1], y[21]);
 1780|     15|   accum.mul(x[2], y[20]);
 1781|     15|   accum.mul(x[3], y[19]);
 1782|     15|   accum.mul(x[4], y[18]);
 1783|     15|   accum.mul(x[5], y[17]);
 1784|     15|   accum.mul(x[6], y[16]);
 1785|     15|   accum.mul(x[7], y[15]);
 1786|     15|   accum.mul(x[8], y[14]);
 1787|     15|   accum.mul(x[9], y[13]);
 1788|     15|   accum.mul(x[10], y[12]);
 1789|     15|   accum.mul(x[11], y[11]);
 1790|     15|   accum.mul(x[12], y[10]);
 1791|     15|   accum.mul(x[13], y[9]);
 1792|     15|   accum.mul(x[14], y[8]);
 1793|     15|   accum.mul(x[15], y[7]);
 1794|     15|   accum.mul(x[16], y[6]);
 1795|     15|   accum.mul(x[17], y[5]);
 1796|     15|   accum.mul(x[18], y[4]);
 1797|     15|   accum.mul(x[19], y[3]);
 1798|     15|   accum.mul(x[20], y[2]);
 1799|     15|   accum.mul(x[21], y[1]);
 1800|     15|   accum.mul(x[22], y[0]);
 1801|     15|   z[22] = accum.extract();
 1802|     15|   accum.mul(x[0], y[23]);
 1803|     15|   accum.mul(x[1], y[22]);
 1804|     15|   accum.mul(x[2], y[21]);
 1805|     15|   accum.mul(x[3], y[20]);
 1806|     15|   accum.mul(x[4], y[19]);
 1807|     15|   accum.mul(x[5], y[18]);
 1808|     15|   accum.mul(x[6], y[17]);
 1809|     15|   accum.mul(x[7], y[16]);
 1810|     15|   accum.mul(x[8], y[15]);
 1811|     15|   accum.mul(x[9], y[14]);
 1812|     15|   accum.mul(x[10], y[13]);
 1813|     15|   accum.mul(x[11], y[12]);
 1814|     15|   accum.mul(x[12], y[11]);
 1815|     15|   accum.mul(x[13], y[10]);
 1816|     15|   accum.mul(x[14], y[9]);
 1817|     15|   accum.mul(x[15], y[8]);
 1818|     15|   accum.mul(x[16], y[7]);
 1819|     15|   accum.mul(x[17], y[6]);
 1820|     15|   accum.mul(x[18], y[5]);
 1821|     15|   accum.mul(x[19], y[4]);
 1822|     15|   accum.mul(x[20], y[3]);
 1823|     15|   accum.mul(x[21], y[2]);
 1824|     15|   accum.mul(x[22], y[1]);
 1825|     15|   accum.mul(x[23], y[0]);
 1826|     15|   z[23] = accum.extract();
 1827|     15|   accum.mul(x[1], y[23]);
 1828|     15|   accum.mul(x[2], y[22]);
 1829|     15|   accum.mul(x[3], y[21]);
 1830|     15|   accum.mul(x[4], y[20]);
 1831|     15|   accum.mul(x[5], y[19]);
 1832|     15|   accum.mul(x[6], y[18]);
 1833|     15|   accum.mul(x[7], y[17]);
 1834|     15|   accum.mul(x[8], y[16]);
 1835|     15|   accum.mul(x[9], y[15]);
 1836|     15|   accum.mul(x[10], y[14]);
 1837|     15|   accum.mul(x[11], y[13]);
 1838|     15|   accum.mul(x[12], y[12]);
 1839|     15|   accum.mul(x[13], y[11]);
 1840|     15|   accum.mul(x[14], y[10]);
 1841|     15|   accum.mul(x[15], y[9]);
 1842|     15|   accum.mul(x[16], y[8]);
 1843|     15|   accum.mul(x[17], y[7]);
 1844|     15|   accum.mul(x[18], y[6]);
 1845|     15|   accum.mul(x[19], y[5]);
 1846|     15|   accum.mul(x[20], y[4]);
 1847|     15|   accum.mul(x[21], y[3]);
 1848|     15|   accum.mul(x[22], y[2]);
 1849|     15|   accum.mul(x[23], y[1]);
 1850|     15|   z[24] = accum.extract();
 1851|     15|   accum.mul(x[2], y[23]);
 1852|     15|   accum.mul(x[3], y[22]);
 1853|     15|   accum.mul(x[4], y[21]);
 1854|     15|   accum.mul(x[5], y[20]);
 1855|     15|   accum.mul(x[6], y[19]);
 1856|     15|   accum.mul(x[7], y[18]);
 1857|     15|   accum.mul(x[8], y[17]);
 1858|     15|   accum.mul(x[9], y[16]);
 1859|     15|   accum.mul(x[10], y[15]);
 1860|     15|   accum.mul(x[11], y[14]);
 1861|     15|   accum.mul(x[12], y[13]);
 1862|     15|   accum.mul(x[13], y[12]);
 1863|     15|   accum.mul(x[14], y[11]);
 1864|     15|   accum.mul(x[15], y[10]);
 1865|     15|   accum.mul(x[16], y[9]);
 1866|     15|   accum.mul(x[17], y[8]);
 1867|     15|   accum.mul(x[18], y[7]);
 1868|     15|   accum.mul(x[19], y[6]);
 1869|     15|   accum.mul(x[20], y[5]);
 1870|     15|   accum.mul(x[21], y[4]);
 1871|     15|   accum.mul(x[22], y[3]);
 1872|     15|   accum.mul(x[23], y[2]);
 1873|     15|   z[25] = accum.extract();
 1874|     15|   accum.mul(x[3], y[23]);
 1875|     15|   accum.mul(x[4], y[22]);
 1876|     15|   accum.mul(x[5], y[21]);
 1877|     15|   accum.mul(x[6], y[20]);
 1878|     15|   accum.mul(x[7], y[19]);
 1879|     15|   accum.mul(x[8], y[18]);
 1880|     15|   accum.mul(x[9], y[17]);
 1881|     15|   accum.mul(x[10], y[16]);
 1882|     15|   accum.mul(x[11], y[15]);
 1883|     15|   accum.mul(x[12], y[14]);
 1884|     15|   accum.mul(x[13], y[13]);
 1885|     15|   accum.mul(x[14], y[12]);
 1886|     15|   accum.mul(x[15], y[11]);
 1887|     15|   accum.mul(x[16], y[10]);
 1888|     15|   accum.mul(x[17], y[9]);
 1889|     15|   accum.mul(x[18], y[8]);
 1890|     15|   accum.mul(x[19], y[7]);
 1891|     15|   accum.mul(x[20], y[6]);
 1892|     15|   accum.mul(x[21], y[5]);
 1893|     15|   accum.mul(x[22], y[4]);
 1894|     15|   accum.mul(x[23], y[3]);
 1895|     15|   z[26] = accum.extract();
 1896|     15|   accum.mul(x[4], y[23]);
 1897|     15|   accum.mul(x[5], y[22]);
 1898|     15|   accum.mul(x[6], y[21]);
 1899|     15|   accum.mul(x[7], y[20]);
 1900|     15|   accum.mul(x[8], y[19]);
 1901|     15|   accum.mul(x[9], y[18]);
 1902|     15|   accum.mul(x[10], y[17]);
 1903|     15|   accum.mul(x[11], y[16]);
 1904|     15|   accum.mul(x[12], y[15]);
 1905|     15|   accum.mul(x[13], y[14]);
 1906|     15|   accum.mul(x[14], y[13]);
 1907|     15|   accum.mul(x[15], y[12]);
 1908|     15|   accum.mul(x[16], y[11]);
 1909|     15|   accum.mul(x[17], y[10]);
 1910|     15|   accum.mul(x[18], y[9]);
 1911|     15|   accum.mul(x[19], y[8]);
 1912|     15|   accum.mul(x[20], y[7]);
 1913|     15|   accum.mul(x[21], y[6]);
 1914|     15|   accum.mul(x[22], y[5]);
 1915|     15|   accum.mul(x[23], y[4]);
 1916|     15|   z[27] = accum.extract();
 1917|     15|   accum.mul(x[5], y[23]);
 1918|     15|   accum.mul(x[6], y[22]);
 1919|     15|   accum.mul(x[7], y[21]);
 1920|     15|   accum.mul(x[8], y[20]);
 1921|     15|   accum.mul(x[9], y[19]);
 1922|     15|   accum.mul(x[10], y[18]);
 1923|     15|   accum.mul(x[11], y[17]);
 1924|     15|   accum.mul(x[12], y[16]);
 1925|     15|   accum.mul(x[13], y[15]);
 1926|     15|   accum.mul(x[14], y[14]);
 1927|     15|   accum.mul(x[15], y[13]);
 1928|     15|   accum.mul(x[16], y[12]);
 1929|     15|   accum.mul(x[17], y[11]);
 1930|     15|   accum.mul(x[18], y[10]);
 1931|     15|   accum.mul(x[19], y[9]);
 1932|     15|   accum.mul(x[20], y[8]);
 1933|     15|   accum.mul(x[21], y[7]);
 1934|     15|   accum.mul(x[22], y[6]);
 1935|     15|   accum.mul(x[23], y[5]);
 1936|     15|   z[28] = accum.extract();
 1937|     15|   accum.mul(x[6], y[23]);
 1938|     15|   accum.mul(x[7], y[22]);
 1939|     15|   accum.mul(x[8], y[21]);
 1940|     15|   accum.mul(x[9], y[20]);
 1941|     15|   accum.mul(x[10], y[19]);
 1942|     15|   accum.mul(x[11], y[18]);
 1943|     15|   accum.mul(x[12], y[17]);
 1944|     15|   accum.mul(x[13], y[16]);
 1945|     15|   accum.mul(x[14], y[15]);
 1946|     15|   accum.mul(x[15], y[14]);
 1947|     15|   accum.mul(x[16], y[13]);
 1948|     15|   accum.mul(x[17], y[12]);
 1949|     15|   accum.mul(x[18], y[11]);
 1950|     15|   accum.mul(x[19], y[10]);
 1951|     15|   accum.mul(x[20], y[9]);
 1952|     15|   accum.mul(x[21], y[8]);
 1953|     15|   accum.mul(x[22], y[7]);
 1954|     15|   accum.mul(x[23], y[6]);
 1955|     15|   z[29] = accum.extract();
 1956|     15|   accum.mul(x[7], y[23]);
 1957|     15|   accum.mul(x[8], y[22]);
 1958|     15|   accum.mul(x[9], y[21]);
 1959|     15|   accum.mul(x[10], y[20]);
 1960|     15|   accum.mul(x[11], y[19]);
 1961|     15|   accum.mul(x[12], y[18]);
 1962|     15|   accum.mul(x[13], y[17]);
 1963|     15|   accum.mul(x[14], y[16]);
 1964|     15|   accum.mul(x[15], y[15]);
 1965|     15|   accum.mul(x[16], y[14]);
 1966|     15|   accum.mul(x[17], y[13]);
 1967|     15|   accum.mul(x[18], y[12]);
 1968|     15|   accum.mul(x[19], y[11]);
 1969|     15|   accum.mul(x[20], y[10]);
 1970|     15|   accum.mul(x[21], y[9]);
 1971|     15|   accum.mul(x[22], y[8]);
 1972|     15|   accum.mul(x[23], y[7]);
 1973|     15|   z[30] = accum.extract();
 1974|     15|   accum.mul(x[8], y[23]);
 1975|     15|   accum.mul(x[9], y[22]);
 1976|     15|   accum.mul(x[10], y[21]);
 1977|     15|   accum.mul(x[11], y[20]);
 1978|     15|   accum.mul(x[12], y[19]);
 1979|     15|   accum.mul(x[13], y[18]);
 1980|     15|   accum.mul(x[14], y[17]);
 1981|     15|   accum.mul(x[15], y[16]);
 1982|     15|   accum.mul(x[16], y[15]);
 1983|     15|   accum.mul(x[17], y[14]);
 1984|     15|   accum.mul(x[18], y[13]);
 1985|     15|   accum.mul(x[19], y[12]);
 1986|     15|   accum.mul(x[20], y[11]);
 1987|     15|   accum.mul(x[21], y[10]);
 1988|     15|   accum.mul(x[22], y[9]);
 1989|     15|   accum.mul(x[23], y[8]);
 1990|     15|   z[31] = accum.extract();
 1991|     15|   accum.mul(x[9], y[23]);
 1992|     15|   accum.mul(x[10], y[22]);
 1993|     15|   accum.mul(x[11], y[21]);
 1994|     15|   accum.mul(x[12], y[20]);
 1995|     15|   accum.mul(x[13], y[19]);
 1996|     15|   accum.mul(x[14], y[18]);
 1997|     15|   accum.mul(x[15], y[17]);
 1998|     15|   accum.mul(x[16], y[16]);
 1999|     15|   accum.mul(x[17], y[15]);
 2000|     15|   accum.mul(x[18], y[14]);
 2001|     15|   accum.mul(x[19], y[13]);
 2002|     15|   accum.mul(x[20], y[12]);
 2003|     15|   accum.mul(x[21], y[11]);
 2004|     15|   accum.mul(x[22], y[10]);
 2005|     15|   accum.mul(x[23], y[9]);
 2006|     15|   z[32] = accum.extract();
 2007|     15|   accum.mul(x[10], y[23]);
 2008|     15|   accum.mul(x[11], y[22]);
 2009|     15|   accum.mul(x[12], y[21]);
 2010|     15|   accum.mul(x[13], y[20]);
 2011|     15|   accum.mul(x[14], y[19]);
 2012|     15|   accum.mul(x[15], y[18]);
 2013|     15|   accum.mul(x[16], y[17]);
 2014|     15|   accum.mul(x[17], y[16]);
 2015|     15|   accum.mul(x[18], y[15]);
 2016|     15|   accum.mul(x[19], y[14]);
 2017|     15|   accum.mul(x[20], y[13]);
 2018|     15|   accum.mul(x[21], y[12]);
 2019|     15|   accum.mul(x[22], y[11]);
 2020|     15|   accum.mul(x[23], y[10]);
 2021|     15|   z[33] = accum.extract();
 2022|     15|   accum.mul(x[11], y[23]);
 2023|     15|   accum.mul(x[12], y[22]);
 2024|     15|   accum.mul(x[13], y[21]);
 2025|     15|   accum.mul(x[14], y[20]);
 2026|     15|   accum.mul(x[15], y[19]);
 2027|     15|   accum.mul(x[16], y[18]);
 2028|     15|   accum.mul(x[17], y[17]);
 2029|     15|   accum.mul(x[18], y[16]);
 2030|     15|   accum.mul(x[19], y[15]);
 2031|     15|   accum.mul(x[20], y[14]);
 2032|     15|   accum.mul(x[21], y[13]);
 2033|     15|   accum.mul(x[22], y[12]);
 2034|     15|   accum.mul(x[23], y[11]);
 2035|     15|   z[34] = accum.extract();
 2036|     15|   accum.mul(x[12], y[23]);
 2037|     15|   accum.mul(x[13], y[22]);
 2038|     15|   accum.mul(x[14], y[21]);
 2039|     15|   accum.mul(x[15], y[20]);
 2040|     15|   accum.mul(x[16], y[19]);
 2041|     15|   accum.mul(x[17], y[18]);
 2042|     15|   accum.mul(x[18], y[17]);
 2043|     15|   accum.mul(x[19], y[16]);
 2044|     15|   accum.mul(x[20], y[15]);
 2045|     15|   accum.mul(x[21], y[14]);
 2046|     15|   accum.mul(x[22], y[13]);
 2047|     15|   accum.mul(x[23], y[12]);
 2048|     15|   z[35] = accum.extract();
 2049|     15|   accum.mul(x[13], y[23]);
 2050|     15|   accum.mul(x[14], y[22]);
 2051|     15|   accum.mul(x[15], y[21]);
 2052|     15|   accum.mul(x[16], y[20]);
 2053|     15|   accum.mul(x[17], y[19]);
 2054|     15|   accum.mul(x[18], y[18]);
 2055|     15|   accum.mul(x[19], y[17]);
 2056|     15|   accum.mul(x[20], y[16]);
 2057|     15|   accum.mul(x[21], y[15]);
 2058|     15|   accum.mul(x[22], y[14]);
 2059|     15|   accum.mul(x[23], y[13]);
 2060|     15|   z[36] = accum.extract();
 2061|     15|   accum.mul(x[14], y[23]);
 2062|     15|   accum.mul(x[15], y[22]);
 2063|     15|   accum.mul(x[16], y[21]);
 2064|     15|   accum.mul(x[17], y[20]);
 2065|     15|   accum.mul(x[18], y[19]);
 2066|     15|   accum.mul(x[19], y[18]);
 2067|     15|   accum.mul(x[20], y[17]);
 2068|     15|   accum.mul(x[21], y[16]);
 2069|     15|   accum.mul(x[22], y[15]);
 2070|     15|   accum.mul(x[23], y[14]);
 2071|     15|   z[37] = accum.extract();
 2072|     15|   accum.mul(x[15], y[23]);
 2073|     15|   accum.mul(x[16], y[22]);
 2074|     15|   accum.mul(x[17], y[21]);
 2075|     15|   accum.mul(x[18], y[20]);
 2076|     15|   accum.mul(x[19], y[19]);
 2077|     15|   accum.mul(x[20], y[18]);
 2078|     15|   accum.mul(x[21], y[17]);
 2079|     15|   accum.mul(x[22], y[16]);
 2080|     15|   accum.mul(x[23], y[15]);
 2081|     15|   z[38] = accum.extract();
 2082|     15|   accum.mul(x[16], y[23]);
 2083|     15|   accum.mul(x[17], y[22]);
 2084|     15|   accum.mul(x[18], y[21]);
 2085|     15|   accum.mul(x[19], y[20]);
 2086|     15|   accum.mul(x[20], y[19]);
 2087|     15|   accum.mul(x[21], y[18]);
 2088|     15|   accum.mul(x[22], y[17]);
 2089|     15|   accum.mul(x[23], y[16]);
 2090|     15|   z[39] = accum.extract();
 2091|     15|   accum.mul(x[17], y[23]);
 2092|     15|   accum.mul(x[18], y[22]);
 2093|     15|   accum.mul(x[19], y[21]);
 2094|     15|   accum.mul(x[20], y[20]);
 2095|     15|   accum.mul(x[21], y[19]);
 2096|     15|   accum.mul(x[22], y[18]);
 2097|     15|   accum.mul(x[23], y[17]);
 2098|     15|   z[40] = accum.extract();
 2099|     15|   accum.mul(x[18], y[23]);
 2100|     15|   accum.mul(x[19], y[22]);
 2101|     15|   accum.mul(x[20], y[21]);
 2102|     15|   accum.mul(x[21], y[20]);
 2103|     15|   accum.mul(x[22], y[19]);
 2104|     15|   accum.mul(x[23], y[18]);
 2105|     15|   z[41] = accum.extract();
 2106|     15|   accum.mul(x[19], y[23]);
 2107|     15|   accum.mul(x[20], y[22]);
 2108|     15|   accum.mul(x[21], y[21]);
 2109|     15|   accum.mul(x[22], y[20]);
 2110|     15|   accum.mul(x[23], y[19]);
 2111|     15|   z[42] = accum.extract();
 2112|     15|   accum.mul(x[20], y[23]);
 2113|     15|   accum.mul(x[21], y[22]);
 2114|     15|   accum.mul(x[22], y[21]);
 2115|     15|   accum.mul(x[23], y[20]);
 2116|     15|   z[43] = accum.extract();
 2117|     15|   accum.mul(x[21], y[23]);
 2118|     15|   accum.mul(x[22], y[22]);
 2119|     15|   accum.mul(x[23], y[21]);
 2120|     15|   z[44] = accum.extract();
 2121|     15|   accum.mul(x[22], y[23]);
 2122|     15|   accum.mul(x[23], y[22]);
 2123|     15|   z[45] = accum.extract();
 2124|     15|   accum.mul(x[23], y[23]);
 2125|     15|   z[46] = accum.extract();
 2126|     15|   z[47] = accum.extract();
 2127|     15|}

_ZN5Botan12basecase_mulEPmmPKmmS2_m:
   20|    763|void basecase_mul(word z[], size_t z_size, const word x[], size_t x_size, const word y[], size_t y_size) {
   21|    763|   if(z_size < x_size + y_size) {
  ------------------
  |  Branch (21:7): [True: 0, False: 763]
  ------------------
   22|      0|      throw Invalid_Argument("basecase_mul z_size too small");
   23|      0|   }
   24|       |
   25|    763|   const size_t x_size_8 = x_size - (x_size % 8);
   26|       |
   27|    763|   zeroize_buffer(z, z_size);
   28|       |
   29|  6.63k|   for(size_t i = 0; i != y_size; ++i) {
  ------------------
  |  Branch (29:22): [True: 5.86k, False: 763]
  ------------------
   30|  5.86k|      const word y_i = y[i];
   31|       |
   32|  5.86k|      word carry = 0;
   33|       |
   34|  16.7k|      for(size_t j = 0; j != x_size_8; j += 8) {
  ------------------
  |  Branch (34:25): [True: 10.8k, False: 5.86k]
  ------------------
   35|  10.8k|         carry = word8_madd3(z + i + j, x + j, y_i, carry);
   36|  10.8k|      }
   37|       |
   38|  26.5k|      for(size_t j = x_size_8; j != x_size; ++j) {
  ------------------
  |  Branch (38:32): [True: 20.6k, False: 5.86k]
  ------------------
   39|  20.6k|         z[i + j] = word_madd3(x[j], y_i, z[i + j], &carry);
   40|  20.6k|      }
   41|       |
   42|  5.86k|      z[x_size + i] = carry;
   43|  5.86k|   }
   44|    763|}
_ZN5Botan10bigint_mulEPmmPKmmmS2_mmS0_m:
  292|  1.70k|                size_t ws_size) {
  293|  1.70k|   zeroize_buffer(z, z_size);
  294|       |
  295|  1.70k|   if(x_sw == 1) {
  ------------------
  |  Branch (295:7): [True: 0, False: 1.70k]
  ------------------
  296|      0|      bigint_linmul3(z, y, y_sw, x[0]);
  297|  1.70k|   } else if(y_sw == 1) {
  ------------------
  |  Branch (297:14): [True: 535, False: 1.17k]
  ------------------
  298|    535|      bigint_linmul3(z, x, x_sw, y[0]);
  299|  1.17k|   } else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (299:14): [True: 195, False: 978]
  ------------------
  300|    195|      bigint_comba_mul4(z, x, y);
  301|    978|   } else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (301:14): [True: 255, False: 723]
  ------------------
  302|    255|      bigint_comba_mul6(z, x, y);
  303|    723|   } else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (303:14): [True: 18, False: 705]
  ------------------
  304|     18|      bigint_comba_mul8(z, x, y);
  305|    705|   } else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (305:14): [True: 10, False: 695]
  ------------------
  306|     10|      bigint_comba_mul9(z, x, y);
  307|    695|   } else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (307:14): [True: 11, False: 684]
  ------------------
  308|     11|      bigint_comba_mul16(z, x, y);
  309|    684|   } else if(sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (309:14): [True: 15, False: 669]
  ------------------
  310|     15|      bigint_comba_mul24(z, x, y);
  311|    669|   } else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || y_sw < KARATSUBA_MULTIPLY_THRESHOLD || workspace == nullptr) {
  ------------------
  |  Branch (311:14): [True: 603, False: 66]
  |  Branch (311:53): [True: 5, False: 61]
  |  Branch (311:92): [True: 0, False: 61]
  ------------------
  312|    608|      basecase_mul(z, z_size, x, x_sw, y, y_sw);
  313|    608|   } else {
  314|     61|      const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw);
  315|       |
  316|     61|      if(N > 0 && z_size >= 2 * N && ws_size >= 2 * N) {
  ------------------
  |  Branch (316:10): [True: 61, False: 0]
  |  Branch (316:19): [True: 61, False: 0]
  |  Branch (316:38): [True: 53, False: 8]
  ------------------
  317|     53|         karatsuba_mul(z, x, y, N, workspace);
  318|     53|      } else {
  319|      8|         basecase_mul(z, z_size, x, x_sw, y, y_sw);
  320|      8|      }
  321|     61|   }
  322|  1.70k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_114karatsuba_sizeEmmmmm:
  203|     61|size_t karatsuba_size(size_t z_size, size_t x_size, size_t x_sw, size_t y_size, size_t y_sw) {
  204|     61|   if(x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size) {
  ------------------
  |  Branch (204:7): [True: 0, False: 61]
  |  Branch (204:24): [True: 0, False: 61]
  |  Branch (204:41): [True: 0, False: 61]
  |  Branch (204:58): [True: 0, False: 61]
  ------------------
  205|      0|      return 0;
  206|      0|   }
  207|       |
  208|     61|   if(((x_size == x_sw) && (x_size % 2 != 0)) || ((y_size == y_sw) && (y_size % 2 != 0))) {
  ------------------
  |  Branch (208:8): [True: 0, False: 61]
  |  Branch (208:28): [True: 0, False: 0]
  |  Branch (208:51): [True: 0, False: 61]
  |  Branch (208:71): [True: 0, False: 0]
  ------------------
  209|      0|      return 0;
  210|      0|   }
  211|       |
  212|     61|   const size_t start = (x_sw > y_sw) ? x_sw : y_sw;
  ------------------
  |  Branch (212:25): [True: 28, False: 33]
  ------------------
  213|     61|   const size_t end = (x_size < y_size) ? x_size : y_size;
  ------------------
  |  Branch (213:23): [True: 28, False: 33]
  ------------------
  214|       |
  215|     61|   if(start == end) {
  ------------------
  |  Branch (215:7): [True: 0, False: 61]
  ------------------
  216|      0|      if(start % 2 != 0) {
  ------------------
  |  Branch (216:10): [True: 0, False: 0]
  ------------------
  217|      0|         return 0;
  218|      0|      }
  219|      0|      return start;
  220|      0|   }
  221|       |
  222|     90|   for(size_t j = start; j <= end; ++j) {
  ------------------
  |  Branch (222:26): [True: 90, False: 0]
  ------------------
  223|     90|      if(j % 2 != 0) {
  ------------------
  |  Branch (223:10): [True: 29, False: 61]
  ------------------
  224|     29|         continue;
  225|     29|      }
  226|       |
  227|     61|      if(2 * j > z_size) {
  ------------------
  |  Branch (227:10): [True: 0, False: 61]
  ------------------
  228|      0|         return 0;
  229|      0|      }
  230|       |
  231|     61|      if(x_sw <= j && j <= x_size && y_sw <= j && j <= y_size) {
  ------------------
  |  Branch (231:10): [True: 61, False: 0]
  |  Branch (231:23): [True: 61, False: 0]
  |  Branch (231:38): [True: 61, False: 0]
  |  Branch (231:51): [True: 61, False: 0]
  ------------------
  232|     61|         if(j % 4 == 2 && (j + 2) <= x_size && (j + 2) <= y_size && 2 * (j + 2) <= z_size) {
  ------------------
  |  Branch (232:13): [True: 26, False: 35]
  |  Branch (232:27): [True: 22, False: 4]
  |  Branch (232:48): [True: 22, False: 0]
  |  Branch (232:69): [True: 2, False: 20]
  ------------------
  233|      2|            return j + 2;
  234|      2|         }
  235|     59|         return j;
  236|     61|      }
  237|     61|   }
  238|       |
  239|      0|   return 0;
  240|     61|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_113karatsuba_mulEPmPKmS3_mS1_:
   80|    212|void karatsuba_mul(word z[], const word x[], const word y[], size_t N, word workspace[]) {
   81|    212|   if(N < KARATSUBA_MULTIPLY_THRESHOLD || N % 2 != 0) {
  ------------------
  |  Branch (81:7): [True: 159, False: 53]
  |  Branch (81:43): [True: 0, False: 53]
  ------------------
   82|    159|      switch(N) {
   83|      0|         case 6:
  ------------------
  |  Branch (83:10): [True: 0, False: 159]
  ------------------
   84|      0|            return bigint_comba_mul6(z, x, y);
   85|      0|         case 8:
  ------------------
  |  Branch (85:10): [True: 0, False: 159]
  ------------------
   86|      0|            return bigint_comba_mul8(z, x, y);
   87|      0|         case 9:
  ------------------
  |  Branch (87:10): [True: 0, False: 159]
  ------------------
   88|      0|            return bigint_comba_mul9(z, x, y);
   89|     12|         case 16:
  ------------------
  |  Branch (89:10): [True: 12, False: 147]
  ------------------
   90|     12|            return bigint_comba_mul16(z, x, y);
   91|      0|         case 24:
  ------------------
  |  Branch (91:10): [True: 0, False: 159]
  ------------------
   92|      0|            return bigint_comba_mul24(z, x, y);
   93|    147|         default:
  ------------------
  |  Branch (93:10): [True: 147, False: 12]
  ------------------
   94|    147|            return basecase_mul(z, 2 * N, x, N, y, N);
   95|    159|      }
   96|    159|   }
   97|       |
   98|     53|   const size_t N2 = N / 2;
   99|       |
  100|     53|   const word* x0 = x;
  101|     53|   const word* x1 = x + N2;
  102|     53|   const word* y0 = y;
  103|     53|   const word* y1 = y + N2;
  104|     53|   word* z0 = z;
  105|     53|   word* z1 = z + N;
  106|       |
  107|     53|   word* ws0 = workspace;
  108|     53|   word* ws1 = workspace + N;
  109|       |
  110|     53|   zeroize_buffer(workspace, 2 * N);
  111|       |
  112|       |   /*
  113|       |   * If either of cmp0 or cmp1 is zero then z0 or z1 resp is zero here,
  114|       |   * resulting in a no-op - z0*z1 will be equal to zero so we don't need to do
  115|       |   * anything, zeroize_buffer above already set the correct result.
  116|       |   *
  117|       |   * However we ignore the result of the comparisons and always perform the
  118|       |   * subtractions and recursively multiply to avoid the timing channel.
  119|       |   */
  120|       |
  121|       |   // First compute (X_lo - X_hi)*(Y_hi - Y_lo)
  122|     53|   const auto cmp0 = bigint_sub_abs(z0, x0, x1, N2, workspace);
  123|     53|   const auto cmp1 = bigint_sub_abs(z1, y1, y0, N2, workspace);
  124|     53|   const auto neg_mask = ~(cmp0 ^ cmp1);
  125|       |
  126|     53|   karatsuba_mul(ws0, z0, z1, N2, ws1);
  127|       |
  128|       |   // Compute X_lo * Y_lo
  129|     53|   karatsuba_mul(z0, x0, y0, N2, ws1);
  130|       |
  131|       |   // Compute X_hi * Y_hi
  132|     53|   karatsuba_mul(z1, x1, y1, N2, ws1);
  133|       |
  134|     53|   const word ws_carry = bigint_add3(ws1, z0, N, z1, N);
  135|     53|   word z_carry = bigint_add2(z + N2, N, ws1, N);
  136|       |
  137|     53|   z_carry += bigint_add2(z + N + N2, N2, &ws_carry, 1);
  138|     53|   bigint_add2(z + N + N2, N2, &z_carry, 1);
  139|       |
  140|     53|   zeroize_buffer(workspace + N, N2);
  141|       |
  142|     53|   bigint_cnd_add(neg_mask.value(), z + N2, workspace, 2 * N - N2);
  143|     53|   bigint_cnd_sub((~neg_mask).value(), z + N2, workspace, 2 * N - N2);
  144|     53|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm4EEEbmmmmm:
  272|  1.17k|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) {
  273|  1.17k|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 723, False: 450]
  |  Branch (273:26): [True: 723, False: 0]
  |  Branch (273:42): [True: 721, False: 2]
  |  Branch (273:56): [True: 721, False: 0]
  |  Branch (273:72): [True: 195, False: 526]
  ------------------
  274|  1.17k|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm6EEEbmmmmm:
  272|    978|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) {
  273|    978|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 782, False: 196]
  |  Branch (273:26): [True: 782, False: 0]
  |  Branch (273:42): [True: 781, False: 1]
  |  Branch (273:56): [True: 781, False: 0]
  |  Branch (273:72): [True: 255, False: 526]
  ------------------
  274|    978|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm8EEEbmmmmm:
  272|    723|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) {
  273|    723|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 545, False: 178]
  |  Branch (273:26): [True: 19, False: 526]
  |  Branch (273:42): [True: 18, False: 1]
  |  Branch (273:56): [True: 18, False: 0]
  |  Branch (273:72): [True: 18, False: 0]
  ------------------
  274|    723|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm9EEEbmmmmm:
  272|    705|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) {
  273|    705|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 539, False: 166]
  |  Branch (273:26): [True: 13, False: 526]
  |  Branch (273:42): [True: 10, False: 3]
  |  Branch (273:56): [True: 10, False: 0]
  |  Branch (273:72): [True: 10, False: 0]
  ------------------
  274|    705|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm16EEEbmmmmm:
  272|    695|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) {
  273|    695|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 567, False: 128]
  |  Branch (273:26): [True: 32, False: 535]
  |  Branch (273:42): [True: 31, False: 1]
  |  Branch (273:56): [True: 31, False: 0]
  |  Branch (273:72): [True: 11, False: 20]
  ------------------
  274|    695|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm24EEEbmmmmm:
  272|    684|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) {
  273|    684|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 598, False: 86]
  |  Branch (273:26): [True: 45, False: 553]
  |  Branch (273:42): [True: 44, False: 1]
  |  Branch (273:56): [True: 44, False: 0]
  |  Branch (273:72): [True: 15, False: 29]
  ------------------
  274|    684|}

_ZN5Botan16bigint_mulx_mul4EPmPKmS2_:
  120|    195|void bigint_mulx_mul4(word z[8], const word x[4], const word y[4]) {
  121|       |   // clang-format off
  122|    195|   asm(
  123|    195|      "xorl %%r8d, %%r8d\n\t"
  124|    195|      "xorl %%r9d, %%r9d\n\t"
  125|    195|      "xorl %%r10d, %%r10d\n\t"
  126|    195|      "xorl %%r11d, %%r11d\n\t"
  127|       |
  128|    195|      "movq 0(%[y]), %%rdx\n\t"  // row 0: x * y[0]
  129|    195|      "xorl %%eax, %%eax\n\t"
  130|    195|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  131|    195|      "adcx %%rax, %%r8\n\t"
  132|    195|      "movq %%r8, 0(%[z])\n\t"
  133|    195|      "mulx 8(%[x]), %%rax, %%r8\n\t"
  134|    195|      "adox %%rcx, %%rax\n\t"
  135|    195|      "adcx %%rax, %%r9\n\t"
  136|    195|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  137|    195|      "adox %%r8, %%rax\n\t"
  138|    195|      "adcx %%rax, %%r10\n\t"
  139|    195|      "mulx 24(%[x]), %%rax, %%r8\n\t"
  140|    195|      "adox %%rcx, %%rax\n\t"
  141|    195|      "adcx %%rax, %%r11\n\t"
  142|    195|      "movl $0, %%eax\n\t"
  143|    195|      "adox %%rax, %%r8\n\t"
  144|    195|      "adcx %%rax, %%r8\n\t"
  145|       |
  146|    195|      "movq 8(%[y]), %%rdx\n\t"  // row 1: x * y[1]
  147|    195|      "xorl %%eax, %%eax\n\t"
  148|    195|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  149|    195|      "adcx %%rax, %%r9\n\t"
  150|    195|      "movq %%r9, 8(%[z])\n\t"
  151|    195|      "mulx 8(%[x]), %%rax, %%r9\n\t"
  152|    195|      "adox %%rcx, %%rax\n\t"
  153|    195|      "adcx %%rax, %%r10\n\t"
  154|    195|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  155|    195|      "adox %%r9, %%rax\n\t"
  156|    195|      "adcx %%rax, %%r11\n\t"
  157|    195|      "mulx 24(%[x]), %%rax, %%r9\n\t"
  158|    195|      "adox %%rcx, %%rax\n\t"
  159|    195|      "adcx %%rax, %%r8\n\t"
  160|    195|      "movl $0, %%eax\n\t"
  161|    195|      "adox %%rax, %%r9\n\t"
  162|    195|      "adcx %%rax, %%r9\n\t"
  163|       |
  164|    195|      "movq 16(%[y]), %%rdx\n\t"  // row 2: x * y[2]
  165|    195|      "xorl %%eax, %%eax\n\t"
  166|    195|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  167|    195|      "adcx %%rax, %%r10\n\t"
  168|    195|      "movq %%r10, 16(%[z])\n\t"
  169|    195|      "mulx 8(%[x]), %%rax, %%r10\n\t"
  170|    195|      "adox %%rcx, %%rax\n\t"
  171|    195|      "adcx %%rax, %%r11\n\t"
  172|    195|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  173|    195|      "adox %%r10, %%rax\n\t"
  174|    195|      "adcx %%rax, %%r8\n\t"
  175|    195|      "mulx 24(%[x]), %%rax, %%r10\n\t"
  176|    195|      "adox %%rcx, %%rax\n\t"
  177|    195|      "adcx %%rax, %%r9\n\t"
  178|    195|      "movl $0, %%eax\n\t"
  179|    195|      "adox %%rax, %%r10\n\t"
  180|    195|      "adcx %%rax, %%r10\n\t"
  181|       |
  182|    195|      "movq 24(%[y]), %%rdx\n\t"  // row 3: x * y[3]
  183|    195|      "xorl %%eax, %%eax\n\t"
  184|    195|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  185|    195|      "adcx %%rax, %%r11\n\t"
  186|    195|      "movq %%r11, 24(%[z])\n\t"
  187|    195|      "mulx 8(%[x]), %%rax, %%r11\n\t"
  188|    195|      "adox %%rcx, %%rax\n\t"
  189|    195|      "adcx %%rax, %%r8\n\t"
  190|    195|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  191|    195|      "adox %%r11, %%rax\n\t"
  192|    195|      "adcx %%rax, %%r9\n\t"
  193|    195|      "mulx 24(%[x]), %%rax, %%r11\n\t"
  194|    195|      "adox %%rcx, %%rax\n\t"
  195|    195|      "adcx %%rax, %%r10\n\t"
  196|    195|      "movl $0, %%eax\n\t"
  197|    195|      "adox %%rax, %%r11\n\t"
  198|    195|      "adcx %%rax, %%r11\n\t"
  199|       |
  200|    195|      "movq %%r8, 32(%[z])\n\t"
  201|    195|      "movq %%r9, 40(%[z])\n\t"
  202|    195|      "movq %%r10, 48(%[z])\n\t"
  203|    195|      "movq %%r11, 56(%[z])\n\t"
  204|    195|      :
  205|    195|      : [z] "r"(z), [x] "r"(x), [y] "r"(y)
  206|    195|      : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "cc", "memory");
  207|       |   // clang-format on
  208|    195|}
_ZN5Botan16bigint_mulx_mul6EPmPKmS2_:
  367|    255|void bigint_mulx_mul6(word z[12], const word x[6], const word y[6]) {
  368|       |   // clang-format off
  369|    255|   asm(
  370|    255|      "xorl %%r8d, %%r8d\n\t"
  371|    255|      "xorl %%r9d, %%r9d\n\t"
  372|    255|      "xorl %%r10d, %%r10d\n\t"
  373|    255|      "xorl %%r11d, %%r11d\n\t"
  374|    255|      "xorl %%r12d, %%r12d\n\t"
  375|    255|      "xorl %%r13d, %%r13d\n\t"
  376|       |
  377|    255|      "movq 0(%[y]), %%rdx\n\t"  // row 0: x * y[0]
  378|    255|      "xorl %%eax, %%eax\n\t"
  379|    255|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  380|    255|      "adcx %%rax, %%r8\n\t"
  381|    255|      "movq %%r8, 0(%[z])\n\t"
  382|    255|      "mulx 8(%[x]), %%rax, %%r8\n\t"
  383|    255|      "adox %%rcx, %%rax\n\t"
  384|    255|      "adcx %%rax, %%r9\n\t"
  385|    255|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  386|    255|      "adox %%r8, %%rax\n\t"
  387|    255|      "adcx %%rax, %%r10\n\t"
  388|    255|      "mulx 24(%[x]), %%rax, %%r8\n\t"
  389|    255|      "adox %%rcx, %%rax\n\t"
  390|    255|      "adcx %%rax, %%r11\n\t"
  391|    255|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  392|    255|      "adox %%r8, %%rax\n\t"
  393|    255|      "adcx %%rax, %%r12\n\t"
  394|    255|      "mulx 40(%[x]), %%rax, %%r8\n\t"
  395|    255|      "adox %%rcx, %%rax\n\t"
  396|    255|      "adcx %%rax, %%r13\n\t"
  397|    255|      "movl $0, %%eax\n\t"
  398|    255|      "adox %%rax, %%r8\n\t"
  399|    255|      "adcx %%rax, %%r8\n\t"
  400|       |
  401|    255|      "movq 8(%[y]), %%rdx\n\t"  // row 1: x * y[1]
  402|    255|      "xorl %%eax, %%eax\n\t"
  403|    255|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  404|    255|      "adcx %%rax, %%r9\n\t"
  405|    255|      "movq %%r9, 8(%[z])\n\t"
  406|    255|      "mulx 8(%[x]), %%rax, %%r9\n\t"
  407|    255|      "adox %%rcx, %%rax\n\t"
  408|    255|      "adcx %%rax, %%r10\n\t"
  409|    255|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  410|    255|      "adox %%r9, %%rax\n\t"
  411|    255|      "adcx %%rax, %%r11\n\t"
  412|    255|      "mulx 24(%[x]), %%rax, %%r9\n\t"
  413|    255|      "adox %%rcx, %%rax\n\t"
  414|    255|      "adcx %%rax, %%r12\n\t"
  415|    255|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  416|    255|      "adox %%r9, %%rax\n\t"
  417|    255|      "adcx %%rax, %%r13\n\t"
  418|    255|      "mulx 40(%[x]), %%rax, %%r9\n\t"
  419|    255|      "adox %%rcx, %%rax\n\t"
  420|    255|      "adcx %%rax, %%r8\n\t"
  421|    255|      "movl $0, %%eax\n\t"
  422|    255|      "adox %%rax, %%r9\n\t"
  423|    255|      "adcx %%rax, %%r9\n\t"
  424|       |
  425|    255|      "movq 16(%[y]), %%rdx\n\t"  // row 2: x * y[2]
  426|    255|      "xorl %%eax, %%eax\n\t"
  427|    255|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  428|    255|      "adcx %%rax, %%r10\n\t"
  429|    255|      "movq %%r10, 16(%[z])\n\t"
  430|    255|      "mulx 8(%[x]), %%rax, %%r10\n\t"
  431|    255|      "adox %%rcx, %%rax\n\t"
  432|    255|      "adcx %%rax, %%r11\n\t"
  433|    255|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  434|    255|      "adox %%r10, %%rax\n\t"
  435|    255|      "adcx %%rax, %%r12\n\t"
  436|    255|      "mulx 24(%[x]), %%rax, %%r10\n\t"
  437|    255|      "adox %%rcx, %%rax\n\t"
  438|    255|      "adcx %%rax, %%r13\n\t"
  439|    255|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  440|    255|      "adox %%r10, %%rax\n\t"
  441|    255|      "adcx %%rax, %%r8\n\t"
  442|    255|      "mulx 40(%[x]), %%rax, %%r10\n\t"
  443|    255|      "adox %%rcx, %%rax\n\t"
  444|    255|      "adcx %%rax, %%r9\n\t"
  445|    255|      "movl $0, %%eax\n\t"
  446|    255|      "adox %%rax, %%r10\n\t"
  447|    255|      "adcx %%rax, %%r10\n\t"
  448|       |
  449|    255|      "movq 24(%[y]), %%rdx\n\t"  // row 3: x * y[3]
  450|    255|      "xorl %%eax, %%eax\n\t"
  451|    255|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  452|    255|      "adcx %%rax, %%r11\n\t"
  453|    255|      "movq %%r11, 24(%[z])\n\t"
  454|    255|      "mulx 8(%[x]), %%rax, %%r11\n\t"
  455|    255|      "adox %%rcx, %%rax\n\t"
  456|    255|      "adcx %%rax, %%r12\n\t"
  457|    255|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  458|    255|      "adox %%r11, %%rax\n\t"
  459|    255|      "adcx %%rax, %%r13\n\t"
  460|    255|      "mulx 24(%[x]), %%rax, %%r11\n\t"
  461|    255|      "adox %%rcx, %%rax\n\t"
  462|    255|      "adcx %%rax, %%r8\n\t"
  463|    255|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  464|    255|      "adox %%r11, %%rax\n\t"
  465|    255|      "adcx %%rax, %%r9\n\t"
  466|    255|      "mulx 40(%[x]), %%rax, %%r11\n\t"
  467|    255|      "adox %%rcx, %%rax\n\t"
  468|    255|      "adcx %%rax, %%r10\n\t"
  469|    255|      "movl $0, %%eax\n\t"
  470|    255|      "adox %%rax, %%r11\n\t"
  471|    255|      "adcx %%rax, %%r11\n\t"
  472|       |
  473|    255|      "movq 32(%[y]), %%rdx\n\t"  // row 4: x * y[4]
  474|    255|      "xorl %%eax, %%eax\n\t"
  475|    255|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  476|    255|      "adcx %%rax, %%r12\n\t"
  477|    255|      "movq %%r12, 32(%[z])\n\t"
  478|    255|      "mulx 8(%[x]), %%rax, %%r12\n\t"
  479|    255|      "adox %%rcx, %%rax\n\t"
  480|    255|      "adcx %%rax, %%r13\n\t"
  481|    255|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  482|    255|      "adox %%r12, %%rax\n\t"
  483|    255|      "adcx %%rax, %%r8\n\t"
  484|    255|      "mulx 24(%[x]), %%rax, %%r12\n\t"
  485|    255|      "adox %%rcx, %%rax\n\t"
  486|    255|      "adcx %%rax, %%r9\n\t"
  487|    255|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  488|    255|      "adox %%r12, %%rax\n\t"
  489|    255|      "adcx %%rax, %%r10\n\t"
  490|    255|      "mulx 40(%[x]), %%rax, %%r12\n\t"
  491|    255|      "adox %%rcx, %%rax\n\t"
  492|    255|      "adcx %%rax, %%r11\n\t"
  493|    255|      "movl $0, %%eax\n\t"
  494|    255|      "adox %%rax, %%r12\n\t"
  495|    255|      "adcx %%rax, %%r12\n\t"
  496|       |
  497|    255|      "movq 40(%[y]), %%rdx\n\t"  // row 5: x * y[5]
  498|    255|      "xorl %%eax, %%eax\n\t"
  499|    255|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  500|    255|      "adcx %%rax, %%r13\n\t"
  501|    255|      "movq %%r13, 40(%[z])\n\t"
  502|    255|      "mulx 8(%[x]), %%rax, %%r13\n\t"
  503|    255|      "adox %%rcx, %%rax\n\t"
  504|    255|      "adcx %%rax, %%r8\n\t"
  505|    255|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  506|    255|      "adox %%r13, %%rax\n\t"
  507|    255|      "adcx %%rax, %%r9\n\t"
  508|    255|      "mulx 24(%[x]), %%rax, %%r13\n\t"
  509|    255|      "adox %%rcx, %%rax\n\t"
  510|    255|      "adcx %%rax, %%r10\n\t"
  511|    255|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  512|    255|      "adox %%r13, %%rax\n\t"
  513|    255|      "adcx %%rax, %%r11\n\t"
  514|    255|      "mulx 40(%[x]), %%rax, %%r13\n\t"
  515|    255|      "adox %%rcx, %%rax\n\t"
  516|    255|      "adcx %%rax, %%r12\n\t"
  517|    255|      "movl $0, %%eax\n\t"
  518|    255|      "adox %%rax, %%r13\n\t"
  519|    255|      "adcx %%rax, %%r13\n\t"
  520|       |
  521|    255|      "movq %%r8, 48(%[z])\n\t"
  522|    255|      "movq %%r9, 56(%[z])\n\t"
  523|    255|      "movq %%r10, 64(%[z])\n\t"
  524|    255|      "movq %%r11, 72(%[z])\n\t"
  525|    255|      "movq %%r12, 80(%[z])\n\t"
  526|    255|      "movq %%r13, 88(%[z])\n\t"
  527|    255|      :
  528|    255|      : [z] "r"(z), [x] "r"(x), [y] "r"(y)
  529|    255|      : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "cc", "memory");
  530|       |   // clang-format on
  531|    255|}
_ZN5Botan16bigint_mulx_mul8EPmPKmS2_:
  766|     18|void bigint_mulx_mul8(word z[16], const word x[8], const word y[8]) {
  767|       |   // clang-format off
  768|     18|   asm(
  769|     18|      "xorl %%r8d, %%r8d\n\t"
  770|     18|      "xorl %%r9d, %%r9d\n\t"
  771|     18|      "xorl %%r10d, %%r10d\n\t"
  772|     18|      "xorl %%r11d, %%r11d\n\t"
  773|     18|      "xorl %%r12d, %%r12d\n\t"
  774|     18|      "xorl %%r13d, %%r13d\n\t"
  775|     18|      "xorl %%r14d, %%r14d\n\t"
  776|     18|      "xorl %%r15d, %%r15d\n\t"
  777|       |
  778|     18|      "movq 0(%[y]), %%rdx\n\t"  // row 0: x * y[0]
  779|     18|      "xorl %%eax, %%eax\n\t"
  780|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  781|     18|      "adcx %%rax, %%r8\n\t"
  782|     18|      "movq %%r8, 0(%[z])\n\t"
  783|     18|      "mulx 8(%[x]), %%rax, %%r8\n\t"
  784|     18|      "adox %%rcx, %%rax\n\t"
  785|     18|      "adcx %%rax, %%r9\n\t"
  786|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  787|     18|      "adox %%r8, %%rax\n\t"
  788|     18|      "adcx %%rax, %%r10\n\t"
  789|     18|      "mulx 24(%[x]), %%rax, %%r8\n\t"
  790|     18|      "adox %%rcx, %%rax\n\t"
  791|     18|      "adcx %%rax, %%r11\n\t"
  792|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  793|     18|      "adox %%r8, %%rax\n\t"
  794|     18|      "adcx %%rax, %%r12\n\t"
  795|     18|      "mulx 40(%[x]), %%rax, %%r8\n\t"
  796|     18|      "adox %%rcx, %%rax\n\t"
  797|     18|      "adcx %%rax, %%r13\n\t"
  798|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  799|     18|      "adox %%r8, %%rax\n\t"
  800|     18|      "adcx %%rax, %%r14\n\t"
  801|     18|      "mulx 56(%[x]), %%rax, %%r8\n\t"
  802|     18|      "adox %%rcx, %%rax\n\t"
  803|     18|      "adcx %%rax, %%r15\n\t"
  804|     18|      "movl $0, %%eax\n\t"
  805|     18|      "adox %%rax, %%r8\n\t"
  806|     18|      "adcx %%rax, %%r8\n\t"
  807|       |
  808|     18|      "movq 8(%[y]), %%rdx\n\t"  // row 1: x * y[1]
  809|     18|      "xorl %%eax, %%eax\n\t"
  810|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  811|     18|      "adcx %%rax, %%r9\n\t"
  812|     18|      "movq %%r9, 8(%[z])\n\t"
  813|     18|      "mulx 8(%[x]), %%rax, %%r9\n\t"
  814|     18|      "adox %%rcx, %%rax\n\t"
  815|     18|      "adcx %%rax, %%r10\n\t"
  816|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  817|     18|      "adox %%r9, %%rax\n\t"
  818|     18|      "adcx %%rax, %%r11\n\t"
  819|     18|      "mulx 24(%[x]), %%rax, %%r9\n\t"
  820|     18|      "adox %%rcx, %%rax\n\t"
  821|     18|      "adcx %%rax, %%r12\n\t"
  822|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  823|     18|      "adox %%r9, %%rax\n\t"
  824|     18|      "adcx %%rax, %%r13\n\t"
  825|     18|      "mulx 40(%[x]), %%rax, %%r9\n\t"
  826|     18|      "adox %%rcx, %%rax\n\t"
  827|     18|      "adcx %%rax, %%r14\n\t"
  828|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  829|     18|      "adox %%r9, %%rax\n\t"
  830|     18|      "adcx %%rax, %%r15\n\t"
  831|     18|      "mulx 56(%[x]), %%rax, %%r9\n\t"
  832|     18|      "adox %%rcx, %%rax\n\t"
  833|     18|      "adcx %%rax, %%r8\n\t"
  834|     18|      "movl $0, %%eax\n\t"
  835|     18|      "adox %%rax, %%r9\n\t"
  836|     18|      "adcx %%rax, %%r9\n\t"
  837|       |
  838|     18|      "movq 16(%[y]), %%rdx\n\t"  // row 2: x * y[2]
  839|     18|      "xorl %%eax, %%eax\n\t"
  840|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  841|     18|      "adcx %%rax, %%r10\n\t"
  842|     18|      "movq %%r10, 16(%[z])\n\t"
  843|     18|      "mulx 8(%[x]), %%rax, %%r10\n\t"
  844|     18|      "adox %%rcx, %%rax\n\t"
  845|     18|      "adcx %%rax, %%r11\n\t"
  846|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  847|     18|      "adox %%r10, %%rax\n\t"
  848|     18|      "adcx %%rax, %%r12\n\t"
  849|     18|      "mulx 24(%[x]), %%rax, %%r10\n\t"
  850|     18|      "adox %%rcx, %%rax\n\t"
  851|     18|      "adcx %%rax, %%r13\n\t"
  852|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  853|     18|      "adox %%r10, %%rax\n\t"
  854|     18|      "adcx %%rax, %%r14\n\t"
  855|     18|      "mulx 40(%[x]), %%rax, %%r10\n\t"
  856|     18|      "adox %%rcx, %%rax\n\t"
  857|     18|      "adcx %%rax, %%r15\n\t"
  858|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  859|     18|      "adox %%r10, %%rax\n\t"
  860|     18|      "adcx %%rax, %%r8\n\t"
  861|     18|      "mulx 56(%[x]), %%rax, %%r10\n\t"
  862|     18|      "adox %%rcx, %%rax\n\t"
  863|     18|      "adcx %%rax, %%r9\n\t"
  864|     18|      "movl $0, %%eax\n\t"
  865|     18|      "adox %%rax, %%r10\n\t"
  866|     18|      "adcx %%rax, %%r10\n\t"
  867|       |
  868|     18|      "movq 24(%[y]), %%rdx\n\t"  // row 3: x * y[3]
  869|     18|      "xorl %%eax, %%eax\n\t"
  870|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  871|     18|      "adcx %%rax, %%r11\n\t"
  872|     18|      "movq %%r11, 24(%[z])\n\t"
  873|     18|      "mulx 8(%[x]), %%rax, %%r11\n\t"
  874|     18|      "adox %%rcx, %%rax\n\t"
  875|     18|      "adcx %%rax, %%r12\n\t"
  876|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  877|     18|      "adox %%r11, %%rax\n\t"
  878|     18|      "adcx %%rax, %%r13\n\t"
  879|     18|      "mulx 24(%[x]), %%rax, %%r11\n\t"
  880|     18|      "adox %%rcx, %%rax\n\t"
  881|     18|      "adcx %%rax, %%r14\n\t"
  882|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  883|     18|      "adox %%r11, %%rax\n\t"
  884|     18|      "adcx %%rax, %%r15\n\t"
  885|     18|      "mulx 40(%[x]), %%rax, %%r11\n\t"
  886|     18|      "adox %%rcx, %%rax\n\t"
  887|     18|      "adcx %%rax, %%r8\n\t"
  888|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  889|     18|      "adox %%r11, %%rax\n\t"
  890|     18|      "adcx %%rax, %%r9\n\t"
  891|     18|      "mulx 56(%[x]), %%rax, %%r11\n\t"
  892|     18|      "adox %%rcx, %%rax\n\t"
  893|     18|      "adcx %%rax, %%r10\n\t"
  894|     18|      "movl $0, %%eax\n\t"
  895|     18|      "adox %%rax, %%r11\n\t"
  896|     18|      "adcx %%rax, %%r11\n\t"
  897|       |
  898|     18|      "movq 32(%[y]), %%rdx\n\t"  // row 4: x * y[4]
  899|     18|      "xorl %%eax, %%eax\n\t"
  900|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  901|     18|      "adcx %%rax, %%r12\n\t"
  902|     18|      "movq %%r12, 32(%[z])\n\t"
  903|     18|      "mulx 8(%[x]), %%rax, %%r12\n\t"
  904|     18|      "adox %%rcx, %%rax\n\t"
  905|     18|      "adcx %%rax, %%r13\n\t"
  906|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  907|     18|      "adox %%r12, %%rax\n\t"
  908|     18|      "adcx %%rax, %%r14\n\t"
  909|     18|      "mulx 24(%[x]), %%rax, %%r12\n\t"
  910|     18|      "adox %%rcx, %%rax\n\t"
  911|     18|      "adcx %%rax, %%r15\n\t"
  912|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  913|     18|      "adox %%r12, %%rax\n\t"
  914|     18|      "adcx %%rax, %%r8\n\t"
  915|     18|      "mulx 40(%[x]), %%rax, %%r12\n\t"
  916|     18|      "adox %%rcx, %%rax\n\t"
  917|     18|      "adcx %%rax, %%r9\n\t"
  918|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  919|     18|      "adox %%r12, %%rax\n\t"
  920|     18|      "adcx %%rax, %%r10\n\t"
  921|     18|      "mulx 56(%[x]), %%rax, %%r12\n\t"
  922|     18|      "adox %%rcx, %%rax\n\t"
  923|     18|      "adcx %%rax, %%r11\n\t"
  924|     18|      "movl $0, %%eax\n\t"
  925|     18|      "adox %%rax, %%r12\n\t"
  926|     18|      "adcx %%rax, %%r12\n\t"
  927|       |
  928|     18|      "movq 40(%[y]), %%rdx\n\t"  // row 5: x * y[5]
  929|     18|      "xorl %%eax, %%eax\n\t"
  930|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  931|     18|      "adcx %%rax, %%r13\n\t"
  932|     18|      "movq %%r13, 40(%[z])\n\t"
  933|     18|      "mulx 8(%[x]), %%rax, %%r13\n\t"
  934|     18|      "adox %%rcx, %%rax\n\t"
  935|     18|      "adcx %%rax, %%r14\n\t"
  936|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  937|     18|      "adox %%r13, %%rax\n\t"
  938|     18|      "adcx %%rax, %%r15\n\t"
  939|     18|      "mulx 24(%[x]), %%rax, %%r13\n\t"
  940|     18|      "adox %%rcx, %%rax\n\t"
  941|     18|      "adcx %%rax, %%r8\n\t"
  942|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  943|     18|      "adox %%r13, %%rax\n\t"
  944|     18|      "adcx %%rax, %%r9\n\t"
  945|     18|      "mulx 40(%[x]), %%rax, %%r13\n\t"
  946|     18|      "adox %%rcx, %%rax\n\t"
  947|     18|      "adcx %%rax, %%r10\n\t"
  948|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  949|     18|      "adox %%r13, %%rax\n\t"
  950|     18|      "adcx %%rax, %%r11\n\t"
  951|     18|      "mulx 56(%[x]), %%rax, %%r13\n\t"
  952|     18|      "adox %%rcx, %%rax\n\t"
  953|     18|      "adcx %%rax, %%r12\n\t"
  954|     18|      "movl $0, %%eax\n\t"
  955|     18|      "adox %%rax, %%r13\n\t"
  956|     18|      "adcx %%rax, %%r13\n\t"
  957|       |
  958|     18|      "movq 48(%[y]), %%rdx\n\t"  // row 6: x * y[6]
  959|     18|      "xorl %%eax, %%eax\n\t"
  960|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  961|     18|      "adcx %%rax, %%r14\n\t"
  962|     18|      "movq %%r14, 48(%[z])\n\t"
  963|     18|      "mulx 8(%[x]), %%rax, %%r14\n\t"
  964|     18|      "adox %%rcx, %%rax\n\t"
  965|     18|      "adcx %%rax, %%r15\n\t"
  966|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  967|     18|      "adox %%r14, %%rax\n\t"
  968|     18|      "adcx %%rax, %%r8\n\t"
  969|     18|      "mulx 24(%[x]), %%rax, %%r14\n\t"
  970|     18|      "adox %%rcx, %%rax\n\t"
  971|     18|      "adcx %%rax, %%r9\n\t"
  972|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
  973|     18|      "adox %%r14, %%rax\n\t"
  974|     18|      "adcx %%rax, %%r10\n\t"
  975|     18|      "mulx 40(%[x]), %%rax, %%r14\n\t"
  976|     18|      "adox %%rcx, %%rax\n\t"
  977|     18|      "adcx %%rax, %%r11\n\t"
  978|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
  979|     18|      "adox %%r14, %%rax\n\t"
  980|     18|      "adcx %%rax, %%r12\n\t"
  981|     18|      "mulx 56(%[x]), %%rax, %%r14\n\t"
  982|     18|      "adox %%rcx, %%rax\n\t"
  983|     18|      "adcx %%rax, %%r13\n\t"
  984|     18|      "movl $0, %%eax\n\t"
  985|     18|      "adox %%rax, %%r14\n\t"
  986|     18|      "adcx %%rax, %%r14\n\t"
  987|       |
  988|     18|      "movq 56(%[y]), %%rdx\n\t"  // row 7: x * y[7]
  989|     18|      "xorl %%eax, %%eax\n\t"
  990|     18|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
  991|     18|      "adcx %%rax, %%r15\n\t"
  992|     18|      "movq %%r15, 56(%[z])\n\t"
  993|     18|      "mulx 8(%[x]), %%rax, %%r15\n\t"
  994|     18|      "adox %%rcx, %%rax\n\t"
  995|     18|      "adcx %%rax, %%r8\n\t"
  996|     18|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
  997|     18|      "adox %%r15, %%rax\n\t"
  998|     18|      "adcx %%rax, %%r9\n\t"
  999|     18|      "mulx 24(%[x]), %%rax, %%r15\n\t"
 1000|     18|      "adox %%rcx, %%rax\n\t"
 1001|     18|      "adcx %%rax, %%r10\n\t"
 1002|     18|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1003|     18|      "adox %%r15, %%rax\n\t"
 1004|     18|      "adcx %%rax, %%r11\n\t"
 1005|     18|      "mulx 40(%[x]), %%rax, %%r15\n\t"
 1006|     18|      "adox %%rcx, %%rax\n\t"
 1007|     18|      "adcx %%rax, %%r12\n\t"
 1008|     18|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1009|     18|      "adox %%r15, %%rax\n\t"
 1010|     18|      "adcx %%rax, %%r13\n\t"
 1011|     18|      "mulx 56(%[x]), %%rax, %%r15\n\t"
 1012|     18|      "adox %%rcx, %%rax\n\t"
 1013|     18|      "adcx %%rax, %%r14\n\t"
 1014|     18|      "movl $0, %%eax\n\t"
 1015|     18|      "adox %%rax, %%r15\n\t"
 1016|     18|      "adcx %%rax, %%r15\n\t"
 1017|       |
 1018|     18|      "movq %%r8, 64(%[z])\n\t"
 1019|     18|      "movq %%r9, 72(%[z])\n\t"
 1020|     18|      "movq %%r10, 80(%[z])\n\t"
 1021|     18|      "movq %%r11, 88(%[z])\n\t"
 1022|     18|      "movq %%r12, 96(%[z])\n\t"
 1023|     18|      "movq %%r13, 104(%[z])\n\t"
 1024|     18|      "movq %%r14, 112(%[z])\n\t"
 1025|     18|      "movq %%r15, 120(%[z])\n\t"
 1026|     18|      :
 1027|     18|      : [z] "r"(z), [x] "r"(x), [y] "r"(y)
 1028|     18|      : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "cc", "memory");
 1029|       |   // clang-format on
 1030|     18|}
_ZN5Botan16bigint_mulx_mul9EPmPKmS2_:
 1307|     10|void bigint_mulx_mul9(word z[18], const word x[9], const word y[9]) {
 1308|     10|   copy_mem(z + 9, y, 9);
 1309|       |   // clang-format off
 1310|     10|   asm(
 1311|     10|      "xorl %%r8d, %%r8d\n\t"
 1312|     10|      "xorl %%r9d, %%r9d\n\t"
 1313|     10|      "xorl %%r10d, %%r10d\n\t"
 1314|     10|      "xorl %%r11d, %%r11d\n\t"
 1315|     10|      "xorl %%r12d, %%r12d\n\t"
 1316|     10|      "xorl %%r13d, %%r13d\n\t"
 1317|     10|      "xorl %%r14d, %%r14d\n\t"
 1318|     10|      "xorl %%r15d, %%r15d\n\t"
 1319|     10|      "xorl %%ebx, %%ebx\n\t"
 1320|       |
 1321|     10|      "movq 72(%[z]), %%rdx\n\t"  // row 0: x * y[0]
 1322|     10|      "xorl %%eax, %%eax\n\t"
 1323|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1324|     10|      "adcx %%rax, %%r8\n\t"
 1325|     10|      "movq %%r8, 0(%[z])\n\t"
 1326|     10|      "mulx 8(%[x]), %%rax, %%r8\n\t"
 1327|     10|      "adox %%rcx, %%rax\n\t"
 1328|     10|      "adcx %%rax, %%r9\n\t"
 1329|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1330|     10|      "adox %%r8, %%rax\n\t"
 1331|     10|      "adcx %%rax, %%r10\n\t"
 1332|     10|      "mulx 24(%[x]), %%rax, %%r8\n\t"
 1333|     10|      "adox %%rcx, %%rax\n\t"
 1334|     10|      "adcx %%rax, %%r11\n\t"
 1335|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1336|     10|      "adox %%r8, %%rax\n\t"
 1337|     10|      "adcx %%rax, %%r12\n\t"
 1338|     10|      "mulx 40(%[x]), %%rax, %%r8\n\t"
 1339|     10|      "adox %%rcx, %%rax\n\t"
 1340|     10|      "adcx %%rax, %%r13\n\t"
 1341|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1342|     10|      "adox %%r8, %%rax\n\t"
 1343|     10|      "adcx %%rax, %%r14\n\t"
 1344|     10|      "mulx 56(%[x]), %%rax, %%r8\n\t"
 1345|     10|      "adox %%rcx, %%rax\n\t"
 1346|     10|      "adcx %%rax, %%r15\n\t"
 1347|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1348|     10|      "adox %%r8, %%rax\n\t"
 1349|     10|      "adcx %%rax, %%rbx\n\t"
 1350|     10|      "movl $0, %%eax\n\t"
 1351|     10|      "adox %%rax, %%rcx\n\t"
 1352|     10|      "adcx %%rax, %%rcx\n\t"
 1353|     10|      "movq %%rcx, %%r8\n\t"
 1354|       |
 1355|     10|      "movq 80(%[z]), %%rdx\n\t"  // row 1: x * y[1]
 1356|     10|      "xorl %%eax, %%eax\n\t"
 1357|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1358|     10|      "adcx %%rax, %%r9\n\t"
 1359|     10|      "movq %%r9, 8(%[z])\n\t"
 1360|     10|      "mulx 8(%[x]), %%rax, %%r9\n\t"
 1361|     10|      "adox %%rcx, %%rax\n\t"
 1362|     10|      "adcx %%rax, %%r10\n\t"
 1363|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1364|     10|      "adox %%r9, %%rax\n\t"
 1365|     10|      "adcx %%rax, %%r11\n\t"
 1366|     10|      "mulx 24(%[x]), %%rax, %%r9\n\t"
 1367|     10|      "adox %%rcx, %%rax\n\t"
 1368|     10|      "adcx %%rax, %%r12\n\t"
 1369|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1370|     10|      "adox %%r9, %%rax\n\t"
 1371|     10|      "adcx %%rax, %%r13\n\t"
 1372|     10|      "mulx 40(%[x]), %%rax, %%r9\n\t"
 1373|     10|      "adox %%rcx, %%rax\n\t"
 1374|     10|      "adcx %%rax, %%r14\n\t"
 1375|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1376|     10|      "adox %%r9, %%rax\n\t"
 1377|     10|      "adcx %%rax, %%r15\n\t"
 1378|     10|      "mulx 56(%[x]), %%rax, %%r9\n\t"
 1379|     10|      "adox %%rcx, %%rax\n\t"
 1380|     10|      "adcx %%rax, %%rbx\n\t"
 1381|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1382|     10|      "adox %%r9, %%rax\n\t"
 1383|     10|      "adcx %%rax, %%r8\n\t"
 1384|     10|      "movl $0, %%eax\n\t"
 1385|     10|      "adox %%rax, %%rcx\n\t"
 1386|     10|      "adcx %%rax, %%rcx\n\t"
 1387|     10|      "movq %%rcx, %%r9\n\t"
 1388|       |
 1389|     10|      "movq 88(%[z]), %%rdx\n\t"  // row 2: x * y[2]
 1390|     10|      "xorl %%eax, %%eax\n\t"
 1391|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1392|     10|      "adcx %%rax, %%r10\n\t"
 1393|     10|      "movq %%r10, 16(%[z])\n\t"
 1394|     10|      "mulx 8(%[x]), %%rax, %%r10\n\t"
 1395|     10|      "adox %%rcx, %%rax\n\t"
 1396|     10|      "adcx %%rax, %%r11\n\t"
 1397|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1398|     10|      "adox %%r10, %%rax\n\t"
 1399|     10|      "adcx %%rax, %%r12\n\t"
 1400|     10|      "mulx 24(%[x]), %%rax, %%r10\n\t"
 1401|     10|      "adox %%rcx, %%rax\n\t"
 1402|     10|      "adcx %%rax, %%r13\n\t"
 1403|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1404|     10|      "adox %%r10, %%rax\n\t"
 1405|     10|      "adcx %%rax, %%r14\n\t"
 1406|     10|      "mulx 40(%[x]), %%rax, %%r10\n\t"
 1407|     10|      "adox %%rcx, %%rax\n\t"
 1408|     10|      "adcx %%rax, %%r15\n\t"
 1409|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1410|     10|      "adox %%r10, %%rax\n\t"
 1411|     10|      "adcx %%rax, %%rbx\n\t"
 1412|     10|      "mulx 56(%[x]), %%rax, %%r10\n\t"
 1413|     10|      "adox %%rcx, %%rax\n\t"
 1414|     10|      "adcx %%rax, %%r8\n\t"
 1415|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1416|     10|      "adox %%r10, %%rax\n\t"
 1417|     10|      "adcx %%rax, %%r9\n\t"
 1418|     10|      "movl $0, %%eax\n\t"
 1419|     10|      "adox %%rax, %%rcx\n\t"
 1420|     10|      "adcx %%rax, %%rcx\n\t"
 1421|     10|      "movq %%rcx, %%r10\n\t"
 1422|       |
 1423|     10|      "movq 96(%[z]), %%rdx\n\t"  // row 3: x * y[3]
 1424|     10|      "xorl %%eax, %%eax\n\t"
 1425|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1426|     10|      "adcx %%rax, %%r11\n\t"
 1427|     10|      "movq %%r11, 24(%[z])\n\t"
 1428|     10|      "mulx 8(%[x]), %%rax, %%r11\n\t"
 1429|     10|      "adox %%rcx, %%rax\n\t"
 1430|     10|      "adcx %%rax, %%r12\n\t"
 1431|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1432|     10|      "adox %%r11, %%rax\n\t"
 1433|     10|      "adcx %%rax, %%r13\n\t"
 1434|     10|      "mulx 24(%[x]), %%rax, %%r11\n\t"
 1435|     10|      "adox %%rcx, %%rax\n\t"
 1436|     10|      "adcx %%rax, %%r14\n\t"
 1437|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1438|     10|      "adox %%r11, %%rax\n\t"
 1439|     10|      "adcx %%rax, %%r15\n\t"
 1440|     10|      "mulx 40(%[x]), %%rax, %%r11\n\t"
 1441|     10|      "adox %%rcx, %%rax\n\t"
 1442|     10|      "adcx %%rax, %%rbx\n\t"
 1443|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1444|     10|      "adox %%r11, %%rax\n\t"
 1445|     10|      "adcx %%rax, %%r8\n\t"
 1446|     10|      "mulx 56(%[x]), %%rax, %%r11\n\t"
 1447|     10|      "adox %%rcx, %%rax\n\t"
 1448|     10|      "adcx %%rax, %%r9\n\t"
 1449|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1450|     10|      "adox %%r11, %%rax\n\t"
 1451|     10|      "adcx %%rax, %%r10\n\t"
 1452|     10|      "movl $0, %%eax\n\t"
 1453|     10|      "adox %%rax, %%rcx\n\t"
 1454|     10|      "adcx %%rax, %%rcx\n\t"
 1455|     10|      "movq %%rcx, %%r11\n\t"
 1456|       |
 1457|     10|      "movq 104(%[z]), %%rdx\n\t"  // row 4: x * y[4]
 1458|     10|      "xorl %%eax, %%eax\n\t"
 1459|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1460|     10|      "adcx %%rax, %%r12\n\t"
 1461|     10|      "movq %%r12, 32(%[z])\n\t"
 1462|     10|      "mulx 8(%[x]), %%rax, %%r12\n\t"
 1463|     10|      "adox %%rcx, %%rax\n\t"
 1464|     10|      "adcx %%rax, %%r13\n\t"
 1465|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1466|     10|      "adox %%r12, %%rax\n\t"
 1467|     10|      "adcx %%rax, %%r14\n\t"
 1468|     10|      "mulx 24(%[x]), %%rax, %%r12\n\t"
 1469|     10|      "adox %%rcx, %%rax\n\t"
 1470|     10|      "adcx %%rax, %%r15\n\t"
 1471|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1472|     10|      "adox %%r12, %%rax\n\t"
 1473|     10|      "adcx %%rax, %%rbx\n\t"
 1474|     10|      "mulx 40(%[x]), %%rax, %%r12\n\t"
 1475|     10|      "adox %%rcx, %%rax\n\t"
 1476|     10|      "adcx %%rax, %%r8\n\t"
 1477|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1478|     10|      "adox %%r12, %%rax\n\t"
 1479|     10|      "adcx %%rax, %%r9\n\t"
 1480|     10|      "mulx 56(%[x]), %%rax, %%r12\n\t"
 1481|     10|      "adox %%rcx, %%rax\n\t"
 1482|     10|      "adcx %%rax, %%r10\n\t"
 1483|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1484|     10|      "adox %%r12, %%rax\n\t"
 1485|     10|      "adcx %%rax, %%r11\n\t"
 1486|     10|      "movl $0, %%eax\n\t"
 1487|     10|      "adox %%rax, %%rcx\n\t"
 1488|     10|      "adcx %%rax, %%rcx\n\t"
 1489|     10|      "movq %%rcx, %%r12\n\t"
 1490|       |
 1491|     10|      "movq 112(%[z]), %%rdx\n\t"  // row 5: x * y[5]
 1492|     10|      "xorl %%eax, %%eax\n\t"
 1493|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1494|     10|      "adcx %%rax, %%r13\n\t"
 1495|     10|      "movq %%r13, 40(%[z])\n\t"
 1496|     10|      "mulx 8(%[x]), %%rax, %%r13\n\t"
 1497|     10|      "adox %%rcx, %%rax\n\t"
 1498|     10|      "adcx %%rax, %%r14\n\t"
 1499|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1500|     10|      "adox %%r13, %%rax\n\t"
 1501|     10|      "adcx %%rax, %%r15\n\t"
 1502|     10|      "mulx 24(%[x]), %%rax, %%r13\n\t"
 1503|     10|      "adox %%rcx, %%rax\n\t"
 1504|     10|      "adcx %%rax, %%rbx\n\t"
 1505|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1506|     10|      "adox %%r13, %%rax\n\t"
 1507|     10|      "adcx %%rax, %%r8\n\t"
 1508|     10|      "mulx 40(%[x]), %%rax, %%r13\n\t"
 1509|     10|      "adox %%rcx, %%rax\n\t"
 1510|     10|      "adcx %%rax, %%r9\n\t"
 1511|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1512|     10|      "adox %%r13, %%rax\n\t"
 1513|     10|      "adcx %%rax, %%r10\n\t"
 1514|     10|      "mulx 56(%[x]), %%rax, %%r13\n\t"
 1515|     10|      "adox %%rcx, %%rax\n\t"
 1516|     10|      "adcx %%rax, %%r11\n\t"
 1517|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1518|     10|      "adox %%r13, %%rax\n\t"
 1519|     10|      "adcx %%rax, %%r12\n\t"
 1520|     10|      "movl $0, %%eax\n\t"
 1521|     10|      "adox %%rax, %%rcx\n\t"
 1522|     10|      "adcx %%rax, %%rcx\n\t"
 1523|     10|      "movq %%rcx, %%r13\n\t"
 1524|       |
 1525|     10|      "movq 120(%[z]), %%rdx\n\t"  // row 6: x * y[6]
 1526|     10|      "xorl %%eax, %%eax\n\t"
 1527|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1528|     10|      "adcx %%rax, %%r14\n\t"
 1529|     10|      "movq %%r14, 48(%[z])\n\t"
 1530|     10|      "mulx 8(%[x]), %%rax, %%r14\n\t"
 1531|     10|      "adox %%rcx, %%rax\n\t"
 1532|     10|      "adcx %%rax, %%r15\n\t"
 1533|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1534|     10|      "adox %%r14, %%rax\n\t"
 1535|     10|      "adcx %%rax, %%rbx\n\t"
 1536|     10|      "mulx 24(%[x]), %%rax, %%r14\n\t"
 1537|     10|      "adox %%rcx, %%rax\n\t"
 1538|     10|      "adcx %%rax, %%r8\n\t"
 1539|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1540|     10|      "adox %%r14, %%rax\n\t"
 1541|     10|      "adcx %%rax, %%r9\n\t"
 1542|     10|      "mulx 40(%[x]), %%rax, %%r14\n\t"
 1543|     10|      "adox %%rcx, %%rax\n\t"
 1544|     10|      "adcx %%rax, %%r10\n\t"
 1545|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1546|     10|      "adox %%r14, %%rax\n\t"
 1547|     10|      "adcx %%rax, %%r11\n\t"
 1548|     10|      "mulx 56(%[x]), %%rax, %%r14\n\t"
 1549|     10|      "adox %%rcx, %%rax\n\t"
 1550|     10|      "adcx %%rax, %%r12\n\t"
 1551|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1552|     10|      "adox %%r14, %%rax\n\t"
 1553|     10|      "adcx %%rax, %%r13\n\t"
 1554|     10|      "movl $0, %%eax\n\t"
 1555|     10|      "adox %%rax, %%rcx\n\t"
 1556|     10|      "adcx %%rax, %%rcx\n\t"
 1557|     10|      "movq %%rcx, %%r14\n\t"
 1558|       |
 1559|     10|      "movq 128(%[z]), %%rdx\n\t"  // row 7: x * y[7]
 1560|     10|      "xorl %%eax, %%eax\n\t"
 1561|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1562|     10|      "adcx %%rax, %%r15\n\t"
 1563|     10|      "movq %%r15, 56(%[z])\n\t"
 1564|     10|      "mulx 8(%[x]), %%rax, %%r15\n\t"
 1565|     10|      "adox %%rcx, %%rax\n\t"
 1566|     10|      "adcx %%rax, %%rbx\n\t"
 1567|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1568|     10|      "adox %%r15, %%rax\n\t"
 1569|     10|      "adcx %%rax, %%r8\n\t"
 1570|     10|      "mulx 24(%[x]), %%rax, %%r15\n\t"
 1571|     10|      "adox %%rcx, %%rax\n\t"
 1572|     10|      "adcx %%rax, %%r9\n\t"
 1573|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1574|     10|      "adox %%r15, %%rax\n\t"
 1575|     10|      "adcx %%rax, %%r10\n\t"
 1576|     10|      "mulx 40(%[x]), %%rax, %%r15\n\t"
 1577|     10|      "adox %%rcx, %%rax\n\t"
 1578|     10|      "adcx %%rax, %%r11\n\t"
 1579|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1580|     10|      "adox %%r15, %%rax\n\t"
 1581|     10|      "adcx %%rax, %%r12\n\t"
 1582|     10|      "mulx 56(%[x]), %%rax, %%r15\n\t"
 1583|     10|      "adox %%rcx, %%rax\n\t"
 1584|     10|      "adcx %%rax, %%r13\n\t"
 1585|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1586|     10|      "adox %%r15, %%rax\n\t"
 1587|     10|      "adcx %%rax, %%r14\n\t"
 1588|     10|      "movl $0, %%eax\n\t"
 1589|     10|      "adox %%rax, %%rcx\n\t"
 1590|     10|      "adcx %%rax, %%rcx\n\t"
 1591|     10|      "movq %%rcx, %%r15\n\t"
 1592|       |
 1593|     10|      "movq 136(%[z]), %%rdx\n\t"  // row 8: x * y[8]
 1594|     10|      "xorl %%eax, %%eax\n\t"
 1595|     10|      "mulx 0(%[x]), %%rax, %%rcx\n\t"
 1596|     10|      "adcx %%rax, %%rbx\n\t"
 1597|     10|      "movq %%rbx, 64(%[z])\n\t"
 1598|     10|      "mulx 8(%[x]), %%rax, %%rbx\n\t"
 1599|     10|      "adox %%rcx, %%rax\n\t"
 1600|     10|      "adcx %%rax, %%r8\n\t"
 1601|     10|      "mulx 16(%[x]), %%rax, %%rcx\n\t"
 1602|     10|      "adox %%rbx, %%rax\n\t"
 1603|     10|      "adcx %%rax, %%r9\n\t"
 1604|     10|      "mulx 24(%[x]), %%rax, %%rbx\n\t"
 1605|     10|      "adox %%rcx, %%rax\n\t"
 1606|     10|      "adcx %%rax, %%r10\n\t"
 1607|     10|      "mulx 32(%[x]), %%rax, %%rcx\n\t"
 1608|     10|      "adox %%rbx, %%rax\n\t"
 1609|     10|      "adcx %%rax, %%r11\n\t"
 1610|     10|      "mulx 40(%[x]), %%rax, %%rbx\n\t"
 1611|     10|      "adox %%rcx, %%rax\n\t"
 1612|     10|      "adcx %%rax, %%r12\n\t"
 1613|     10|      "mulx 48(%[x]), %%rax, %%rcx\n\t"
 1614|     10|      "adox %%rbx, %%rax\n\t"
 1615|     10|      "adcx %%rax, %%r13\n\t"
 1616|     10|      "mulx 56(%[x]), %%rax, %%rbx\n\t"
 1617|     10|      "adox %%rcx, %%rax\n\t"
 1618|     10|      "adcx %%rax, %%r14\n\t"
 1619|     10|      "mulx 64(%[x]), %%rax, %%rcx\n\t"
 1620|     10|      "adox %%rbx, %%rax\n\t"
 1621|     10|      "adcx %%rax, %%r15\n\t"
 1622|     10|      "movl $0, %%eax\n\t"
 1623|     10|      "adox %%rax, %%rcx\n\t"
 1624|     10|      "adcx %%rax, %%rcx\n\t"
 1625|     10|      "movq %%rcx, %%rbx\n\t"
 1626|       |
 1627|     10|      "movq %%r8, 72(%[z])\n\t"
 1628|     10|      "movq %%r9, 80(%[z])\n\t"
 1629|     10|      "movq %%r10, 88(%[z])\n\t"
 1630|     10|      "movq %%r11, 96(%[z])\n\t"
 1631|     10|      "movq %%r12, 104(%[z])\n\t"
 1632|     10|      "movq %%r13, 112(%[z])\n\t"
 1633|     10|      "movq %%r14, 120(%[z])\n\t"
 1634|     10|      "movq %%r15, 128(%[z])\n\t"
 1635|     10|      "movq %%rbx, 136(%[z])\n\t"
 1636|     10|      :
 1637|     10|      : [z] "r"(z), [x] "r"(x)
 1638|     10|      : "rax", "rcx", "rdx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rbx", "cc", "memory");
 1639|       |   // clang-format on
 1640|     10|}

_ZN5Botan17Barrett_ReductionC2ERKNS_6BigIntES1_m:
   17|    870|      m_modulus(m), m_mu(std::move(mu)), m_mod_words(mw), m_modulus_bits(m.bits()) {
   18|       |   // Give some extra space for Karatsuba
   19|    870|   m_modulus.grow_to(m_mod_words + 8);
   20|    870|   m_mu.grow_to(m_mod_words + 8);
   21|    870|}
_ZN5Botan17Barrett_Reduction18for_secret_modulusERKNS_6BigIntE:
   23|    870|Barrett_Reduction Barrett_Reduction::for_secret_modulus(const BigInt& mod) {
   24|    870|   BOTAN_ARG_CHECK(mod.signum() > 0, "Modulus must be positive");
  ------------------
  |  |   35|    870|   do {                                                          \
  |  |   36|    870|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|    870|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 870]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|    870|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 870]
  |  |  ------------------
  ------------------
   25|       |
   26|    870|   const size_t mod_words = mod.sig_words();
   27|       |
   28|       |   // Compute mu = floor(2^{2k} / m)
   29|    870|   const size_t mu_bits = 2 * WordInfo<word>::bits * mod_words;
   30|    870|   return Barrett_Reduction(mod, ct_divide_pow2k(mu_bits, mod), mod_words);
   31|    870|}
_ZN5Botan17Barrett_Reduction18for_public_modulusERKNS_6BigIntE:
   33|    870|Barrett_Reduction Barrett_Reduction::for_public_modulus(const BigInt& mod) {
   34|    870|   return Barrett_Reduction::for_secret_modulus(mod);
   35|    870|}
_ZNK5Botan17Barrett_Reduction6reduceERKNS_6BigIntE:
  185|    870|BigInt Barrett_Reduction::reduce(const BigInt& x) const {
  186|    870|   BOTAN_ARG_CHECK(x.signum() >= 0, "Argument must be non-negative");
  ------------------
  |  |   35|    870|   do {                                                          \
  |  |   36|    870|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|    870|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 870]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|    870|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 870]
  |  |  ------------------
  ------------------
  187|       |
  188|    870|   const size_t x_sw = x.sig_words();
  189|    870|   BOTAN_ARG_CHECK(x_sw <= 2 * m_mod_words, "Argument is too large for Barrett reduction");
  ------------------
  |  |   35|    870|   do {                                                          \
  |  |   36|    870|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|    870|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 16, False: 854]
  |  |  ------------------
  |  |   38|     16|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|     16|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|     16|      }                                                          \
  |  |   41|    870|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 870]
  |  |  ------------------
  ------------------
  190|       |
  191|    870|   x.grow_to(2 * m_mod_words);
  192|       |
  193|    870|   secure_vector<word> ws;
  194|    870|   return barrett_reduce(m_mod_words, m_modulus, m_mu, x._as_span(), ws);
  195|    870|}
barrett.cpp:_ZN5Botan12_GLOBAL__N_114barrett_reduceEmRKNS_6BigIntES3_NSt3__14spanIKmLm18446744073709551615EEERNS4_6vectorImNS_16secure_allocatorImEEEE:
   48|    854|   size_t mod_words, const BigInt& modulus, const BigInt& mu, std::span<const word> x_words, secure_vector<word>& ws) {
   49|    854|   BOTAN_ASSERT_NOMSG(modulus.sig_words() == mod_words);
  ------------------
  |  |   84|    854|   do {                                                                     \
  |  |   85|    854|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|    854|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 854]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|    854|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 854]
  |  |  ------------------
  ------------------
   50|       |
   51|       |   // Caller must expand input to be at least this size
   52|    854|   BOTAN_ASSERT_NOMSG(x_words.size() >= 2 * mod_words);
  ------------------
  |  |   84|    854|   do {                                                                     \
  |  |   85|    854|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|    854|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 854]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|    854|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 854]
  |  |  ------------------
  ------------------
   53|       |
   54|       |   // Normally mod_words + 1 but can be + 2 if the modulus is a power of 2
   55|    854|   const size_t mu_words = mu.sig_words();
   56|    854|   BOTAN_ASSERT_NOMSG(mu_words <= mod_words + 2);
  ------------------
  |  |   84|    854|   do {                                                                     \
  |  |   85|    854|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|    854|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 854]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|    854|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 854]
  |  |  ------------------
  ------------------
   57|       |
   58|    854|   if(ws.size() < 2 * (mod_words + 2)) {
  ------------------
  |  Branch (58:7): [True: 854, False: 0]
  ------------------
   59|    854|      ws.resize(2 * (mod_words + 2));
   60|    854|   }
   61|       |
   62|    854|   CT::poison(x_words);
   63|       |
   64|       |   /*
   65|       |   * Following the notation of Handbook of Applied Cryptography
   66|       |   * Algorithm 14.42 "Barrett modular reduction", page 604
   67|       |   * <https://cacr.uwaterloo.ca/hac/about/chap14.pdf>
   68|       |   *
   69|       |   * Using `mu` for µ in the code
   70|       |   */
   71|       |
   72|       |   // Compute q1 = floor(x / 2^(k - 1)) which is equivalent to ignoring the low (k-1) words
   73|       |
   74|       |   // 2 * mod_words + 1 is sufficient, extra is to enable Karatsuba
   75|    854|   secure_vector<word> r(2 * mu_words + 2);
   76|       |
   77|    854|   copy_mem(r.data(), x_words.data() + (mod_words - 1), mod_words + 1);
   78|       |
   79|       |   // Now compute q2 = q1 * µ
   80|       |
   81|       |   // We allocate more size than required since this allows Karatsuba more often;
   82|       |   // just `mu_words + (mod_words + 1)` is sufficient
   83|    854|   const size_t q2_size = 2 * mu_words + 2;
   84|       |
   85|    854|   secure_vector<word> q2(q2_size);
   86|       |
   87|    854|   bigint_mul(
   88|    854|      q2.data(), q2.size(), r.data(), r.size(), mod_words + 1, mu._data(), mu.size(), mu_words, ws.data(), ws.size());
   89|       |
   90|       |   // Compute r2 = (floor(q2 / b^(k+1)) * m) mod 2^(k+1)
   91|       |   // The division/floor is again effected by just ignoring the low k + 1 words
   92|    854|   bigint_mul(r.data(),
   93|    854|              r.size(),
   94|    854|              &q2[mod_words + 1],  // ignoring the low mod_words + 1 words of the first product
   95|    854|              q2.size() - (mod_words + 1),
   96|    854|              mod_words + 1,
   97|    854|              modulus._data(),
   98|    854|              modulus.size(),
   99|    854|              mod_words,
  100|    854|              ws.data(),
  101|    854|              ws.size());
  102|       |
  103|       |   // Clear the high words of the product, equivalent to computing mod 2^(k+1)
  104|       |   // TODO add masked mul to avoid computing high bits at all
  105|    854|   clear_mem(std::span{r}.subspan(mod_words + 1));
  106|       |
  107|       |   // Compute r = r1 - r2
  108|       |
  109|       |   // The return value of bigint_sub_abs isn't quite right for what we need here so first compare
  110|    854|   const int32_t relative_size = bigint_cmp(r.data(), mod_words + 1, x_words.data(), mod_words + 1);
  111|       |
  112|    854|   bigint_sub_abs(r.data(), r.data(), x_words.data(), mod_words + 1, ws.data());
  113|       |
  114|       |   /*
  115|       |   If r is negative then we have to set r to r + 2^(k+1)
  116|       |
  117|       |   However for r negative computing this sum is equivalent to computing 2^(k+1) - abs(r)
  118|       |   */
  119|    854|   clear_mem(ws.data(), mod_words + 2);
  120|    854|   ws[mod_words + 1] = 1;
  121|    854|   bigint_sub2(ws.data(), mod_words + 2, r.data(), mod_words + 2);
  122|       |
  123|       |   // If relative_size > 0 then assign r to 2^(k+1) - r
  124|    854|   CT::Mask<word>::is_equal(static_cast<word>(relative_size), 1).select_n(r.data(), ws.data(), r.data(), mod_words + 2);
  125|       |
  126|       |   /*
  127|       |   * Per HAC Note 14.44 (ii) "step 4 is repeated at most twice since 0 <= r < 3m"
  128|       |   */
  129|    854|   const size_t bound = 2;
  130|       |
  131|    854|   BOTAN_ASSERT_NOMSG(r.size() >= mod_words + 1);
  ------------------
  |  |   84|    854|   do {                                                                     \
  |  |   85|    854|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|    854|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 854]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|    854|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 854]
  |  |  ------------------
  ------------------
  132|  2.56k|   for(size_t i = 0; i != bound; ++i) {
  ------------------
  |  Branch (132:22): [True: 1.70k, False: 854]
  ------------------
  133|  1.70k|      const word borrow = bigint_sub3(ws.data(), r.data(), mod_words + 1, modulus._data(), mod_words);
  134|  1.70k|      CT::Mask<word>::is_zero(borrow).select_n(r.data(), ws.data(), r.data(), mod_words + 1);
  135|  1.70k|   }
  136|       |
  137|    854|   CT::unpoison(q2);
  138|    854|   CT::unpoison(r);
  139|    854|   CT::unpoison(ws);
  140|    854|   CT::unpoison(x_words);
  141|       |
  142|    854|   return BigInt::_from_words(r);
  143|    854|}

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

_ZN5Botan22throw_invalid_argumentEPKcS1_S1_:
   23|     16|void throw_invalid_argument(const char* message, const char* func, const char* file) {
   24|     16|   throw Invalid_Argument(fmt("{} in {}:{}", message, func, file));
   25|     16|}

_ZN5Botan5CPUID10CPUID_DataC2Ev:
   80|      1|CPUID::CPUID_Data::CPUID_Data() {
   81|       |   // NOLINTBEGIN(*-prefer-member-initializer)
   82|      1|#if defined(BOTAN_HAS_CPUID_DETECTION)
   83|      1|   m_processor_features = detect_cpu_features(~cleared_cpuid_bits());
   84|       |#else
   85|       |   m_processor_features = 0;
   86|       |#endif
   87|       |   // NOLINTEND(*-prefer-member-initializer)
   88|      1|}
cpuid.cpp:_ZN5Botan12_GLOBAL__N_118cleared_cpuid_bitsEv:
   59|      1|uint32_t cleared_cpuid_bits() {
   60|      1|   uint32_t cleared = 0;
   61|       |
   62|      1|   #if defined(BOTAN_HAS_OS_UTILS)
   63|      1|   std::string clear_cpuid_env;
   64|      1|   if(OS::read_env_variable(clear_cpuid_env, "BOTAN_CLEAR_CPUID")) {
  ------------------
  |  Branch (64:7): [True: 0, False: 1]
  ------------------
   65|      0|      for(const auto& cpuid : split_on(clear_cpuid_env, ',')) {
  ------------------
  |  Branch (65:29): [True: 0, False: 0]
  ------------------
   66|      0|         if(auto bit = CPUID::bit_from_string(cpuid)) {
  ------------------
  |  Branch (66:18): [True: 0, False: 0]
  ------------------
   67|      0|            cleared |= bit->as_u32();
   68|      0|         }
   69|      0|      }
   70|      0|   }
   71|      1|   #endif
   72|       |
   73|      1|   return cleared;
   74|      1|}

_ZN5Botan5CPUID10CPUID_Data19detect_cpu_featuresEj:
   62|      1|uint32_t CPUID::CPUID_Data::detect_cpu_features(uint32_t allowed) {
   63|      1|   enum class x86_CPUID_1_bits : uint64_t {
   64|      1|      RDTSC = (1ULL << 4),
   65|      1|      SSE2 = (1ULL << 26),
   66|      1|      CLMUL = (1ULL << 33),
   67|      1|      SSSE3 = (1ULL << 41),
   68|      1|      SSE41 = (1ULL << 51),
   69|      1|      POPCNT = (1ULL << 55),
   70|      1|      AESNI = (1ULL << 57),
   71|       |      // AVX + OSXSAVE
   72|      1|      OSXSAVE = (1ULL << 59) | (1ULL << 60),
   73|      1|      RDRAND = (1ULL << 62)
   74|      1|   };
   75|       |
   76|      1|   enum class x86_CPUID_7_bits : uint64_t {
   77|      1|      BMI1 = (1ULL << 3),
   78|      1|      AVX2 = (1ULL << 5),
   79|      1|      BMI2 = (1ULL << 8),
   80|      1|      BMI_1_AND_2 = BMI1 | BMI2,
   81|      1|      AVX512_F = (1ULL << 16),
   82|      1|      AVX512_DQ = (1ULL << 17),
   83|      1|      RDSEED = (1ULL << 18),
   84|      1|      ADX = (1ULL << 19),
   85|      1|      AVX512_IFMA = (1ULL << 21),
   86|      1|      SHA = (1ULL << 29),
   87|      1|      AVX512_BW = (1ULL << 30),
   88|      1|      AVX512_VL = (1ULL << 31),
   89|      1|      AVX512_VBMI = (1ULL << 33),
   90|      1|      AVX512_VBMI2 = (1ULL << 38),
   91|      1|      GFNI = (1ULL << 40),
   92|      1|      AVX512_VAES = (1ULL << 41),
   93|      1|      AVX512_VCLMUL = (1ULL << 42),
   94|      1|      AVX512_VBITALG = (1ULL << 44),
   95|       |
   96|       |      /*
   97|       |      We only enable AVX512 support if all of the below flags are available
   98|       |
   99|       |      This is more than we strictly need for most uses, however it also has
  100|       |      the effect of preventing execution of AVX512 codepaths on cores that
  101|       |      have serious downclocking problems when AVX512 code executes,
  102|       |      especially Intel Skylake.
  103|       |
  104|       |      VBMI2/VBITALG are the key flags here as they restrict us to Intel Ice
  105|       |      Lake/Rocket Lake, or AMD Zen4, all of which do not have penalties for
  106|       |      executing AVX512.
  107|       |
  108|       |      There is nothing stopping some future processor from supporting the
  109|       |      above flags and having AVX512 penalties, but maybe you should not have
  110|       |      bought such a processor.
  111|       |      */
  112|      1|      AVX512_PROFILE =
  113|      1|         AVX512_F | AVX512_DQ | AVX512_IFMA | AVX512_BW | AVX512_VL | AVX512_VBMI | AVX512_VBMI2 | AVX512_VBITALG,
  114|      1|   };
  115|       |
  116|       |   // NOLINTNEXTLINE(performance-enum-size)
  117|      1|   enum class x86_CPUID_7_1_bits : uint64_t {
  118|      1|      SHA512 = (1 << 0),
  119|      1|      SM3 = (1 << 1),
  120|      1|      SM4 = (1 << 2),
  121|      1|   };
  122|       |
  123|      1|   uint32_t feat = 0;
  124|      1|   uint32_t cpuid[4] = {0};
  125|      1|   bool has_sse41 = false;
  126|      1|   bool has_os_ymm_support = false;
  127|      1|   bool has_os_zmm_support = false;
  128|       |
  129|       |   // CPUID 0: vendor identification, max sublevel
  130|      1|   invoke_cpuid(0, cpuid);
  131|       |
  132|      1|   const uint32_t max_supported_sublevel = cpuid[0];
  133|       |
  134|      1|   if(max_supported_sublevel >= 1) {
  ------------------
  |  Branch (134:7): [True: 1, False: 0]
  ------------------
  135|       |      // CPUID 1: feature bits
  136|      1|      invoke_cpuid(1, cpuid);
  137|      1|      const uint64_t flags0 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[3];
  138|       |
  139|      1|      feat |= if_set(flags0, x86_CPUID_1_bits::RDTSC, CPUFeature::Bit::RDTSC, allowed);
  140|       |
  141|      1|      feat |= if_set(flags0, x86_CPUID_1_bits::RDRAND, CPUFeature::Bit::RDRAND, allowed);
  142|       |
  143|      1|      feat |= if_set(flags0, x86_CPUID_1_bits::POPCNT, CPUFeature::Bit::POPCNT, allowed);
  144|       |
  145|      1|      feat |= if_set(flags0, x86_CPUID_1_bits::SSE2, CPUFeature::Bit::SSE2, allowed);
  146|       |
  147|      1|      if(is_set(feat, CPUFeature::Bit::SSE2)) {
  ------------------
  |  Branch (147:10): [True: 1, False: 0]
  ------------------
  148|      1|         feat |= if_set(flags0, x86_CPUID_1_bits::SSSE3, CPUFeature::Bit::SSSE3, allowed);
  149|       |
  150|      1|         if(is_set(feat, CPUFeature::Bit::SSSE3)) {
  ------------------
  |  Branch (150:13): [True: 1, False: 0]
  ------------------
  151|      1|            feat |= if_set(flags0, x86_CPUID_1_bits::CLMUL, CPUFeature::Bit::CLMUL, allowed);
  152|      1|            feat |= if_set(flags0, x86_CPUID_1_bits::AESNI, CPUFeature::Bit::AESNI, allowed);
  153|       |
  154|       |            // SSE4.1 is not tracked as a feature, but is required by the SHA-NI code
  155|      1|            const uint64_t sse41 = static_cast<uint64_t>(x86_CPUID_1_bits::SSE41);
  156|      1|            has_sse41 = (flags0 & sse41) == sse41;
  157|      1|         }
  158|       |
  159|      1|         const uint64_t osxsave64 = static_cast<uint64_t>(x86_CPUID_1_bits::OSXSAVE);
  160|      1|         if((flags0 & osxsave64) == osxsave64) {
  ------------------
  |  Branch (160:13): [True: 1, False: 0]
  ------------------
  161|      1|            const uint64_t xcr_flags = xgetbv();
  162|      1|            if((xcr_flags & 0x6) == 0x6) {
  ------------------
  |  Branch (162:16): [True: 1, False: 0]
  ------------------
  163|      1|               has_os_ymm_support = true;
  164|      1|               has_os_zmm_support = (xcr_flags & 0xE0) == 0xE0;
  165|      1|            }
  166|      1|         }
  167|      1|      }
  168|      1|   }
  169|       |
  170|      1|   if(max_supported_sublevel >= 7) {
  ------------------
  |  Branch (170:7): [True: 1, False: 0]
  ------------------
  171|      1|      clear_mem(cpuid, 4);
  172|      1|      invoke_cpuid_sublevel(7, 0, cpuid);
  173|       |
  174|      1|      const uint64_t flags7 = (static_cast<uint64_t>(cpuid[2]) << 32) | cpuid[1];
  175|       |
  176|      1|      clear_mem(cpuid, 4);
  177|      1|      invoke_cpuid_sublevel(7, 1, cpuid);
  178|      1|      const uint32_t flags7_1 = cpuid[0];
  179|       |
  180|      1|      feat |= if_set(flags7, x86_CPUID_7_bits::RDSEED, CPUFeature::Bit::RDSEED, allowed);
  181|      1|      feat |= if_set(flags7, x86_CPUID_7_bits::ADX, CPUFeature::Bit::ADX, allowed);
  182|       |
  183|       |      /*
  184|       |      We only set the BMI bit if both BMI1 and BMI2 are supported, since
  185|       |      typically we want to use both extensions in the same code.
  186|       |      */
  187|      1|      feat |= if_set(flags7, x86_CPUID_7_bits::BMI_1_AND_2, CPUFeature::Bit::BMI, allowed);
  188|       |
  189|      1|      if(is_set(feat, CPUFeature::Bit::SSSE3)) {
  ------------------
  |  Branch (189:10): [True: 1, False: 0]
  ------------------
  190|       |         // The SHA-NI code uses SSE4.1 instructions in addition to SSSE3
  191|      1|         if(has_sse41) {
  ------------------
  |  Branch (191:13): [True: 1, False: 0]
  ------------------
  192|      1|            feat |= if_set(flags7, x86_CPUID_7_bits::SHA, CPUFeature::Bit::SHA, allowed);
  193|      1|         }
  194|       |
  195|       |         // We only consider AVX2 if SSSE3 is supported
  196|      1|         if(has_os_ymm_support) {
  ------------------
  |  Branch (196:13): [True: 1, False: 0]
  ------------------
  197|      1|            feat |= if_set(flags7, x86_CPUID_7_bits::AVX2, CPUFeature::Bit::AVX2, allowed);
  198|       |
  199|      1|            if(is_set(feat, CPUFeature::Bit::AVX2)) {
  ------------------
  |  Branch (199:16): [True: 1, False: 0]
  ------------------
  200|      1|               feat |= if_set(flags7, x86_CPUID_7_bits::GFNI, CPUFeature::Bit::GFNI, allowed);
  201|      1|               feat |= if_set(flags7, x86_CPUID_7_bits::AVX512_VAES, CPUFeature::Bit::AVX2_AES, allowed);
  202|      1|               feat |= if_set(flags7_1, x86_CPUID_7_1_bits::SHA512, CPUFeature::Bit::SHA512, allowed);
  203|       |               // The SM3/SM4 instructions are VEX encoded and the code using them also uses AVX2
  204|      1|               feat |= if_set(flags7_1, x86_CPUID_7_1_bits::SM3, CPUFeature::Bit::SM3, allowed);
  205|      1|               feat |= if_set(flags7_1, x86_CPUID_7_1_bits::SM4, CPUFeature::Bit::SM4, allowed);
  206|       |
  207|       |               // The VPCLMULQDQ code also uses the legacy 128-bit PCLMULQDQ instruction
  208|      1|               if(is_set(feat, CPUFeature::Bit::CLMUL)) {
  ------------------
  |  Branch (208:19): [True: 1, False: 0]
  ------------------
  209|      1|                  feat |= if_set(flags7, x86_CPUID_7_bits::AVX512_VCLMUL, CPUFeature::Bit::AVX2_CLMUL, allowed);
  210|      1|               }
  211|       |
  212|       |               // Likewise we only consider AVX-512 if AVX2 is supported
  213|      1|               if(has_os_zmm_support) {
  ------------------
  |  Branch (213:19): [True: 0, False: 1]
  ------------------
  214|      0|                  feat |= if_set(flags7, x86_CPUID_7_bits::AVX512_PROFILE, CPUFeature::Bit::AVX512, allowed);
  215|       |
  216|      0|                  if(is_set(feat, CPUFeature::Bit::AVX512)) {
  ------------------
  |  Branch (216:22): [True: 0, False: 0]
  ------------------
  217|      0|                     feat |= if_set(flags7, x86_CPUID_7_bits::AVX512_VAES, CPUFeature::Bit::AVX512_AES, allowed);
  218|      0|                     if(is_set(feat, CPUFeature::Bit::CLMUL)) {
  ------------------
  |  Branch (218:25): [True: 0, False: 0]
  ------------------
  219|      0|                        feat |= if_set(flags7, x86_CPUID_7_bits::AVX512_VCLMUL, CPUFeature::Bit::AVX512_CLMUL, allowed);
  220|      0|                     }
  221|      0|                  }
  222|      0|               }
  223|      1|            }
  224|      1|         }
  225|      1|      }
  226|      1|   }
  227|       |
  228|       |/*
  229|       |   * If we don't have access to CPUID, we can still safely assume that
  230|       |   * any x86-64 processor has SSE2 and RDTSC
  231|       |   */
  232|      1|#if defined(BOTAN_TARGET_ARCH_IS_X86_64)
  233|      1|   if(feat == 0) {
  ------------------
  |  Branch (233:7): [True: 0, False: 1]
  ------------------
  234|      0|      feat |= CPUFeature::Bit::SSE2 & allowed;
  235|      0|      feat |= CPUFeature::Bit::RDTSC & allowed;
  236|      0|   }
  237|      1|#endif
  238|       |
  239|      1|   return feat;
  240|      1|}
cpuid_x86.cpp:_ZN5Botan12_GLOBAL__N_112invoke_cpuidEjPj:
   24|      2|void invoke_cpuid(uint32_t type, uint32_t out[4]) {
   25|      2|   clear_mem(out, 4);
   26|       |
   27|      2|#if defined(BOTAN_USE_GCC_INLINE_ASM)
   28|       |   // NOLINTNEXTLINE(*-no-assembler)
   29|      2|   asm volatile("cpuid\n\t" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "0"(type));
   30|       |
   31|       |#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
   32|       |   __cpuid((int*)out, type);
   33|       |
   34|       |#else
   35|       |   BOTAN_UNUSED(type);
   36|       |   #warning "No way of calling x86 cpuid instruction for this compiler"
   37|       |#endif
   38|      2|}
cpuid_x86.cpp:_ZN5Botan12_GLOBAL__N_16xgetbvEv:
   56|      1|BOTAN_FUNC_ISA("xsave") uint64_t xgetbv() {
   57|       |   return _xgetbv(0);
   58|      1|}
cpuid_x86.cpp:_ZN5Botan12_GLOBAL__N_121invoke_cpuid_sublevelEjjPj:
   40|      2|void invoke_cpuid_sublevel(uint32_t type, uint32_t level, uint32_t out[4]) {
   41|      2|   clear_mem(out, 4);
   42|       |
   43|      2|#if defined(BOTAN_USE_GCC_INLINE_ASM)
   44|       |   // NOLINTNEXTLINE(*-no-assembler)
   45|      2|   asm volatile("cpuid\n\t" : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3]) : "0"(type), "2"(level));
   46|       |
   47|       |#elif defined(BOTAN_BUILD_COMPILER_IS_MSVC)
   48|       |   __cpuidex((int*)out, type, level);
   49|       |
   50|       |#else
   51|       |   BOTAN_UNUSED(type, level);
   52|       |   #warning "No way of calling x86 cpuid instruction for this compiler"
   53|       |#endif
   54|      2|}

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

_ZN5Botan19secure_scrub_memoryEPvm:
   24|  14.3k|void secure_scrub_memory(void* ptr, size_t n) {
   25|  14.3k|   return secure_zeroize_buffer(ptr, n);
   26|  14.3k|}
_ZN5Botan21secure_zeroize_bufferEPvm:
   28|  14.3k|void secure_zeroize_buffer(void* ptr, size_t n) {
   29|  14.3k|   if(n == 0) {
  ------------------
  |  Branch (29:7): [True: 0, False: 14.3k]
  ------------------
   30|      0|      return;
   31|      0|   }
   32|       |
   33|       |#if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY)
   34|       |   ::RtlSecureZeroMemory(ptr, n);
   35|       |
   36|       |#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO)
   37|  14.3k|   ::explicit_bzero(ptr, n);
   38|       |
   39|       |#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_MEMSET)
   40|       |   (void)::explicit_memset(ptr, 0, n);
   41|       |
   42|       |#else
   43|       |   /*
   44|       |   * Call memset through a static volatile pointer, which the compiler should
   45|       |   * not elide. This construct should be safe in conforming compilers, but who
   46|       |   * knows. This has been checked to generate the expected code, which saves the
   47|       |   * memset address in the data segment and unconditionally loads and jumps to
   48|       |   * that address, with the following targets:
   49|       |   *
   50|       |   * x86-64: Clang 19, GCC 6, 11, 13, 14
   51|       |   * riscv64: GCC 14
   52|       |   * aarch64: GCC 14
   53|       |   * armv7: GCC 14
   54|       |   *
   55|       |   * Actually all of them generated the expected jump even without marking the
   56|       |   * function pointer as volatile. However this seems worth including as an
   57|       |   * additional precaution.
   58|       |   */
   59|       |   static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset;
   60|       |   (memset_ptr)(ptr, 0, n);
   61|       |#endif
   62|  14.3k|}

_ZN5Botan2OS17read_env_variableERNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS1_17basic_string_viewIcS4_EE:
  471|      1|bool OS::read_env_variable(std::string& value_out, std::string_view name_view) {
  472|      1|   value_out = "";
  473|       |
  474|      1|   if(running_in_privileged_state()) {
  ------------------
  |  Branch (474:7): [True: 0, False: 1]
  ------------------
  475|      0|      return false;
  476|      0|   }
  477|       |
  478|       |#if defined(BOTAN_TARGET_OS_HAS_WIN32) && \
  479|       |   (defined(BOTAN_BUILD_COMPILER_IS_MSVC) || defined(BOTAN_BUILD_COMPILER_IS_CLANGCL))
  480|       |   const std::string name(name_view);
  481|       |
  482|       |   // First query the required buffer size; req_size is 0 if the variable is not set
  483|       |   size_t req_size = 0;
  484|       |   if(getenv_s(&req_size, nullptr, 0, name.c_str()) != 0 || req_size == 0) {
  485|       |      return false;
  486|       |   }
  487|       |
  488|       |   // The reported size includes the terminating \0
  489|       |   std::string val(req_size, '\0');
  490|       |   if(getenv_s(&req_size, val.data(), val.size(), name.c_str()) != 0) {
  491|       |      return false;
  492|       |   }
  493|       |
  494|       |   value_out = std::string(val.c_str());
  495|       |   return true;
  496|       |#else
  497|      1|   const std::string name(name_view);
  498|      1|   if(const char* val = std::getenv(name.c_str())) {
  ------------------
  |  Branch (498:19): [True: 0, False: 1]
  ------------------
  499|      0|      value_out = val;
  500|      0|      return true;
  501|      0|   }
  502|      1|#endif
  503|       |
  504|      1|   return false;
  505|      1|}
os_utils.cpp:_ZN5Botan12_GLOBAL__N_110get_auxvalENSt3__18optionalImEE:
  120|      1|std::optional<unsigned long> get_auxval(std::optional<unsigned long> id) {
  121|      1|   if(id) {
  ------------------
  |  Branch (121:7): [True: 1, False: 0]
  ------------------
  122|      1|#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL)
  123|      1|      return ::getauxval(*id);
  124|       |#elif defined(BOTAN_TARGET_OS_HAS_ELF_AUX_INFO)
  125|       |      unsigned long auxinfo = 0;
  126|       |      if(::elf_aux_info(static_cast<int>(*id), &auxinfo, sizeof(auxinfo)) == 0) {
  127|       |         return auxinfo;
  128|       |      }
  129|       |#endif
  130|      1|   }
  131|       |
  132|      0|   return {};
  133|      1|}
os_utils.cpp:_ZN5Botan12_GLOBAL__N_127running_in_privileged_stateEv:
  154|      1|bool running_in_privileged_state() {
  155|      1|#if defined(AT_SECURE)
  156|      1|   if(const auto at_secure = get_auxval(AT_SECURE)) {
  ------------------
  |  Branch (156:18): [True: 1, False: 0]
  ------------------
  157|      1|      return at_secure != 0;
  158|      1|   }
  159|      0|#endif
  160|       |
  161|      0|#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
  162|      0|   return (::getuid() != ::geteuid()) || (::getgid() != ::getegid());
  ------------------
  |  Branch (162:11): [True: 0, False: 0]
  |  Branch (162:42): [True: 0, False: 0]
  ------------------
  163|       |#else
  164|       |   return false;
  165|       |#endif
  166|      1|}

