_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEmEET_S2_:
   28|  5.46M|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|  5.46M|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|  5.46M|   return static_cast<T>(0) - top;
   31|  5.46M|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEmEET_S2_S2_S2_:
  216|  25.7M|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  217|       |   //return (mask & a) | (~mask & b);
  218|  25.7M|   return (b ^ (mask & (a ^ b)));
  219|  25.7M|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEmEET_S2_:
   37|  3.78M|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|  3.78M|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|  3.78M|}
_ZN5Botan8high_bitITkNSt3__117unsigned_integralEmEEmT_:
   73|  6.70k|BOTAN_FORCE_INLINE constexpr size_t high_bit(T n) {
   74|  6.70k|   size_t hb = 0;
   75|       |
   76|  46.9k|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (76:38): [True: 40.2k, False: 6.70k]
  ------------------
   77|       |      // Equivalent to: ((n >> s) == 0) ? 0 : s;
   78|  40.2k|      const size_t z = s - ct_if_is_zero_ret<T>(n >> s, s);
   79|  40.2k|      hb += z;
   80|  40.2k|      n >>= z;
   81|  40.2k|   }
   82|       |
   83|  6.70k|   hb += n;
   84|       |
   85|  6.70k|   return hb;
   86|  6.70k|}
_ZN5Botan17ct_if_is_zero_retITkNSt3__117unsigned_integralEmEEmT_m:
   45|  40.2k|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|  40.2k|   const T a = ~x & (x - 1);
   51|  40.2k|   const size_t a_top = static_cast<size_t>(CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1)));
   52|  40.2k|   const size_t mask = static_cast<size_t>(0) - a_top;
   53|  40.2k|   return mask & s;
   54|  40.2k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEhEET_S2_:
   37|  8.49k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|  8.49k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|  8.49k|}
_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEhEET_S2_:
   28|  8.49k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|  8.49k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|  8.49k|   return static_cast<T>(0) - top;
   31|  8.49k|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEhEET_S2_S2_S2_:
  216|  8.49k|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  217|       |   //return (mask & a) | (~mask & b);
  218|  8.49k|   return (b ^ (mask & (a ^ b)));
  219|  8.49k|}

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

_ZN5Botan2CT4MaskImE8is_equalEmm:
  442|   334k|      static constexpr Mask<T> is_equal(T x, T y) {
  443|   334k|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|   334k|         return Mask<T>::is_zero(diff);
  445|   334k|      }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  450|  1.00M|      static constexpr Mask<T> is_lt(T x, T y) {
  451|  1.00M|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|  1.00M|         return Mask<T>::expand_top_bit(u);
  453|  1.00M|      }
_ZN5Botan2CT4MaskImE14expand_top_bitEm:
  415|  1.67M|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskImEC2Em:
  637|  6.21M|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskImE6selectEmm:
  548|  25.7M|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZNK5Botan2CT4MaskImE5valueEv:
  630|  43.6M|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZN5Botan2CT4MaskImE7is_zeroEm:
  437|  1.75M|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT8unpoisonITkNSt3__18integralEmEEvRKT_:
  112|   777k|constexpr void unpoison(const T& p) {
  113|   777k|   unpoison(&p, 1);
  114|   777k|}
_ZN5Botan2CT8unpoisonImEEvPKT_m:
   67|   825k|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|   825k|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  144|   825k|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|   825k|}
_ZN5Botan2CT4MaskImE6expandEm:
  392|  1.41M|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZNK5Botan2CT4MaskImEcoEv:
  533|  2.08M|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskImE13if_set_returnEm:
  538|  13.6M|      constexpr T if_set_return(T x) const { return value() & x; }
_ZNK5Botan2CT4MaskImE7as_boolEv:
  614|   680k|      constexpr bool as_bool() const { return unpoisoned_value() != 0; }
_ZNK5Botan2CT4MaskImE16unpoisoned_valueEv:
  598|   680k|      constexpr T unpoisoned_value() const {
  599|   680k|         T r = value();
  600|   680k|         CT::unpoison(r);
  601|   680k|         return r;
  602|   680k|      }
_ZNK5Botan2CT4MaskImE11select_maskES2_S2_:
  559|  34.7k|      Mask<T> select_mask(Mask<T> x, Mask<T> y) const { return Mask<T>(select(x.value(), y.value())); }
_ZN5Botan2CT4MaskImEoRES2_:
  510|    108|      Mask<T>& operator|=(Mask<T> o) {
  511|    108|         m_mask |= o.value();
  512|    108|         return (*this);
  513|    108|      }
_ZN5Botan2CT4MaskImEaNES2_:
  494|    481|      Mask<T>& operator&=(Mask<T> o) {
  495|    481|         m_mask &= o.value();
  496|    481|         return (*this);
  497|    481|      }
_ZNK5Botan2CT4MaskImE8select_nEPmPKmS5_m:
  565|     10|      constexpr void select_n(T output[], const T x[], const T y[], size_t len) const {
  566|     10|         const T mask = value();
  567|    182|         for(size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (567:28): [True: 172, False: 10]
  ------------------
  568|    172|            output[i] = choose(mask, x[i], y[i]);
  569|    172|         }
  570|     10|      }
_ZN5Botan2CT4MaskIhE11expand_boolEb:
  397|  8.49k|      static constexpr Mask<T> expand_bool(bool v) { return Mask<T>::expand(static_cast<T>(v)); }
_ZN5Botan2CT4MaskIhE6expandEh:
  392|  8.49k|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  437|  8.49k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT4MaskIhEC2Eh:
  637|  16.9k|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhEcoEv:
  533|  8.49k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskIhE5valueEv:
  630|  16.9k|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskIhE6selectEhh:
  548|  8.49k|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT4MaskImE6is_gteEmm:
  468|   668k|      static constexpr Mask<T> is_gte(T x, T y) { return ~Mask<T>::is_lt(x, y); }
_ZN5Botan2CTorENS0_4MaskImEES2_:
  528|   668k|      friend Mask<T> operator|(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() | y.value()); }
_ZN5Botan2CT20conditional_copy_memImEENS0_4MaskIT_EES3_PS3_PKS3_S7_m:
  738|     10|constexpr inline Mask<T> conditional_copy_mem(T cnd, T* dest, const T* if_set, const T* if_unset, size_t elems) {
  739|     10|   const auto mask = CT::Mask<T>::expand(cnd);
  740|     10|   return CT::conditional_copy_mem(mask, dest, if_set, if_unset, elems);
  741|     10|}
_ZN5Botan2CT20conditional_copy_memImEENS0_4MaskIT_EES4_PS3_PKS3_S7_m:
  732|     10|constexpr inline Mask<T> conditional_copy_mem(Mask<T> mask, T* dest, const T* if_set, const T* if_unset, size_t elems) {
  733|     10|   mask.select_n(dest, if_set, if_unset, elems);
  734|     10|   return mask;
  735|     10|}
_ZN5Botan2CTeoENS0_4MaskImEES2_:
  523|      5|      friend Mask<T> operator^(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() ^ y.value()); }

_ZN5Botan11checked_mulITkNSt3__117unsigned_integralEmEENS1_8optionalIT_EES3_S3_:
   46|  51.2k|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|  51.2k|   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|  51.2k|   if(a != 0 && r / a != b) {
  ------------------
  |  Branch (53:7): [True: 51.2k, False: 0]
  |  Branch (53:17): [True: 0, False: 51.2k]
  ------------------
   54|      0|      return {};
   55|      0|   }
   56|  51.2k|   return r;
   57|  51.2k|}

_ZN5Botan7load_beImJNSt3__14spanIKhLm8EEEEEEDaDpOT0_:
  504|  21.8k|inline constexpr auto load_be(ParamTs&&... params) {
  505|  21.8k|   return detail::load_any<std::endian::big, OutT>(std::forward<ParamTs>(params)...);
  506|  21.8k|}
_ZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEENS2_4spanIKhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_:
  278|  21.8k|inline constexpr WrappedOutT load_any(InR&& in_range) {
  279|  21.8k|   using OutT = detail::wrapped_type<WrappedOutT>;
  280|  21.8k|   ranges::assert_exact_byte_length<sizeof(OutT)>(in_range);
  281|       |
  282|  21.8k|   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|  21.8k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  287|  21.8k|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  21.8k|      } else {
  289|  21.8k|         const std::span in{in_range};
  290|  21.8k|         if constexpr(sizeof(OutT) == 1) {
  291|  21.8k|            return static_cast<OutT>(in[0]);
  292|  21.8k|         } else if constexpr(endianness == std::endian::native) {
  293|  21.8k|            return typecast_copy<OutT>(in);
  294|  21.8k|         } else {
  295|  21.8k|            static_assert(opposite(endianness) == std::endian::native);
  296|  21.8k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  21.8k|         }
  298|  21.8k|      }
  299|  21.8k|   }());
  300|  21.8k|}
_ZN5Botan6detail24wrap_strong_type_or_enumITkNS0_20unsigned_integralishEmTkNSt3__117unsigned_integralEmEEDaT0_:
  200|  24.6k|constexpr auto wrap_strong_type_or_enum(T t) {
  201|       |   if constexpr(std::is_enum_v<OutT>) {
  202|       |      return static_cast<OutT>(t);
  203|  24.6k|   } else {
  204|  24.6k|      return Botan::wrap_strong_type<OutT>(t);
  205|  24.6k|   }
  206|  24.6k|}
_ZZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEENS2_4spanIKhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_ENKUlvE_clEv:
  282|  21.8k|   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|  21.8k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (286:10): [Folded, False: 21.8k]
  ------------------
  287|      0|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  21.8k|      } else {
  289|  21.8k|         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|  21.8k|         } else {
  295|  21.8k|            static_assert(opposite(endianness) == std::endian::native);
  296|  21.8k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  21.8k|         }
  298|  21.8k|      }
  299|  21.8k|   }());
_ZN5Botan7load_beImJRNSt3__15arrayIhLm8EEEEEEDaDpOT0_:
  504|  2.76k|inline constexpr auto load_be(ParamTs&&... params) {
  505|  2.76k|   return detail::load_any<std::endian::big, OutT>(std::forward<ParamTs>(params)...);
  506|  2.76k|}
_ZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEERNS2_5arrayIhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_:
  278|  2.76k|inline constexpr WrappedOutT load_any(InR&& in_range) {
  279|  2.76k|   using OutT = detail::wrapped_type<WrappedOutT>;
  280|  2.76k|   ranges::assert_exact_byte_length<sizeof(OutT)>(in_range);
  281|       |
  282|  2.76k|   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|  2.76k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  287|  2.76k|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  2.76k|      } else {
  289|  2.76k|         const std::span in{in_range};
  290|  2.76k|         if constexpr(sizeof(OutT) == 1) {
  291|  2.76k|            return static_cast<OutT>(in[0]);
  292|  2.76k|         } else if constexpr(endianness == std::endian::native) {
  293|  2.76k|            return typecast_copy<OutT>(in);
  294|  2.76k|         } else {
  295|  2.76k|            static_assert(opposite(endianness) == std::endian::native);
  296|  2.76k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  2.76k|         }
  298|  2.76k|      }
  299|  2.76k|   }());
  300|  2.76k|}
_ZZN5Botan6detail8load_anyILNSt3__16endianE64206ETkNS0_20unsigned_integralishEmTkNS_6ranges16contiguous_rangeIhEERNS2_5arrayIhLm8EEEQnt15custom_loadableINS0_19wrapped_type_helperIu14__remove_cvrefIT0_EE4typeEEEESA_OT1_ENKUlvE_clEv:
  282|  2.76k|   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|  2.76k|      if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (286:10): [Folded, False: 2.76k]
  ------------------
  287|      0|         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  288|  2.76k|      } else {
  289|  2.76k|         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|  2.76k|         } else {
  295|  2.76k|            static_assert(opposite(endianness) == std::endian::native);
  296|  2.76k|            return reverse_bytes(typecast_copy<OutT>(in));
  297|  2.76k|         }
  298|  2.76k|      }
  299|  2.76k|   }());

_ZN5Botan21unchecked_copy_memoryITkNSt3__117unsigned_integralEmEEvPT_PKS2_m:
   44|   718k|inline void unchecked_copy_memory(T* out, const T* in, size_t n) {
   45|   718k|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (45:7): [True: 718k, False: 0]
  |  Branch (45:24): [True: 718k, False: 0]
  |  Branch (45:42): [True: 718k, False: 70]
  ------------------
   46|   718k|      std::memmove(out, in, sizeof(T) * n);
   47|   718k|   }
   48|   718k|}
_ZN5Botan14zeroize_bufferITkNSt3__117unsigned_integralEmEEvPT_m:
   37|   722k|inline void zeroize_buffer(T buf[], size_t n) {
   38|   722k|   if(n > 0) {
  ------------------
  |  Branch (38:7): [True: 23.1k, False: 699k]
  ------------------
   39|  23.1k|      std::memset(buf, 0, sizeof(T) * n);
   40|  23.1k|   }
   41|   722k|}

_ZN5Botan10word8_add3ITkNS_8WordTypeEmEET_PS1_PKS1_S4_S1_:
  294|    351|inline constexpr auto word8_add3(W z[8], const W x[8], const W y[8], W carry) -> W {
  295|    351|#if defined(BOTAN_MP_USE_X86_64_ASM)
  296|    351|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (296:7): [True: 0, Folded]
  |  Branch (296:36): [True: 0, Folded]
  ------------------
  297|    351|      asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "adcq"))
  298|    351|                   : [carry] "=r"(carry)
  299|    351|                   : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry)
  300|    351|                   : "cc", "memory");
  301|    351|      return carry;
  302|    351|   }
  303|      0|#endif
  304|       |
  305|      0|   z[0] = word_add(x[0], y[0], &carry);
  306|      0|   z[1] = word_add(x[1], y[1], &carry);
  307|      0|   z[2] = word_add(x[2], y[2], &carry);
  308|      0|   z[3] = word_add(x[3], y[3], &carry);
  309|      0|   z[4] = word_add(x[4], y[4], &carry);
  310|      0|   z[5] = word_add(x[5], y[5], &carry);
  311|      0|   z[6] = word_add(x[6], y[6], &carry);
  312|      0|   z[7] = word_add(x[7], y[7], &carry);
  313|      0|   return carry;
  314|    351|}
_ZN5Botan8word_addITkNS_8WordTypeEmEET_S1_S1_PS1_:
  231|  20.8k|inline constexpr auto word_add(W x, W y, W* carry) -> W {
  232|  20.8k|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_addc)
  233|  20.8k|   if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (233:7): [True: 20.8k, Folded]
  ------------------
  234|       |      if constexpr(std::same_as<W, unsigned int>) {
  235|       |         return __builtin_addc(x, y, *carry & 1, carry);
  236|  20.8k|      } else if constexpr(std::same_as<W, unsigned long>) {
  237|  20.8k|         return __builtin_addcl(x, y, *carry & 1, carry);
  238|       |      } else if constexpr(std::same_as<W, unsigned long long>) {
  239|       |         return __builtin_addcll(x, y, *carry & 1, carry);
  240|       |      }
  241|  20.8k|   }
  242|      0|#endif
  243|       |
  244|       |   if constexpr(WordInfo<W>::dword_is_native && use_dword_for_word_add) {
  245|       |      /*
  246|       |      TODO(Botan4) this is largely a performance hack for GCCs that don't
  247|       |      support __builtin_addc, if we increase the minimum supported version of
  248|       |      GCC to GCC 14 then we can remove this and not worry about it
  249|       |      */
  250|       |      const W cb = *carry & 1;
  251|       |      const auto s = typename WordInfo<W>::dword(x) + y + cb;
  252|       |      *carry = static_cast<W>(s >> WordInfo<W>::bits);
  253|       |      return static_cast<W>(s);
  254|  20.8k|   } else {
  255|  20.8k|      const W cb = *carry & 1;
  256|  20.8k|      W z = x + y;
  257|  20.8k|      W c1 = (z < x);
  258|  20.8k|      z += cb;
  259|  20.8k|      *carry = c1 | (z < cb);
  260|  20.8k|      return z;
  261|  20.8k|   }
  262|  20.8k|}
_ZN5Botan10word8_sub3ITkNS_8WordTypeEmEET_PS1_PKS1_S4_S1_:
  371|  1.22M|inline constexpr auto word8_sub3(W z[8], const W x[8], const W y[8], W carry) -> W {
  372|  1.22M|#if defined(BOTAN_MP_USE_X86_64_ASM)
  373|  1.22M|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (373:7): [True: 0, Folded]
  |  Branch (373:36): [True: 0, Folded]
  ------------------
  374|  1.22M|      asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB3_OP, "sbbq"))
  375|  1.22M|                   : [carry] "=r"(carry)
  376|  1.22M|                   : [x] "r"(x), [y] "r"(y), [z] "r"(z), "0"(carry)
  377|  1.22M|                   : "cc", "memory");
  378|  1.22M|      return carry;
  379|  1.22M|   }
  380|      0|#endif
  381|       |
  382|      0|   z[0] = word_sub(x[0], y[0], &carry);
  383|      0|   z[1] = word_sub(x[1], y[1], &carry);
  384|      0|   z[2] = word_sub(x[2], y[2], &carry);
  385|      0|   z[3] = word_sub(x[3], y[3], &carry);
  386|      0|   z[4] = word_sub(x[4], y[4], &carry);
  387|      0|   z[5] = word_sub(x[5], y[5], &carry);
  388|      0|   z[6] = word_sub(x[6], y[6], &carry);
  389|      0|   z[7] = word_sub(x[7], y[7], &carry);
  390|      0|   return carry;
  391|  1.22M|}
_ZN5Botan8word_subITkNS_8WordTypeEmEET_S1_S1_PS1_:
  320|  2.54M|inline constexpr auto word_sub(W x, W y, W* carry) -> W {
  321|  2.54M|#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_subc)
  322|  2.54M|   if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (322:7): [True: 2.54M, Folded]
  ------------------
  323|       |      if constexpr(std::same_as<W, unsigned int>) {
  324|       |         return __builtin_subc(x, y, *carry & 1, carry);
  325|  2.54M|      } else if constexpr(std::same_as<W, unsigned long>) {
  326|  2.54M|         return __builtin_subcl(x, y, *carry & 1, carry);
  327|       |      } else if constexpr(std::same_as<W, unsigned long long>) {
  328|       |         return __builtin_subcll(x, y, *carry & 1, carry);
  329|       |      }
  330|  2.54M|   }
  331|      0|#endif
  332|       |
  333|      0|   const W cb = *carry & 1;
  334|  2.54M|   W t0 = x - y;
  335|  2.54M|   W c1 = (t0 > x);
  336|  2.54M|   W z = t0 - cb;
  337|  2.54M|   *carry = c1 | (z > t0);
  338|  2.54M|   return z;
  339|  2.54M|}
_ZN5Botan13word8_linmul3ITkNS_8WordTypeEmEET_PS1_PKS1_S1_S1_:
  397|  29.6k|inline constexpr auto word8_linmul3(W z[8], const W x[8], W y, W carry) -> W {
  398|  29.6k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  399|  29.6k|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (399:7): [True: 0, Folded]
  |  Branch (399:36): [True: 0, Folded]
  ------------------
  400|  29.6k|      asm(DO_8_TIMES(LINMUL_OP, "z")
  401|  29.6k|          : [carry] "=r"(carry)
  402|  29.6k|          : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry)
  403|  29.6k|          : "cc", "%rax", "%rdx", "memory");
  404|  29.6k|      return carry;
  405|  29.6k|   }
  406|      0|#endif
  407|       |
  408|      0|   z[0] = word_madd2(x[0], y, &carry);
  409|      0|   z[1] = word_madd2(x[1], y, &carry);
  410|      0|   z[2] = word_madd2(x[2], y, &carry);
  411|      0|   z[3] = word_madd2(x[3], y, &carry);
  412|      0|   z[4] = word_madd2(x[4], y, &carry);
  413|      0|   z[5] = word_madd2(x[5], y, &carry);
  414|      0|   z[6] = word_madd2(x[6], y, &carry);
  415|      0|   z[7] = word_madd2(x[7], y, &carry);
  416|      0|   return carry;
  417|  29.6k|}
_ZN5Botan10word_madd2ITkNS_8WordTypeEmEET_S1_S1_PS1_:
   90|  89.0k|inline constexpr auto word_madd2(W a, W b, W* c) -> W {
   91|  89.0k|#if defined(BOTAN_MP_USE_X86_64_ASM)
   92|  89.0k|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (92:7): [True: 0, Folded]
  |  Branch (92:36): [True: 0, Folded]
  ------------------
   93|  89.0k|      asm(R"(
   94|  89.0k|         mulq %[b]
   95|  89.0k|         addq %[c],%[a]
   96|  89.0k|         adcq $0,%[carry]
   97|  89.0k|         )"
   98|  89.0k|          : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*c)
   99|  89.0k|          : "0"(a), "1"(b), [c] "g"(*c)
  100|  89.0k|          : "cc");
  101|       |
  102|  89.0k|      return a;
  103|  89.0k|   }
  104|       |#elif defined(BOTAN_MP_USE_AARCH64_ASM)
  105|       |   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  106|       |      W lo = 0;
  107|       |      W hi = 0;
  108|       |      asm(R"(
  109|       |         mul  %[lo], %[a], %[b]
  110|       |         umulh %[hi], %[a], %[b]
  111|       |         adds %[lo], %[lo], %[c]
  112|       |         adc  %[hi], %[hi], xzr
  113|       |         )"
  114|       |          : [lo] "=&r"(lo), [hi] "=&r"(hi)
  115|       |          : [a] "r"(a), [b] "r"(b), [c] "r"(*c)
  116|       |          : "cc");
  117|       |
  118|       |      *c = hi;
  119|       |      return lo;
  120|       |   }
  121|       |#endif
  122|       |
  123|      0|   typedef typename WordInfo<W>::dword dword;
  124|      0|   const dword s = dword(a) * b + *c;
  125|      0|   *c = static_cast<W>(s >> WordInfo<W>::bits);
  126|      0|   return static_cast<W>(s);
  127|  89.0k|}
_ZN5Botan11word8_madd3ITkNS_8WordTypeEmEET_PS1_PKS1_S1_S1_:
  423|  2.24k|inline constexpr auto word8_madd3(W z[8], const W x[8], W y, W carry) -> W {
  424|  2.24k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  425|  2.24k|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (425:7): [True: 0, Folded]
  |  Branch (425:36): [True: 0, Folded]
  ------------------
  426|  2.24k|      asm(DO_8_TIMES(MULADD_OP, "")
  427|  2.24k|          : [carry] "=r"(carry)
  428|  2.24k|          : [z] "r"(z), [x] "r"(x), [y] "rm"(y), "0"(carry)
  429|  2.24k|          : "cc", "%rax", "%rdx", "memory");
  430|  2.24k|      return carry;
  431|  2.24k|   }
  432|      0|#endif
  433|       |
  434|      0|   z[0] = word_madd3(x[0], y, z[0], &carry);
  435|      0|   z[1] = word_madd3(x[1], y, z[1], &carry);
  436|      0|   z[2] = word_madd3(x[2], y, z[2], &carry);
  437|      0|   z[3] = word_madd3(x[3], y, z[3], &carry);
  438|      0|   z[4] = word_madd3(x[4], y, z[4], &carry);
  439|      0|   z[5] = word_madd3(x[5], y, z[5], &carry);
  440|      0|   z[6] = word_madd3(x[6], y, z[6], &carry);
  441|      0|   z[7] = word_madd3(x[7], y, z[7], &carry);
  442|      0|   return carry;
  443|  2.24k|}
_ZN5Botan10word_madd3ITkNS_8WordTypeEmEET_S1_S1_S1_PS1_:
  133|  5.26k|inline constexpr auto word_madd3(W a, W b, W c, W* d) -> W {
  134|  5.26k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  135|  5.26k|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (135:7): [True: 0, Folded]
  |  Branch (135:36): [True: 0, Folded]
  ------------------
  136|  5.26k|      asm(R"(
  137|  5.26k|         mulq %[b]
  138|  5.26k|
  139|  5.26k|         addq %[c],%[a]
  140|  5.26k|         adcq $0,%[carry]
  141|  5.26k|
  142|  5.26k|         addq %[d],%[a]
  143|  5.26k|         adcq $0,%[carry]
  144|  5.26k|         )"
  145|  5.26k|          : [a] "=a"(a), [b] "=rm"(b), [carry] "=&d"(*d)
  146|  5.26k|          : "0"(a), "1"(b), [c] "g"(c), [d] "g"(*d)
  147|  5.26k|          : "cc");
  148|       |
  149|  5.26k|      return a;
  150|  5.26k|   }
  151|       |#elif defined(BOTAN_MP_USE_AARCH64_ASM)
  152|       |   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  153|       |      W lo = 0;
  154|       |      W hi = 0;
  155|       |      asm(R"(
  156|       |         mul  %[lo], %[a], %[b]
  157|       |         umulh %[hi], %[a], %[b]
  158|       |         adds %[lo], %[lo], %[c]
  159|       |         adc  %[hi], %[hi], xzr
  160|       |         adds %[lo], %[lo], %[d]
  161|       |         adc  %[hi], %[hi], xzr
  162|       |         )"
  163|       |          : [lo] "=&r"(lo), [hi] "=&r"(hi)
  164|       |          : [a] "r"(a), [b] "r"(b), [c] "r"(c), [d] "r"(*d)
  165|       |          : "cc");
  166|       |
  167|       |      *d = hi;
  168|       |      return lo;
  169|       |   }
  170|       |#endif
  171|       |
  172|      0|   typedef typename WordInfo<W>::dword dword;
  173|      0|   const dword s = dword(a) * b + c + *d;
  174|      0|   *d = static_cast<W>(s >> WordInfo<W>::bits);
  175|      0|   return static_cast<W>(s);
  176|  5.26k|}
_ZN5Botan10word8_add2ITkNS_8WordTypeEmEET_PS1_PKS1_S1_:
  268|     20|inline constexpr auto word8_add2(W x[8], const W y[8], W carry) -> W {
  269|     20|#if defined(BOTAN_MP_USE_X86_64_ASM)
  270|     20|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (270:7): [True: 0, Folded]
  |  Branch (270:36): [True: 0, Folded]
  ------------------
  271|     20|      asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "adcq"))
  272|     20|                   : [carry] "=r"(carry)
  273|     20|                   : [x] "r"(x), [y] "r"(y), "0"(carry)
  274|     20|                   : "cc", "memory");
  275|     20|      return carry;
  276|     20|   }
  277|      0|#endif
  278|       |
  279|      0|   x[0] = word_add(x[0], y[0], &carry);
  280|      0|   x[1] = word_add(x[1], y[1], &carry);
  281|      0|   x[2] = word_add(x[2], y[2], &carry);
  282|      0|   x[3] = word_add(x[3], y[3], &carry);
  283|      0|   x[4] = word_add(x[4], y[4], &carry);
  284|      0|   x[5] = word_add(x[5], y[5], &carry);
  285|      0|   x[6] = word_add(x[6], y[6], &carry);
  286|      0|   x[7] = word_add(x[7], y[7], &carry);
  287|      0|   return carry;
  288|     20|}
_ZN5Botan10word8_sub2ITkNS_8WordTypeEmEET_PS1_PKS1_S1_:
  345|  29.0k|inline constexpr auto word8_sub2(W x[8], const W y[8], W carry) -> W {
  346|  29.0k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  347|  29.0k|   if(std::same_as<W, uint64_t> && !std::is_constant_evaluated()) {
  ------------------
  |  Branch (347:7): [True: 0, Folded]
  |  Branch (347:36): [True: 0, Folded]
  ------------------
  348|  29.0k|      asm volatile(ADD_OR_SUBTRACT(DO_8_TIMES(ADDSUB2_OP, "sbbq"))
  349|  29.0k|                   : [carry] "=r"(carry)
  350|  29.0k|                   : [x] "r"(x), [y] "r"(y), "0"(carry)
  351|  29.0k|                   : "cc", "memory");
  352|  29.0k|      return carry;
  353|  29.0k|   }
  354|      0|#endif
  355|       |
  356|      0|   x[0] = word_sub(x[0], y[0], &carry);
  357|      0|   x[1] = word_sub(x[1], y[1], &carry);
  358|      0|   x[2] = word_sub(x[2], y[2], &carry);
  359|      0|   x[3] = word_sub(x[3], y[3], &carry);
  360|      0|   x[4] = word_sub(x[4], y[4], &carry);
  361|      0|   x[5] = word_sub(x[5], y[5], &carry);
  362|      0|   x[6] = word_sub(x[6], y[6], &carry);
  363|      0|   x[7] = word_sub(x[7], y[7], &carry);
  364|      0|   return carry;
  365|  29.0k|}
_ZN5Botan5word3ImEC2Ev:
  458|    132|      constexpr word3() : m_w(0) {}
_ZN5Botan5word3ImE3mulEmm:
  460|  24.2k|      inline constexpr void mul(W x, W y) { m_w += static_cast<W3>(x) * y; }
_ZN5Botan5word3ImE7extractEv:
  466|  3.01k|      inline constexpr W extract() {
  467|  3.01k|         W r = static_cast<W>(m_w);
  468|  3.01k|         m_w >>= WordInfo<W>::bits;
  469|  3.01k|         return r;
  470|  3.01k|      }

_ZN5Botan11bigint_add3ITkNS_8WordTypeEmEET_PS1_PKS1_mS4_m:
  120|  4.03k|inline constexpr auto bigint_add3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W {
  121|  4.03k|   if(x_size < y_size) {
  ------------------
  |  Branch (121:7): [True: 639, False: 3.39k]
  ------------------
  122|    639|      return bigint_add3(z, y, y_size, x, x_size);
  123|    639|   }
  124|       |
  125|  3.39k|   W carry = 0;
  126|       |
  127|  3.39k|   const size_t blocks = y_size - (y_size % 8);
  128|       |
  129|  3.75k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (129:22): [True: 351, False: 3.39k]
  ------------------
  130|    351|      carry = word8_add3(z + i, x + i, y + i, carry);
  131|    351|   }
  132|       |
  133|  6.49k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (133:27): [True: 3.09k, False: 3.39k]
  ------------------
  134|  3.09k|      z[i] = word_add(x[i], y[i], &carry);
  135|  3.09k|   }
  136|       |
  137|  20.7k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (137:27): [True: 17.3k, False: 3.39k]
  ------------------
  138|  17.3k|      z[i] = word_add(x[i], static_cast<W>(0), &carry);
  139|  17.3k|   }
  140|       |
  141|  3.39k|   return carry;
  142|  4.03k|}
_ZN5Botan10bigint_cmpITkNS_8WordTypeEmEEiPKT_mS3_m:
  439|  17.9k|inline constexpr int32_t bigint_cmp(const W x[], size_t x_size, const W y[], size_t y_size) {
  440|  17.9k|   static_assert(sizeof(W) >= sizeof(uint32_t), "Size assumption");
  441|       |
  442|  17.9k|   const W LT = static_cast<W>(-1);
  443|  17.9k|   const W EQ = 0;
  444|  17.9k|   const W GT = 1;
  445|       |
  446|  17.9k|   const size_t common_elems = std::min(x_size, y_size);
  447|       |
  448|  17.9k|   W result = EQ;  // until found otherwise
  449|       |
  450|   317k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (450:22): [True: 299k, False: 17.9k]
  ------------------
  451|   299k|      const auto is_eq = CT::Mask<W>::is_equal(x[i], y[i]);
  452|   299k|      const auto is_lt = CT::Mask<W>::is_lt(x[i], y[i]);
  453|       |
  454|   299k|      result = is_eq.select(result, is_lt.select(LT, GT));
  455|   299k|   }
  456|       |
  457|  17.9k|   if(x_size < y_size) {
  ------------------
  |  Branch (457:7): [True: 459, False: 17.5k]
  ------------------
  458|    459|      W mask = 0;
  459|  1.08k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (459:30): [True: 628, False: 459]
  ------------------
  460|    628|         mask |= y[i];
  461|    628|      }
  462|       |
  463|       |      // If any bits were set in high part of y, then x < y
  464|    459|      result = CT::Mask<W>::is_zero(mask).select(result, LT);
  465|  17.5k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (465:14): [True: 328, False: 17.1k]
  ------------------
  466|    328|      W mask = 0;
  467|    656|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (467:30): [True: 328, False: 328]
  ------------------
  468|    328|         mask |= x[i];
  469|    328|      }
  470|       |
  471|       |      // If any bits were set in high part of x, then x > y
  472|    328|      result = CT::Mask<W>::is_zero(mask).select(result, GT);
  473|    328|   }
  474|       |
  475|  17.9k|   CT::unpoison(result);
  476|  17.9k|   BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ);
  ------------------
  |  |  130|  17.9k|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  131|  17.9k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (131:15): [Folded, False: 17.9k]
  |  |  ------------------
  ------------------
  477|  17.9k|   return static_cast<int32_t>(result);
  478|  17.9k|}
_ZN5Botan11bigint_sub3ITkNS_8WordTypeEmEET_PS1_PKS1_mS4_m:
  192|   693k|inline constexpr auto bigint_sub3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W {
  193|   693k|   W borrow = 0;
  194|       |
  195|   693k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   64|   693k|   do {                                                                                 \
  |  |   65|   693k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   66|   693k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (66:10): [True: 0, False: 693k]
  |  |  ------------------
  |  |   67|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   68|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   69|      0|      }                                                                                 \
  |  |   70|   693k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (70:12): [Folded, False: 693k]
  |  |  ------------------
  ------------------
  196|       |
  197|   693k|   const size_t blocks = y_size - (y_size % 8);
  198|       |
  199|  1.91M|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (199:22): [True: 1.22M, False: 693k]
  ------------------
  200|  1.22M|      borrow = word8_sub3(z + i, x + i, y + i, borrow);
  201|  1.22M|   }
  202|       |
  203|  2.47M|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (203:27): [True: 1.78M, False: 693k]
  ------------------
  204|  1.78M|      z[i] = word_sub(x[i], y[i], &borrow);
  205|  1.78M|   }
  206|       |
  207|  1.38M|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (207:27): [True: 693k, False: 693k]
  ------------------
  208|   693k|      z[i] = word_sub(x[i], static_cast<W>(0), &borrow);
  209|   693k|   }
  210|       |
  211|   693k|   return borrow;
  212|   693k|}
_ZN5Botan14bigint_linmul3ITkNS_8WordTypeEmEEvPT_PKS1_mS1_:
  416|  17.4k|inline constexpr void bigint_linmul3(W z[], const W x[], size_t x_size, W y) {
  417|  17.4k|   const size_t blocks = x_size - (x_size % 8);
  418|       |
  419|  17.4k|   W carry = 0;
  420|       |
  421|  47.0k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (421:22): [True: 29.6k, False: 17.4k]
  ------------------
  422|  29.6k|      carry = word8_linmul3(z + i, x + i, y, carry);
  423|  29.6k|   }
  424|       |
  425|  70.1k|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (425:27): [True: 52.7k, False: 17.4k]
  ------------------
  426|  52.7k|      z[i] = word_madd2(x[i], y, &carry);
  427|  52.7k|   }
  428|       |
  429|  17.4k|   z[x_size] = carry;
  430|  17.4k|}
_ZN5Botan14divide_precompImEC2Em:
  574|  3.39k|      explicit constexpr divide_precomp(W divisor) : m_divisor(divisor) {
  575|  3.39k|         BOTAN_ARG_CHECK(m_divisor != 0, "Division by zero");
  ------------------
  |  |   35|  3.39k|   do {                                                          \
  |  |   36|  3.39k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  3.39k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 3.39k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  3.39k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 3.39k]
  |  |  ------------------
  ------------------
  576|  3.39k|      }
_ZNK5Botan14divide_precompImE16vartime_div_2to1Emm:
  581|  16.4k|      inline constexpr W vartime_div_2to1(W n1, W n0) const {
  582|  16.4k|         BOTAN_ASSERT_NOMSG(n1 < m_divisor);
  ------------------
  |  |   77|  16.4k|   do {                                                                     \
  |  |   78|  16.4k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  16.4k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 16.4k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  16.4k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 16.4k]
  |  |  ------------------
  ------------------
  583|       |
  584|  16.4k|         if(m_divisor == WordInfo<W>::max) {
  ------------------
  |  Branch (584:13): [True: 2.86k, False: 13.5k]
  ------------------
  585|  2.86k|            return vartime_div_2to1_max_d(n1, n0);
  586|  2.86k|         }
  587|       |
  588|  13.5k|         if(m_divisor == WordInfo<W>::top_bit) {
  ------------------
  |  Branch (588:13): [True: 3.21k, False: 10.3k]
  ------------------
  589|       |            // Simply a shift by N-1 bits
  590|  3.21k|            return (n1 << 1) | (n0 >> (WordInfo<W>::bits - 1));
  591|  3.21k|         }
  592|       |
  593|  10.3k|         if(!std::is_constant_evaluated()) {
  ------------------
  |  Branch (593:13): [True: 10.3k, Folded]
  ------------------
  594|  10.3k|#if defined(BOTAN_MP_USE_X86_64_ASM)
  595|  10.3k|            if constexpr(std::same_as<W, uint64_t>) {
  596|  10.3k|               W quotient = 0;
  597|  10.3k|               W remainder = 0;
  598|       |               // NOLINTNEXTLINE(*-no-assembler)
  599|  10.3k|               asm("divq %[v]" : "=a"(quotient), "=d"(remainder) : [v] "r"(m_divisor), "a"(n0), "d"(n1) : "cc");
  600|  10.3k|               return quotient;
  601|  10.3k|            }
  602|      0|#endif
  603|       |
  604|      0|#if !defined(BOTAN_BUILD_COMPILER_IS_CLANGCL)
  605|       |
  606|       |            /* clang-cl has a bug where on encountering a 128/64 division it emits
  607|       |            * a call to __udivti3() but then fails to link the relevant builtin into
  608|       |            * the binary, causing a link failure. Work around this by simply omitting
  609|       |            * such code for clang-cl
  610|       |            *
  611|       |            * See https://github.com/llvm/llvm-project/issues/25679
  612|       |            */
  613|  10.3k|            if constexpr(WordInfo<W>::dword_is_native) {
  614|  10.3k|               typename WordInfo<W>::dword n = n1;
  615|  10.3k|               n <<= WordInfo<W>::bits;
  616|  10.3k|               n |= n0;
  617|  10.3k|               return static_cast<W>(n / m_divisor);
  618|  10.3k|            }
  619|  10.3k|#endif
  620|  10.3k|         }
  621|       |
  622|      0|         W high = n1;
  623|  10.3k|         W quotient = 0;
  624|       |
  625|  10.3k|         for(size_t i = 0; i != WordInfo<W>::bits; ++i) {
  ------------------
  |  Branch (625:28): [True: 0, False: 10.3k]
  ------------------
  626|      0|            const W high_top_bit = high >> (WordInfo<W>::bits - 1);
  627|       |
  628|      0|            high <<= 1;
  629|      0|            high |= (n0 >> (WordInfo<W>::bits - 1 - i)) & 1;
  630|      0|            quotient <<= 1;
  631|       |
  632|      0|            if(high_top_bit || high >= m_divisor) {
  ------------------
  |  Branch (632:16): [True: 0, False: 0]
  |  Branch (632:32): [True: 0, False: 0]
  ------------------
  633|      0|               high -= m_divisor;
  634|      0|               quotient |= 1;
  635|      0|            }
  636|      0|         }
  637|       |
  638|  10.3k|         return quotient;
  639|  13.5k|      }
_ZN5Botan14divide_precompImE22vartime_div_2to1_max_dEmm:
  657|  2.86k|      static inline constexpr W vartime_div_2to1_max_d(W n1, W n0) {
  658|       |         /*
  659|       |         Use k to refer to WordInfo<W>::bits
  660|       |
  661|       |         We are dividing n = (n1 * 2^k) + n0 by 2^k - 1
  662|       |
  663|       |         Recall that 2^k = 1 (mod 2^k - 1)
  664|       |
  665|       |         Rewrite n = n1*2^k + n0 as n1*(2^k - 1) + n1 + n0
  666|       |
  667|       |         The result of dividing n by (2^k - 1) will be equal to
  668|       |         (n1*(2^k-1) + n1 + n0) / (2^k-1) =
  669|       |         n1 + ((n1 + n0) / (2^k-1)
  670|       |
  671|       |         Use c to refer to ((n1 + n0) / (2^k-1))
  672|       |
  673|       |         If (n1 + n0) < (2^k - 1) then c is 0
  674|       |         If (n1 + n0) >= (2^k - 1) then c is 1
  675|       |
  676|       |         Since n1 < 2^k - 1 [*] and n0 <= 2^k - 1 it is impossible for (n1 + n0) / (2^k -1)
  677|       |         to be greater than 1.
  678|       |
  679|       |         [*] We require n1 be strictly less than the divisor to ensure that the
  680|       |         output fits in a single word; this is checked at the start of vartime_div_2to1.
  681|       |         */
  682|       |
  683|  2.86k|         const W s = n0 + n1;
  684|       |         // did n0 + n1 overflow? or does (n0 + n1) == 2^k - 1? if either, c == 1
  685|  2.86k|         if(s < n0 || s == WordInfo<W>::max) {
  ------------------
  |  Branch (685:13): [True: 862, False: 2.00k]
  |  Branch (685:23): [True: 174, False: 1.82k]
  ------------------
  686|  1.03k|            n1 += 1;
  687|  1.03k|         }
  688|       |
  689|  2.86k|         return n1;
  690|  2.86k|      }
_ZN5Botan11bigint_shl2ITkNS_8WordTypeEmEEvPT_mPKS1_mm:
  355|  3.39k|inline constexpr void bigint_shl2(W y[], size_t y_size, const W x[], size_t x_size, size_t shift) {
  356|  3.39k|   const size_t word_shift = shift / WordInfo<W>::bits;
  357|  3.39k|   const size_t bit_shift = shift % WordInfo<W>::bits;
  358|       |
  359|  3.39k|   BOTAN_ASSERT_NOMSG(word_shift <= y_size);
  ------------------
  |  |   77|  3.39k|   do {                                                                     \
  |  |   78|  3.39k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  3.39k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 3.39k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  3.39k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 3.39k]
  |  |  ------------------
  ------------------
  360|  3.39k|   BOTAN_ASSERT_NOMSG(x_size < y_size - word_shift);
  ------------------
  |  |   77|  3.39k|   do {                                                                     \
  |  |   78|  3.39k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  3.39k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 3.39k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  3.39k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 3.39k]
  |  |  ------------------
  ------------------
  361|       |
  362|  3.39k|   unchecked_copy_memory(y + word_shift, x, x_size);
  363|  3.39k|   zeroize_buffer(y, word_shift);
  364|  3.39k|   zeroize_buffer(y + word_shift + x_size, y_size - word_shift - x_size);
  365|       |
  366|  3.39k|   const auto carry_mask = CT::Mask<W>::expand(bit_shift);
  367|  3.39k|   const W carry_shift = carry_mask.if_set_return(WordInfo<W>::bits - bit_shift);
  368|       |
  369|  3.39k|   W carry = 0;
  370|  15.3k|   for(size_t i = word_shift; i != x_size + word_shift + 1; ++i) {
  ------------------
  |  Branch (370:31): [True: 11.9k, False: 3.39k]
  ------------------
  371|  11.9k|      const W w = y[i];
  372|  11.9k|      y[i] = (w << bit_shift) | carry;
  373|  11.9k|      carry = carry_mask.if_set_return(w >> carry_shift);
  374|  11.9k|   }
  375|  3.39k|}
_ZN5Botan15bigint_ct_is_eqITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPKS3_mS6_m:
  519|  8.49k|inline constexpr auto bigint_ct_is_eq(const W x[], size_t x_size, const W y[], size_t y_size) -> CT::Mask<W> {
  520|  8.49k|   const size_t common_elems = std::min(x_size, y_size);
  521|       |
  522|  8.49k|   W diff = 0;
  523|       |
  524|   107k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (524:22): [True: 98.5k, False: 8.49k]
  ------------------
  525|  98.5k|      diff |= (x[i] ^ y[i]);
  526|  98.5k|   }
  527|       |
  528|       |   // If any bits were set in high part of x/y, then they are not equal
  529|  8.49k|   if(x_size < y_size) {
  ------------------
  |  Branch (529:7): [True: 370, False: 8.12k]
  ------------------
  530|  5.83k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (530:30): [True: 5.46k, False: 370]
  ------------------
  531|  5.46k|         diff |= y[i];
  532|  5.46k|      }
  533|  8.12k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (533:14): [True: 641, False: 7.48k]
  ------------------
  534|  9.04k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (534:30): [True: 8.40k, False: 641]
  ------------------
  535|  8.40k|         diff |= x[i];
  536|  8.40k|      }
  537|    641|   }
  538|       |
  539|  8.49k|   return CT::Mask<W>::is_zero(diff);
  540|  8.49k|}
_ZN5Botan15bigint_ct_is_ltITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPKS3_mS6_mb:
  487|  3.39k|   -> CT::Mask<W> {
  488|  3.39k|   const size_t common_elems = std::min(x_size, y_size);
  489|       |
  490|  3.39k|   auto is_lt = CT::Mask<W>::expand(lt_or_equal);
  491|       |
  492|  38.1k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (492:22): [True: 34.7k, False: 3.39k]
  ------------------
  493|  34.7k|      const auto eq = CT::Mask<W>::is_equal(x[i], y[i]);
  494|  34.7k|      const auto lt = CT::Mask<W>::is_lt(x[i], y[i]);
  495|  34.7k|      is_lt = eq.select_mask(is_lt, lt);
  496|  34.7k|   }
  497|       |
  498|  3.39k|   if(x_size < y_size) {
  ------------------
  |  Branch (498:7): [True: 108, False: 3.28k]
  ------------------
  499|    108|      W mask = 0;
  500|    742|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (500:30): [True: 634, False: 108]
  ------------------
  501|    634|         mask |= y[i];
  502|    634|      }
  503|       |      // If any bits were set in high part of y, then is_lt should be forced true
  504|    108|      is_lt |= CT::Mask<W>::expand(mask);
  505|  3.28k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (505:14): [True: 481, False: 2.80k]
  ------------------
  506|    481|      W mask = 0;
  507|  10.0k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (507:30): [True: 9.61k, False: 481]
  ------------------
  508|  9.61k|         mask |= x[i];
  509|  9.61k|      }
  510|       |
  511|       |      // If any bits were set in high part of x, then is_lt should be false
  512|    481|      is_lt &= CT::Mask<W>::is_zero(mask);
  513|    481|   }
  514|       |
  515|  3.39k|   return is_lt;
  516|  3.39k|}
_ZN5Botan15bigint_cnd_swapITkNS_8WordTypeEmEEvT_PS1_S2_m:
   29|   690k|inline constexpr void bigint_cnd_swap(W cnd, W x[], W y[], size_t size) {
   30|   690k|   const auto mask = CT::Mask<W>::expand(cnd);
   31|       |
   32|  12.9M|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (32:22): [True: 12.2M, False: 690k]
  ------------------
   33|  12.2M|      const W a = x[i];
   34|  12.2M|      const W b = y[i];
   35|  12.2M|      x[i] = mask.select(b, a);
   36|  12.2M|      y[i] = mask.select(a, b);
   37|  12.2M|   }
   38|   690k|}
_ZN5Botan11bigint_shl1ITkNS_8WordTypeEmEEvPT_mmm:
  309|   695k|inline constexpr void bigint_shl1(W x[], size_t x_size, size_t x_words, size_t shift) {
  310|   695k|   const size_t word_shift = shift / WordInfo<W>::bits;
  311|   695k|   const size_t bit_shift = shift % WordInfo<W>::bits;
  312|       |
  313|   695k|   BOTAN_ASSERT_NOMSG(word_shift <= x_size);
  ------------------
  |  |   77|   695k|   do {                                                                     \
  |  |   78|   695k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|   695k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 695k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|   695k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 695k]
  |  |  ------------------
  ------------------
  314|   695k|   BOTAN_ASSERT_NOMSG(x_words <= x_size - word_shift);
  ------------------
  |  |   77|   695k|   do {                                                                     \
  |  |   78|   695k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|   695k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 695k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|   695k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 695k]
  |  |  ------------------
  ------------------
  315|       |
  316|   695k|   unchecked_copy_memory(x + word_shift, x, x_words);
  317|   695k|   zeroize_buffer(x, word_shift);
  318|       |
  319|   695k|   const auto carry_mask = CT::Mask<W>::expand(bit_shift);
  320|   695k|   const W carry_shift = carry_mask.if_set_return(WordInfo<W>::bits - bit_shift);
  321|       |
  322|   695k|   W carry = 0;
  323|  12.9M|   for(size_t i = word_shift; i != x_size; ++i) {
  ------------------
  |  Branch (323:31): [True: 12.2M, False: 695k]
  ------------------
  324|  12.2M|      const W w = x[i];
  325|  12.2M|      x[i] = (w << bit_shift) | carry;
  326|  12.2M|      carry = carry_mask.if_set_return(w >> carry_shift);
  327|  12.2M|   }
  328|   695k|}
_ZN5Botan14bigint_sub_absITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPS3_PKS3_S7_mS5_:
  279|     10|inline constexpr auto bigint_sub_abs(W z[], const W x[], const W y[], size_t N, W ws[]) -> CT::Mask<W> {
  280|       |   // Subtract in both direction then conditional copy out the result
  281|       |
  282|     10|   W* ws0 = ws;
  283|     10|   W* ws1 = ws + N;
  284|       |
  285|     10|   W borrow0 = 0;
  286|     10|   W borrow1 = 0;
  287|       |
  288|     10|   const size_t blocks = N - (N % 8);
  289|       |
  290|     30|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (290:22): [True: 20, False: 10]
  ------------------
  291|     20|      borrow0 = word8_sub3(ws0 + i, x + i, y + i, borrow0);
  292|     20|      borrow1 = word8_sub3(ws1 + i, y + i, x + i, borrow1);
  293|     20|   }
  294|       |
  295|     22|   for(size_t i = blocks; i != N; ++i) {
  ------------------
  |  Branch (295:27): [True: 12, False: 10]
  ------------------
  296|     12|      ws0[i] = word_sub(x[i], y[i], &borrow0);
  297|     12|      ws1[i] = word_sub(y[i], x[i], &borrow1);
  298|     12|   }
  299|       |
  300|     10|   return CT::conditional_copy_mem(borrow0, z, ws1, ws0, N);
  301|     10|}
_ZN5Botan11bigint_add2ITkNS_8WordTypeEmEET_PS1_mPKS1_m:
   94|     15|inline constexpr auto bigint_add2(W x[], size_t x_size, const W y[], size_t y_size) -> W {
   95|     15|   W carry = 0;
   96|       |
   97|     15|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   64|     15|   do {                                                                                 \
  |  |   65|     15|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   66|     15|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (66:10): [True: 0, False: 15]
  |  |  ------------------
  |  |   67|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   68|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   69|      0|      }                                                                                 \
  |  |   70|     15|   } while(0)
  |  |  ------------------
  |  |  |  Branch (70:12): [Folded, False: 15]
  |  |  ------------------
  ------------------
   98|       |
   99|     15|   const size_t blocks = y_size - (y_size % 8);
  100|       |
  101|     35|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (101:22): [True: 20, False: 15]
  ------------------
  102|     20|      carry = word8_add2(x + i, y + i, carry);
  103|     20|   }
  104|       |
  105|     37|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (105:27): [True: 22, False: 15]
  ------------------
  106|     22|      x[i] = word_add(x[i], y[i], &carry);
  107|     22|   }
  108|       |
  109|    177|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (109:27): [True: 162, False: 15]
  ------------------
  110|    162|      x[i] = word_add(x[i], static_cast<W>(0), &carry);
  111|    162|   }
  112|       |
  113|     15|   return carry;
  114|     15|}
_ZN5Botan14bigint_cnd_addITkNS_8WordTypeEmEET_S1_PS1_PKS1_m:
   45|      5|inline constexpr W bigint_cnd_add(W cnd, W x[], const W y[], size_t size) {
   46|      5|   const auto mask = CT::Mask<W>::expand(cnd).value();
   47|       |
   48|      5|   W carry = 0;
   49|       |
   50|    263|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (50:22): [True: 258, False: 5]
  ------------------
   51|    258|      x[i] = word_add(x[i], y[i] & mask, &carry);
   52|    258|   }
   53|       |
   54|      5|   return (mask & carry);
   55|      5|}
_ZN5Botan14bigint_cnd_subITkNS_8WordTypeEmEET_S1_PS1_PKS1_m:
   62|      5|inline constexpr auto bigint_cnd_sub(W cnd, W x[], const W y[], size_t size) -> W {
   63|      5|   const auto mask = CT::Mask<W>::expand(cnd).value();
   64|       |
   65|      5|   W carry = 0;
   66|       |
   67|    263|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (67:22): [True: 258, False: 5]
  ------------------
   68|    258|      x[i] = word_sub(x[i], y[i] & mask, &carry);
   69|    258|   }
   70|       |
   71|      5|   return (mask & carry);
   72|      5|}
_ZN5Botan11bigint_sub2ITkNS_8WordTypeEmEET_PS1_mPKS1_m:
  148|  14.5k|inline constexpr auto bigint_sub2(W x[], size_t x_size, const W y[], size_t y_size) -> W {
  149|  14.5k|   W borrow = 0;
  150|       |
  151|  14.5k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   64|  14.5k|   do {                                                                                 \
  |  |   65|  14.5k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   66|  14.5k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (66:10): [True: 0, False: 14.5k]
  |  |  ------------------
  |  |   67|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   68|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   69|      0|      }                                                                                 \
  |  |   70|  14.5k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (70:12): [Folded, False: 14.5k]
  |  |  ------------------
  ------------------
  152|       |
  153|  14.5k|   const size_t blocks = y_size - (y_size % 8);
  154|       |
  155|  43.5k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (155:22): [True: 29.0k, False: 14.5k]
  ------------------
  156|  29.0k|      borrow = word8_sub2(x + i, y + i, borrow);
  157|  29.0k|   }
  158|       |
  159|  63.8k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (159:27): [True: 49.3k, False: 14.5k]
  ------------------
  160|  49.3k|      x[i] = word_sub(x[i], y[i], &borrow);
  161|  49.3k|   }
  162|       |
  163|  14.9k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (163:27): [True: 328, False: 14.5k]
  ------------------
  164|    328|      x[i] = word_sub(x[i], static_cast<W>(0), &borrow);
  165|    328|   }
  166|       |
  167|  14.5k|   return borrow;
  168|  14.5k|}
_ZN5Botan15bigint_sub2_revITkNS_8WordTypeEmEEvPT_PKS1_m:
  174|    866|inline constexpr void bigint_sub2_rev(W x[], const W y[], size_t y_size) {
  175|    866|   W borrow = 0;
  176|       |
  177|  17.1k|   for(size_t i = 0; i != y_size; ++i) {
  ------------------
  |  Branch (177:22): [True: 16.3k, False: 866]
  ------------------
  178|  16.3k|      x[i] = word_sub(y[i], x[i], &borrow);
  179|  16.3k|   }
  180|       |
  181|    866|   BOTAN_ASSERT(borrow == 0, "y must be greater than x");
  ------------------
  |  |   64|    866|   do {                                                                                 \
  |  |   65|    866|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   66|    866|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (66:10): [True: 0, False: 866]
  |  |  ------------------
  |  |   67|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   68|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   69|      0|      }                                                                                 \
  |  |   70|    866|   } while(0)
  |  |  ------------------
  |  |  |  Branch (70:12): [Folded, False: 866]
  |  |  ------------------
  ------------------
  182|    866|}
_ZN5Botan11bigint_shr1ITkNS_8WordTypeEmEEvPT_mm:
  331|  19.5k|inline constexpr void bigint_shr1(W x[], size_t x_size, size_t shift) {
  332|  19.5k|   const size_t word_shift = shift / WordInfo<W>::bits;
  333|  19.5k|   const size_t bit_shift = shift % WordInfo<W>::bits;
  334|       |
  335|  19.5k|   const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0;
  ------------------
  |  Branch (335:23): [True: 19.5k, False: 0]
  ------------------
  336|       |
  337|  19.5k|   if(top > 0) {
  ------------------
  |  Branch (337:7): [True: 19.5k, False: 0]
  ------------------
  338|  19.5k|      unchecked_copy_memory(x, x + word_shift, top);
  339|  19.5k|   }
  340|  19.5k|   zeroize_buffer(x + top, std::min(word_shift, x_size));
  341|       |
  342|  19.5k|   const auto carry_mask = CT::Mask<W>::expand(bit_shift);
  343|  19.5k|   const W carry_shift = carry_mask.if_set_return(WordInfo<W>::bits - bit_shift);
  344|       |
  345|  19.5k|   W carry = 0;
  346|       |
  347|   728k|   for(size_t i = 0; i != top; ++i) {
  ------------------
  |  Branch (347:22): [True: 708k, False: 19.5k]
  ------------------
  348|   708k|      const W w = x[top - i - 1];
  349|   708k|      x[top - i - 1] = (w >> bit_shift) | carry;
  350|   708k|      carry = carry_mask.if_set_return(w << carry_shift);
  351|   708k|   }
  352|  19.5k|}

_ZN5Botan8round_upEmm:
   26|  3.42k|constexpr inline size_t round_up(size_t n, size_t align_to) {
   27|       |   // Arguably returning n in this case would also be sensible
   28|  3.42k|   BOTAN_ARG_CHECK(align_to != 0, "align_to must not be 0");
  ------------------
  |  |   35|  3.42k|   do {                                                          \
  |  |   36|  3.42k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  3.42k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 3.42k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  3.42k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 3.42k]
  |  |  ------------------
  ------------------
   29|       |
   30|  3.42k|   if(n % align_to > 0) {
  ------------------
  |  Branch (30:7): [True: 3.18k, False: 242]
  ------------------
   31|  3.18k|      const size_t adj = align_to - (n % align_to);
   32|  3.18k|      BOTAN_ARG_CHECK(n + adj >= n, "Integer overflow during rounding");
  ------------------
  |  |   35|  3.18k|   do {                                                          \
  |  |   36|  3.18k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  3.18k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 3.18k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  3.18k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 3.18k]
  |  |  ------------------
  ------------------
   33|  3.18k|      n += adj;
   34|  3.18k|   }
   35|  3.42k|   return n;
   36|  3.42k|}

_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEmQntsr3stdE7same_asIbT_EEES3_S3_:
   43|  52.9M|constexpr inline T value_barrier(T x) {
   44|  52.9M|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 52.9M]
  ------------------
   45|      0|      return x;
   46|  52.9M|   } else {
   47|  52.9M|#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|  52.9M|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|  52.9M|      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|  52.9M|   }
   64|  52.9M|}
_ZN5Botan2CT13value_barrierITkNSt3__117unsigned_integralEhQntsr3stdE7same_asIbT_EEES3_S3_:
   43|  42.4k|constexpr inline T value_barrier(T x) {
   44|  42.4k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (44:7): [Folded, False: 42.4k]
  ------------------
   45|      0|      return x;
   46|  42.4k|   } else {
   47|  42.4k|#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|  42.4k|      asm("" : "+r"(x) : /* no input */);  // NOLINT(*-no-assembler)
   56|  42.4k|      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|  42.4k|   }
   64|  42.4k|}

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

_ZN5Botan6BigIntD2Ev:
  185|  47.3k|      ~BigInt() { _const_time_unpoison(); }
_ZN5Botan6BigIntaSEOS0_:
  190|  8.52k|      BigInt& operator=(BigInt&& other) noexcept {
  191|  8.52k|         if(this != &other) {
  ------------------
  |  Branch (191:13): [True: 8.52k, False: 0]
  ------------------
  192|  8.52k|            this->swap(other);
  193|  8.52k|         }
  194|       |
  195|  8.52k|         return (*this);
  196|  8.52k|      }
_ZN5Botan6BigInt4swapERS0_:
  207|  8.52k|      void swap(BigInt& other) noexcept {
  208|  8.52k|         m_data.swap(other.m_data);
  209|  8.52k|         std::swap(m_signedness, other.m_signedness);
  210|  8.52k|      }
_ZN5Botan6BigInt4Data4swapERS1_:
 1090|  8.52k|            void swap(Data& other) noexcept {
 1091|  8.52k|               m_reg.swap(other.m_reg);
 1092|  8.52k|               std::swap(m_sig_words, other.m_sig_words);
 1093|  8.52k|            }
_ZN5BotaneqERKNS_6BigIntEm:
 1186|  3.42k|inline bool operator==(const BigInt& a, word b) {
 1187|  3.42k|   return (a.cmp_word(b) == 0);
 1188|  3.42k|}
_ZN5BotanltERKNS_6BigIntES2_:
 1178|  3.39k|inline bool operator<(const BigInt& a, const BigInt& b) {
 1179|  3.39k|   return a.is_less_than(b);
 1180|  3.39k|}
_ZN5BotanplERKNS_6BigIntES2_:
 1125|  3.39k|inline BigInt operator+(const BigInt& x, const BigInt& y) {
 1126|  3.39k|   return BigInt::add2(x, y._data(), y.sig_words(), y.sign());
 1127|  3.39k|}
_ZNK5Botan6BigInt5_dataEv:
  972|  1.47M|      const word* _data() const { return m_data.const_data(); }
_ZNK5Botan6BigInt4Data10const_dataEv:
 1027|  1.52M|            const word* const_data() const { return m_reg.data(); }
_ZNK5Botan6BigInt9sig_wordsEv:
  648|   171k|      size_t sig_words() const { return m_data.sig_words(); }
_ZNK5Botan6BigInt4Data9sig_wordsEv:
 1102|   171k|            size_t sig_words() const {
 1103|   171k|               if(m_sig_words == sig_words_npos) {
  ------------------
  |  Branch (1103:19): [True: 72.4k, False: 99.0k]
  ------------------
 1104|  72.4k|                  m_sig_words = calc_sig_words();
 1105|  72.4k|               }
 1106|   171k|               return m_sig_words;
 1107|   171k|            }
_ZNK5Botan6BigInt4signEv:
  604|   144k|      Sign sign() const { return (m_signedness); }
_ZN5BotanneERKNS_6BigIntES2_:
 1166|  8.49k|inline bool operator!=(const BigInt& a, const BigInt& b) {
 1167|  8.49k|   return !a.is_equal(b);
 1168|  8.49k|}
_ZNK5Botan6BigInt7word_atEm:
  574|  3.47M|      word word_at(size_t n) const { return m_data.get_word_at(n); }
_ZNK5Botan6BigInt4Data11get_word_atEm:
 1038|  3.47M|            word get_word_at(size_t n) const {
 1039|  3.47M|               if(n < m_reg.size()) {
  ------------------
  |  Branch (1039:19): [True: 3.47M, False: 4.47k]
  ------------------
 1040|  3.47M|                  return m_reg[n];
 1041|  3.47M|               }
 1042|  4.47k|               return 0;
 1043|  3.47M|            }
_ZN5Botan6BigInt4zeroEv:
   50|  3.39k|      static BigInt zero() { return BigInt(); }
_ZN5Botan6BigInt8swap_regERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  214|    160|      BOTAN_DEPRECATED("Deprecated no replacement") void swap_reg(secure_vector<word>& reg) {
  215|    160|         m_data.swap(reg);
  216|       |         // sign left unchanged
  217|    160|      }
_ZN5Botan6BigInt3subEPKmmNS0_4SignE:
  332|  15.0k|      BigInt& sub(const word y[], size_t y_words, Sign sign) {
  333|  15.0k|         return add(y, y_words, sign == Positive ? Negative : Positive);
  ------------------
  |  Branch (333:33): [True: 15.0k, False: 0]
  ------------------
  334|  15.0k|      }
_ZN5Botan6BigInt5clearEv:
  415|  3.42k|      void clear() {
  416|  3.42k|         m_data.set_to_zero();
  417|  3.42k|         m_signedness = Positive;
  418|  3.42k|      }
_ZNK5Botan6BigInt6signumEv:
  467|  46.0k|      int signum() const {
  468|  46.0k|         if(sig_words() == 0) {
  ------------------
  |  Branch (468:13): [True: 1.96k, False: 44.0k]
  ------------------
  469|  1.96k|            return 0;
  470|  1.96k|         }
  471|  44.0k|         return (sign() == Negative) ? -1 : 1;
  ------------------
  |  Branch (471:17): [True: 433, False: 43.6k]
  ------------------
  472|  46.0k|      }
_ZNK5Botan6BigInt7is_zeroEv:
  484|  8.93k|      bool is_zero() const { return sig_words() == 0; }
_ZN5Botan6BigInt21conditionally_set_bitEmb:
  500|  2.04M|      void conditionally_set_bit(size_t n, bool set_it) {
  501|  2.04M|         const size_t which = n / (sizeof(word) * 8);
  502|  2.04M|         const word mask = static_cast<word>(set_it) << (n % (sizeof(word) * 8));
  503|  2.04M|         m_data.set_word_at(which, word_at(which) | mask);
  504|  2.04M|      }
_ZNK5Botan6BigInt7get_bitEm:
  523|  1.35M|      bool get_bit(size_t n) const { return ((word_at(n / (sizeof(word) * 8)) >> (n % (sizeof(word) * 8))) & 1) == 1; }
_ZN5Botan6BigInt8set_signENS0_4SignE:
  625|  38.4k|      void set_sign(Sign sign) {
  626|  38.4k|         if(sign == Negative && is_zero()) {
  ------------------
  |  Branch (626:13): [True: 433, False: 38.0k]
  |  Branch (626:33): [True: 0, False: 433]
  ------------------
  627|      0|            sign = Positive;
  628|      0|         }
  629|       |
  630|  38.4k|         m_signedness = sign;
  631|  38.4k|      }
_ZNK5Botan6BigInt4sizeEv:
  642|  34.9k|      size_t size() const { return m_data.size(); }
_ZN5Botan6BigInt12mutable_dataEv:
  673|  2.80M|      BOTAN_DEPRECATED("Deprecated no replacement") word* mutable_data() { return m_data.mutable_data(); }
_ZNK5Botan6BigInt7grow_toEm:
  699|  50.9k|      BOTAN_DEPRECATED("Deprecated no replacement") void grow_to(size_t n) const { m_data.grow_to(n); }
_ZN5Botan6BigInt4Data12mutable_dataEv:
 1022|  2.83M|            word* mutable_data() {
 1023|  2.83M|               invalidate_sig_words();
 1024|  2.83M|               return m_reg.data();
 1025|  2.83M|            }
_ZN5Botan6BigInt4Data11set_word_atEmm:
 1045|  2.05M|            void set_word_at(size_t i, word w) {
 1046|  2.05M|               invalidate_sig_words();
 1047|  2.05M|               if(i >= m_reg.size()) {
  ------------------
  |  Branch (1047:19): [True: 1.70k, False: 2.04M]
  ------------------
 1048|  1.70k|                  if(w == 0) {
  ------------------
  |  Branch (1048:22): [True: 24, False: 1.68k]
  ------------------
 1049|     24|                     return;
 1050|     24|                  }
 1051|  1.68k|                  grow_to(i + 1);
 1052|  1.68k|               }
 1053|  2.05M|               m_reg[i] = w;
 1054|  2.05M|            }
_ZNK5Botan6BigInt4Data7grow_toEm:
 1065|  58.0k|            void grow_to(size_t n) const {
 1066|  58.0k|               if(n > size()) {
  ------------------
  |  Branch (1066:19): [True: 37.3k, False: 20.6k]
  ------------------
 1067|  37.3k|                  if(n <= m_reg.capacity()) {
  ------------------
  |  Branch (1067:22): [True: 0, False: 37.3k]
  ------------------
 1068|      0|                     m_reg.resize(n);
 1069|  37.3k|                  } else {
 1070|  37.3k|                     m_reg.resize(n + (8 - (n % 8)));
 1071|  37.3k|                  }
 1072|  37.3k|               }
 1073|  58.0k|            }
_ZNK5Botan6BigInt4Data4sizeEv:
 1075|   159k|            size_t size() const { return m_reg.size(); }
_ZN5Botan6BigInt4Data4swapERNSt3__16vectorImNS_16secure_allocatorImEEEE:
 1095|  3.58k|            void swap(secure_vector<word>& reg) noexcept {
 1096|  3.58k|               m_reg.swap(reg);
 1097|  3.58k|               invalidate_sig_words();
 1098|  3.58k|            }
_ZNK5Botan6BigInt4Data20invalidate_sig_wordsEv:
 1100|  4.88M|            void invalidate_sig_words() const noexcept { m_sig_words = sig_words_npos; }
_ZN5BotanmlEmRKNS_6BigIntE:
 1148|  15.0k|inline BigInt operator*(word x, const BigInt& y) {
 1149|  15.0k|   return y * x;
 1150|  15.0k|}
_ZN5Botan6BigIntC2Ev:
   45|  38.8k|      BigInt() = default;
_ZN5Botan6BigIntC2ERKS0_:
   88|  6.78k|      BigInt(const BigInt& other) = default;
_ZN5Botan6BigIntaSERKS0_:
  201|  11.8k|      BigInt& operator=(const BigInt&) = default;

_ZN5Botan9clear_memImEEvPT_m:
  118|  6.81k|inline constexpr void clear_mem(T* ptr, size_t n) {
  119|  6.81k|   clear_bytes(ptr, sizeof(T) * n);
  120|  6.81k|}
_ZN5Botan11clear_bytesEPvm:
  101|  6.81k|inline constexpr void clear_bytes(void* ptr, size_t bytes) {
  102|  6.81k|   if(bytes > 0) {
  ------------------
  |  Branch (102:7): [True: 3.39k, False: 3.42k]
  ------------------
  103|  3.39k|      std::memset(ptr, 0, bytes);
  104|  3.39k|   }
  105|  6.81k|}
_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|  21.8k|inline constexpr ToT typecast_copy(const FromR& src) {
  211|  21.8k|   ToT dst;  // NOLINT(*-member-init)
  212|  21.8k|   typecast_copy(dst, src);
  213|  21.8k|   return dst;
  214|  21.8k|}
_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|  21.8k|inline constexpr void typecast_copy(ToT& out, const FromR& in) {
  189|  21.8k|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|  21.8k|}
_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|  21.8k|inline constexpr void typecast_copy(ToR&& out /* NOLINT(*-std-forward) */, const FromR& in) {
  177|  21.8k|   ranges::assert_equal_byte_lengths(out, in);
  178|  21.8k|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|  21.8k|}
_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|  2.76k|inline constexpr void copy_mem(OutR&& out /* NOLINT(*-std-forward) */, const InR& in) {
  161|  2.76k|   ranges::assert_equal_byte_lengths(out, in);
  162|  2.76k|   if(std::is_constant_evaluated()) {
  ------------------
  |  Branch (162:7): [Folded, False: 2.76k]
  ------------------
  163|      0|      std::copy(std::ranges::begin(in), std::ranges::end(in), std::ranges::begin(out));
  164|  2.76k|   } else if(ranges::size_bytes(out) > 0) {
  ------------------
  |  Branch (164:14): [True: 2.76k, False: 0]
  ------------------
  165|  2.76k|      std::memmove(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  166|  2.76k|   }
  167|  2.76k|}
_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|  2.76k|inline constexpr ToT typecast_copy(const FromR& src) {
  211|  2.76k|   ToT dst;  // NOLINT(*-member-init)
  212|  2.76k|   typecast_copy(dst, src);
  213|  2.76k|   return dst;
  214|  2.76k|}
_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|  2.76k|inline constexpr void typecast_copy(ToT& out, const FromR& in) {
  189|  2.76k|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  190|  2.76k|}
_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|  2.76k|inline constexpr void typecast_copy(ToR&& out /* NOLINT(*-std-forward) */, const FromR& in) {
  177|  2.76k|   ranges::assert_equal_byte_lengths(out, in);
  178|  2.76k|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  179|  2.76k|}

_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeENSt3__14spanIhLm8EEEEEvRKT0_:
   77|  2.76k|inline constexpr void assert_exact_byte_length(const R& r) {
   78|  2.76k|   const std::span s{r};
   79|  2.76k|   if constexpr(statically_spanable_range<R>) {
   80|  2.76k|      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|  2.76k|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeENSt3__14spanIKhLm8EEEEEvRKT0_:
   77|  43.7k|inline constexpr void assert_exact_byte_length(const R& r) {
   78|  43.7k|   const std::span s{r};
   79|  43.7k|   if constexpr(statically_spanable_range<R>) {
   80|  43.7k|      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|  43.7k|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeENSt3__14spanImLm1EEETpTkNS0_14spanable_rangeEJNS3_IKhLm8EEEEEEvRKT_DpRKT0_QgtsZT0_Li0E:
  100|  21.8k|{
  101|  21.8k|   const std::span s0{r0};
  102|       |
  103|  21.8k|   if constexpr(statically_spanable_range<R0>) {
  104|  21.8k|      constexpr size_t expected_size = s0.size_bytes();
  105|  21.8k|      (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|  21.8k|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeENSt3__14spanImLm1EEEEEmRKT_:
   59|  24.6k|inline constexpr size_t size_bytes(const spanable_range auto& r) {
   60|  24.6k|   return std::span{r}.size_bytes();
   61|  24.6k|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeENSt3__14spanIhLm18446744073709551615EEETpTkNS0_14spanable_rangeEJNS3_IKhLm18446744073709551615EEEEEEvRKT_DpRKT0_QgtsZT0_Li0E:
  100|  2.76k|{
  101|  2.76k|   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|  2.76k|   } else {
  107|  2.76k|      const size_t expected_size = s0.size_bytes();
  108|  2.76k|      const bool correct_size =
  109|  2.76k|         ((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...);
  110|       |
  111|  2.76k|      if(!correct_size) {
  ------------------
  |  Branch (111:10): [True: 0, False: 2.76k]
  ------------------
  112|      0|         memory_region_size_violation();
  113|      0|      }
  114|  2.76k|   }
  115|  2.76k|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeENSt3__14spanIhLm18446744073709551615EEEEEmRKT_:
   59|  5.52k|inline constexpr size_t size_bytes(const spanable_range auto& r) {
   60|  5.52k|   return std::span{r}.size_bytes();
   61|  5.52k|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeENSt3__15arrayIhLm8EEEEEvRKT0_:
   77|  2.76k|inline constexpr void assert_exact_byte_length(const R& r) {
   78|  2.76k|   const std::span s{r};
   79|  2.76k|   if constexpr(statically_spanable_range<R>) {
   80|  2.76k|      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|  2.76k|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeENSt3__14spanImLm1EEETpTkNS0_14spanable_rangeEJNS3_IhLm8EEEEEEvRKT_DpRKT0_QgtsZT0_Li0E:
  100|  2.76k|{
  101|  2.76k|   const std::span s0{r0};
  102|       |
  103|  2.76k|   if constexpr(statically_spanable_range<R0>) {
  104|  2.76k|      constexpr size_t expected_size = s0.size_bytes();
  105|  2.76k|      (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|  2.76k|}

_ZN5Botan16secure_allocatorImE10deallocateEPmm:
   54|  51.2k|      void deallocate(T* p, std::size_t n) { deallocate_memory(p, n, sizeof(T)); }
_ZN5Botan16secure_allocatorImE8allocateEm:
   52|  51.2k|      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_:
  268|  24.6k|[[nodiscard]] constexpr decltype(auto) wrap_strong_type(ParamT&& t) {
  269|  24.6k|   if constexpr(std::same_as<std::remove_cvref_t<ParamT>, T>) {
  270|       |      // Noop, if the parameter type already is the desired return type.
  271|  24.6k|      return std::forward<ParamT>(t);
  272|       |   } else if constexpr(std::constructible_from<T, ParamT>) {
  273|       |      // Implicit conversion from the parameter type to the return type.
  274|       |      return T{std::forward<ParamT>(t)};
  275|       |   } else {
  276|       |      // Explicitly calling the wrapped type's constructor to support
  277|       |      // implicit conversions on types that mark their constructors as explicit.
  278|       |      static_assert(concepts::strong_type<T> && std::constructible_from<typename T::wrapped_type, ParamT>);
  279|       |      return T{typename T::wrapped_type{std::forward<ParamT>(t)}};
  280|       |   }
  281|  24.6k|}

_Z4fuzzNSt3__14spanIKhLm18446744073709551615EEE:
   10|  1.72k|void fuzz(std::span<const uint8_t> in) {
   11|  1.72k|   if(in.size() > 2 * 4096 / 8) {
  ------------------
  |  Branch (11:7): [True: 15, False: 1.71k]
  ------------------
   12|     15|      return;
   13|     15|   }
   14|       |
   15|       |   // Save on allocations by making these static
   16|  1.71k|   static Botan::BigInt x;
   17|  1.71k|   static Botan::BigInt y;
   18|  1.71k|   static Botan::BigInt q;
   19|  1.71k|   static Botan::BigInt r;
   20|  1.71k|   static Botan::BigInt ct_q;
   21|  1.71k|   static Botan::BigInt ct_r;
   22|  1.71k|   static Botan::BigInt z;
   23|       |
   24|  1.71k|   x = Botan::BigInt::from_bytes(in.subspan(0, in.size() / 2));
   25|  1.71k|   y = Botan::BigInt::from_bytes(in.subspan(in.size() / 2, in.size() - in.size() / 2));
   26|       |
   27|  1.71k|   if(y == 0) {
  ------------------
  |  Branch (27:7): [True: 2, False: 1.70k]
  ------------------
   28|      2|      return;
   29|      2|   }
   30|       |
   31|  1.70k|   Botan::vartime_divide(x, y, q, r);
   32|       |
   33|  1.70k|   FUZZER_ASSERT_TRUE(r < y);
  ------------------
  |  |   89|  1.70k|   do {                                                               \
  |  |   90|  1.70k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                   \
  |  |   91|  1.70k|      if(!(e)) {                                                      \
  |  |  ------------------
  |  |  |  Branch (91:10): [True: 0, False: 1.70k]
  |  |  ------------------
  |  |   92|      0|         FUZZER_WRITE_AND_CRASH("Expression " << #e << " was false"); \
  |  |  ------------------
  |  |  |  |   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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   93|      0|      }                                                               \
  |  |   94|  1.70k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (94:12): [Folded, False: 1.70k]
  |  |  ------------------
  ------------------
   34|       |
   35|  1.70k|   z = q * y + r;
   36|       |
   37|  1.70k|   FUZZER_ASSERT_EQUAL(z, x);
  ------------------
  |  |   79|  1.70k|   do {                                                                                      \
  |  |   80|  1.70k|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 1.70k]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|  1.70k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.70k]
  |  |  ------------------
  ------------------
   38|       |
   39|  1.70k|   Botan::ct_divide(x, y, ct_q, ct_r);
   40|       |
   41|  1.70k|   FUZZER_ASSERT_EQUAL(q, ct_q);
  ------------------
  |  |   79|  1.70k|   do {                                                                                      \
  |  |   80|  1.70k|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 1.70k]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|  1.70k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.70k]
  |  |  ------------------
  ------------------
   42|  1.70k|   FUZZER_ASSERT_EQUAL(r, ct_r);
  ------------------
  |  |   79|  1.70k|   do {                                                                                      \
  |  |   80|  1.70k|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 1.70k]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|  1.70k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.70k]
  |  |  ------------------
  ------------------
   43|       |
   44|       |   // Now divide by just low word of y
   45|       |
   46|  1.70k|   y = y.word_at(0);
   47|  1.70k|   if(y == 0) {
  ------------------
  |  Branch (47:7): [True: 24, False: 1.68k]
  ------------------
   48|     24|      return;
   49|     24|   }
   50|       |
   51|  1.68k|   Botan::vartime_divide(x, y, q, r);
   52|       |
   53|  1.68k|   FUZZER_ASSERT_TRUE(r < y);
  ------------------
  |  |   89|  1.68k|   do {                                                               \
  |  |   90|  1.68k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                   \
  |  |   91|  1.68k|      if(!(e)) {                                                      \
  |  |  ------------------
  |  |  |  Branch (91:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   92|      0|         FUZZER_WRITE_AND_CRASH("Expression " << #e << " was false"); \
  |  |  ------------------
  |  |  |  |   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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   93|      0|      }                                                               \
  |  |   94|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (94:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
   54|  1.68k|   z = q * y + r;
   55|  1.68k|   FUZZER_ASSERT_EQUAL(z, x);
  ------------------
  |  |   79|  1.68k|   do {                                                                                      \
  |  |   80|  1.68k|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
   56|       |
   57|  1.68k|   Botan::word rw = 0;
   58|  1.68k|   Botan::ct_divide_word(x, y.word_at(0), ct_q, rw);
   59|  1.68k|   FUZZER_ASSERT_EQUAL(ct_q, q);
  ------------------
  |  |   79|  1.68k|   do {                                                                                      \
  |  |   80|  1.68k|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
   60|  1.68k|   FUZZER_ASSERT_EQUAL(rw, r.word_at(0));
  ------------------
  |  |   79|  1.68k|   do {                                                                                      \
  |  |   80|  1.68k|      if((x) != (y)) {                                                                       \
  |  |  ------------------
  |  |  |  Branch (80:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   81|      0|         FUZZER_WRITE_AND_CRASH(#x << " = " << (x) << " != " << #y << " = " << (y) << "\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]
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|      }                                                                                      \
  |  |   83|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
   61|  1.68k|}

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|  1.73k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t in[], size_t len) {
   40|  1.73k|   if(len <= max_fuzzer_input_size) {
  ------------------
  |  Branch (40:7): [True: 1.72k, False: 10]
  ------------------
   41|  1.72k|      try {
   42|  1.72k|         fuzz(std::span<const uint8_t>(in, len));
   43|  1.72k|      } 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|  1.72k|   }
   51|  1.73k|   return 0;
   52|  1.73k|}

_ZN5Botan6BigIntpLERKS0_:
   16|    433|BigInt& BigInt::operator+=(const BigInt& y) {
   17|    433|   if(&y == this) {
  ------------------
  |  Branch (17:7): [True: 0, False: 433]
  ------------------
   18|      0|      return *this <<= 1;
   19|      0|   }
   20|    433|   return add(y._data(), y.sig_words(), y.sign());
   21|    433|}
_ZN5Botan6BigIntmIERKS0_:
   23|  15.0k|BigInt& BigInt::operator-=(const BigInt& y) {
   24|  15.0k|   if(&y == this) {
  ------------------
  |  Branch (24:7): [True: 0, False: 15.0k]
  ------------------
   25|      0|      this->clear();
   26|      0|      this->set_sign(Positive);
   27|      0|      return *this;
   28|      0|   }
   29|  15.0k|   return sub(y._data(), y.sig_words(), y.sign());
   30|  15.0k|}
_ZN5Botan6BigInt3addEPKmmNS0_4SignE:
   32|  15.4k|BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) {
   33|  15.4k|   const size_t x_sw = sig_words();
   34|       |
   35|  15.4k|   grow_to(std::max(x_sw, y_words) + 1);
   36|       |
   37|  15.4k|   if(sign() == y_sign) {
  ------------------
  |  Branch (37:7): [True: 0, False: 15.4k]
  ------------------
   38|      0|      const word carry = bigint_add2(mutable_data(), size() - 1, y, y_words);
   39|      0|      mutable_data()[size() - 1] += carry;
   40|  15.4k|   } else {
   41|  15.4k|      const int32_t relative_size = bigint_cmp(_data(), x_sw, y, y_words);
   42|       |
   43|  15.4k|      if(relative_size >= 0) {
  ------------------
  |  Branch (43:10): [True: 14.5k, False: 866]
  ------------------
   44|       |         // *this >= y
   45|  14.5k|         bigint_sub2(mutable_data(), x_sw, y, y_words);
   46|  14.5k|      } else {
   47|       |         // *this < y: compute *this = y - *this
   48|    866|         bigint_sub2_rev(mutable_data(), y, y_words);
   49|    866|      }
   50|       |
   51|  15.4k|      if(relative_size < 0) {
  ------------------
  |  Branch (51:10): [True: 866, False: 14.5k]
  ------------------
   52|    866|         set_sign(y_sign);
   53|  14.5k|      } else if(relative_size == 0) {
  ------------------
  |  Branch (53:17): [True: 497, False: 14.0k]
  ------------------
   54|    497|         set_sign(Positive);
   55|    497|      }
   56|  15.4k|   }
   57|       |
   58|  15.4k|   return (*this);
   59|  15.4k|}
_ZN5Botan6BigIntlSEm:
  269|  5.38k|BigInt& BigInt::operator<<=(size_t shift) {
  270|  5.38k|   if(shift >= 65536) {
  ------------------
  |  Branch (270:7): [True: 0, False: 5.38k]
  ------------------
  271|      0|      throw Invalid_Argument("BigInt left shift count too large");
  272|      0|   }
  273|       |
  274|  5.38k|   const size_t sw = sig_words();
  275|  5.38k|   const size_t new_size = sw + (shift + WordInfo<word>::bits - 1) / WordInfo<word>::bits;
  276|       |
  277|  5.38k|   m_data.grow_to(new_size);
  278|       |
  279|  5.38k|   bigint_shl1(m_data.mutable_data(), new_size, sw, shift);
  280|       |
  281|  5.38k|   return (*this);
  282|  5.38k|}
_ZN5Botan6BigIntrSEm:
  287|  19.5k|BigInt& BigInt::operator>>=(size_t shift) {
  288|  19.5k|   bigint_shr1(m_data.mutable_data(), m_data.size(), shift);
  289|       |
  290|  19.5k|   if(sig_words() == 0 && m_signedness == Negative) {
  ------------------
  |  Branch (290:7): [True: 553, False: 18.9k]
  |  Branch (290:27): [True: 0, False: 553]
  ------------------
  291|      0|      m_signedness = Positive;
  292|      0|   }
  293|       |
  294|  19.5k|   return (*this);
  295|  19.5k|}

_ZN5Botan6BigInt4add2ERKS0_PKmmNS0_4SignE:
   20|  3.39k|BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_size, BigInt::Sign y_sign) {
   21|  3.39k|   const size_t x_sw = x.sig_words();
   22|       |
   23|  3.39k|   BigInt z = BigInt::with_capacity(std::max(x_sw, y_size) + 1);
   24|       |
   25|  3.39k|   if(x.sign() == y_sign) {
  ------------------
  |  Branch (25:7): [True: 3.39k, False: 0]
  ------------------
   26|  3.39k|      const word carry = bigint_add3(z.mutable_data(), x._data(), x_sw, y, y_size);
   27|  3.39k|      z.mutable_data()[std::max(x_sw, y_size)] += carry;
   28|  3.39k|      z.set_sign(x.sign());
   29|  3.39k|   } else {
   30|      0|      const int32_t relative_size = bigint_cmp(x.data(), x_sw, y, y_size);
   31|       |
   32|      0|      if(relative_size < 0) {
  ------------------
  |  Branch (32:10): [True: 0, False: 0]
  ------------------
   33|       |         // x < y so z = abs(y - x)
   34|       |         // NOLINTNEXTLINE(*-suspicious-call-argument) intentionally swapping x and y here
   35|      0|         bigint_sub3(z.mutable_data(), y, y_size, x.data(), x_sw);
   36|      0|         z.set_sign(y_sign);
   37|      0|      } else if(relative_size == 0) {
  ------------------
  |  Branch (37:17): [True: 0, False: 0]
  ------------------
   38|       |         // Positive zero (nothing to do in this case)
   39|      0|      } else {
   40|       |         /*
   41|       |         * We know at this point that x >= y so if y_size is larger than
   42|       |         * x_sw, we are guaranteed they are just leading zeros which can
   43|       |         * be ignored
   44|       |         */
   45|      0|         y_size = std::min(x_sw, y_size);
   46|      0|         bigint_sub3(z.mutable_data(), x.data(), x_sw, y, y_size);
   47|      0|         z.set_sign(x.sign());
   48|      0|      }
   49|      0|   }
   50|       |
   51|  3.39k|   return z;
   52|  3.39k|}
_ZN5BotanmlERKNS_6BigIntES2_:
   57|  3.39k|BigInt operator*(const BigInt& x, const BigInt& y) {
   58|  3.39k|   const size_t x_sw = x.sig_words();
   59|  3.39k|   const size_t y_sw = y.sig_words();
   60|       |
   61|  3.39k|   BigInt z = BigInt::with_capacity(x.size() + y.size());
   62|       |
   63|  3.39k|   if(x_sw == 1 && y_sw > 0) {
  ------------------
  |  Branch (63:7): [True: 1.60k, False: 1.78k]
  |  Branch (63:20): [True: 1.60k, False: 0]
  ------------------
   64|  1.60k|      bigint_linmul3(z.mutable_data(), y._data(), y_sw, x.word_at(0));
   65|  1.78k|   } else if(y_sw == 1 && x_sw > 0) {
  ------------------
  |  Branch (65:14): [True: 1.35k, False: 433]
  |  Branch (65:27): [True: 823, False: 532]
  ------------------
   66|    823|      bigint_linmul3(z.mutable_data(), x._data(), x_sw, y.word_at(0));
   67|    965|   } else if(x_sw > 0 && y_sw > 0) {
  ------------------
  |  Branch (67:14): [True: 242, False: 723]
  |  Branch (67:26): [True: 242, False: 0]
  ------------------
   68|    242|      secure_vector<word> workspace(z.size());
   69|       |
   70|    242|      bigint_mul(z.mutable_data(),
   71|    242|                 z.size(),
   72|    242|                 x._data(),
   73|    242|                 x.size(),
   74|    242|                 x_sw,
   75|    242|                 y._data(),
   76|    242|                 y.size(),
   77|    242|                 y_sw,
   78|    242|                 workspace.data(),
   79|    242|                 workspace.size());
   80|    242|   }
   81|       |
   82|  3.39k|   z.cond_flip_sign(x_sw > 0 && y_sw > 0 && x.sign() != y.sign());
  ------------------
  |  Branch (82:21): [True: 2.67k, False: 723]
  |  Branch (82:33): [True: 2.67k, False: 0]
  |  Branch (82:45): [True: 0, False: 2.67k]
  ------------------
   83|       |
   84|  3.39k|   return z;
   85|  3.39k|}
_ZN5BotanmlERKNS_6BigIntEm:
   90|  15.0k|BigInt operator*(const BigInt& x, word y) {
   91|  15.0k|   const size_t x_sw = x.sig_words();
   92|       |
   93|  15.0k|   BigInt z = BigInt::with_capacity(x_sw + 1);
   94|       |
   95|  15.0k|   if(x_sw > 0 && y > 0) {
  ------------------
  |  Branch (95:7): [True: 15.0k, False: 0]
  |  Branch (95:19): [True: 15.0k, False: 0]
  ------------------
   96|  15.0k|      bigint_linmul3(z.mutable_data(), x._data(), x_sw, y);
   97|  15.0k|      z.set_sign(x.sign());
   98|  15.0k|   }
   99|       |
  100|  15.0k|   return z;
  101|  15.0k|}
_ZN5BotanlsERKNS_6BigIntEm:
  188|  3.39k|BigInt operator<<(const BigInt& x, size_t shift) {
  189|  3.39k|   if(shift >= 65536) {
  ------------------
  |  Branch (189:7): [True: 0, False: 3.39k]
  ------------------
  190|      0|      throw Invalid_Argument("BigInt left shift count too large");
  191|      0|   }
  192|       |
  193|  3.39k|   if(x.is_zero()) {
  ------------------
  |  Branch (193:7): [True: 0, False: 3.39k]
  ------------------
  194|      0|      return BigInt::zero();
  195|      0|   }
  196|       |
  197|  3.39k|   const size_t x_sw = x.sig_words();
  198|       |
  199|  3.39k|   const size_t new_size = x_sw + shift / WordInfo<word>::bits + 1;
  200|  3.39k|   BigInt y = BigInt::with_capacity(new_size);
  201|  3.39k|   bigint_shl2(y.mutable_data(), new_size, x._data(), x_sw, shift);
  202|  3.39k|   y.set_sign(x.sign());
  203|  3.39k|   return y;
  204|  3.39k|}

_ZN5Botan6BigIntC2Em:
   20|  1.70k|BigInt::BigInt(uint64_t n) {
   21|  1.70k|   if constexpr(sizeof(word) == 8) {
   22|  1.70k|      m_data.set_word_at(0, static_cast<word>(n));
   23|       |   } else {
   24|       |      m_data.set_word_at(1, static_cast<word>(n >> 32));
   25|       |      m_data.set_word_at(0, static_cast<word>(n));
   26|       |   }
   27|  1.70k|}
_ZN5Botan6BigInt13with_capacityEm:
   51|  32.0k|BigInt BigInt::with_capacity(size_t size) {
   52|  32.0k|   BigInt bn;
   53|  32.0k|   bn.grow_to(size);
   54|  32.0k|   return bn;
   55|  32.0k|}
_ZN5Botan6BigInt10from_bytesENSt3__14spanIKhLm18446744073709551615EEE:
   83|  3.42k|BigInt BigInt::from_bytes(std::span<const uint8_t> input) {
   84|  3.42k|   BigInt r;
   85|  3.42k|   r.assign_from_bytes(input);
   86|  3.42k|   return r;
   87|  3.42k|}
_ZNK5Botan6BigInt8cmp_wordEm:
  122|  3.42k|int32_t BigInt::cmp_word(word other) const {
  123|  3.42k|   if(signum() < 0) {
  ------------------
  |  Branch (123:7): [True: 0, False: 3.42k]
  ------------------
  124|      0|      return -1;  // other is positive ...
  125|      0|   }
  126|       |
  127|  3.42k|   const size_t sw = this->sig_words();
  128|  3.42k|   if(sw > 1) {
  ------------------
  |  Branch (128:7): [True: 882, False: 2.53k]
  ------------------
  129|    882|      return 1;  // must be larger since other is just one word ...
  130|    882|   }
  131|       |
  132|  2.53k|   return bigint_cmp(this->_data(), sw, &other, 1);
  133|  3.42k|}
_ZNK5Botan6BigInt8is_equalERKS0_:
  156|  8.49k|bool BigInt::is_equal(const BigInt& other) const {
  157|  8.49k|   if(this->sign() != other.sign()) {
  ------------------
  |  Branch (157:7): [True: 0, False: 8.49k]
  ------------------
  158|      0|      return false;
  159|      0|   }
  160|       |
  161|  8.49k|   return bigint_ct_is_eq(this->_data(), this->size(), other._data(), other.size()).as_bool();
  162|  8.49k|}
_ZNK5Botan6BigInt12is_less_thanERKS0_:
  164|  3.39k|bool BigInt::is_less_than(const BigInt& other) const {
  165|  3.39k|   if(this->signum() < 0 && other.signum() >= 0) {
  ------------------
  |  Branch (165:7): [True: 0, False: 3.39k]
  |  Branch (165:29): [True: 0, False: 0]
  ------------------
  166|      0|      return true;
  167|      0|   }
  168|       |
  169|  3.39k|   if(this->signum() >= 0 && other.signum() < 0) {
  ------------------
  |  Branch (169:7): [True: 3.39k, False: 0]
  |  Branch (169:30): [True: 0, False: 3.39k]
  ------------------
  170|      0|      return false;
  171|      0|   }
  172|       |
  173|  3.39k|   if(other.signum() < 0 && this->signum() < 0) {
  ------------------
  |  Branch (173:7): [True: 0, False: 3.39k]
  |  Branch (173:29): [True: 0, False: 0]
  ------------------
  174|      0|      return bigint_ct_is_lt(other._data(), other.size(), this->_data(), this->size()).as_bool();
  175|      0|   }
  176|       |
  177|  3.39k|   return bigint_ct_is_lt(this->_data(), this->size(), other._data(), other.size()).as_bool();
  178|  3.39k|}
_ZN5Botan6BigInt4Data11set_to_zeroEv:
  191|  3.42k|void BigInt::Data::set_to_zero() {
  192|  3.42k|   m_reg.resize(m_reg.capacity());
  193|  3.42k|   clear_mem(m_reg.data(), m_reg.size());
  194|  3.42k|   m_sig_words = 0;
  195|  3.42k|}
_ZNK5Botan6BigInt4Data14calc_sig_wordsEv:
  215|  72.4k|size_t BigInt::Data::calc_sig_words() const {
  216|  72.4k|   const size_t sz = m_reg.size();
  217|  72.4k|   size_t sig = sz;
  218|       |
  219|  72.4k|   word sub = 1;
  220|       |
  221|  2.10M|   for(size_t i = 0; i != sz; ++i) {
  ------------------
  |  Branch (221:22): [True: 2.03M, False: 72.4k]
  ------------------
  222|  2.03M|      const word w = m_reg[sz - i - 1];
  223|  2.03M|      sub &= ct_is_zero(w);
  224|  2.03M|      sig -= sub;
  225|  2.03M|   }
  226|       |
  227|       |   /*
  228|       |   * This depends on the data so is poisoned, but unpoison it here as
  229|       |   * later conditionals are made on the size.
  230|       |   */
  231|  72.4k|   CT::unpoison(sig);
  232|       |
  233|  72.4k|   return sig;
  234|  72.4k|}
_ZNK5Botan6BigInt13top_bits_freeEv:
  298|  6.70k|size_t BigInt::top_bits_free() const {
  299|  6.70k|   const size_t words = sig_words();
  300|       |
  301|  6.70k|   const word top_word = word_at(words - 1);
  302|  6.70k|   const size_t bits_used = high_bit(CT::value_barrier(top_word));
  303|  6.70k|   CT::unpoison(bits_used);
  304|  6.70k|   return WordInfo<word>::bits - bits_used;
  305|  6.70k|}
_ZNK5Botan6BigInt4bitsEv:
  307|  3.39k|size_t BigInt::bits() const {
  308|  3.39k|   const size_t words = sig_words();
  309|       |
  310|  3.39k|   if(words == 0) {
  ------------------
  |  Branch (310:7): [True: 84, False: 3.31k]
  ------------------
  311|     84|      return 0;
  312|     84|   }
  313|       |
  314|  3.31k|   const size_t full_words = (words - 1) * WordInfo<word>::bits;
  315|  3.31k|   const size_t top_bits = WordInfo<word>::bits - top_bits_free();
  316|       |
  317|  3.31k|   return full_words + top_bits;
  318|  3.39k|}
_ZN5Botan6BigInt12reduce_belowERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  329|  3.39k|size_t BigInt::reduce_below(const BigInt& p, secure_vector<word>& ws) {
  330|  3.39k|   if(p.signum() < 0 || this->signum() < 0) {
  ------------------
  |  Branch (330:7): [True: 0, False: 3.39k]
  |  Branch (330:25): [True: 0, False: 3.39k]
  ------------------
  331|      0|      throw Invalid_Argument("BigInt::reduce_below both values must be positive");
  332|      0|   }
  333|       |
  334|  3.39k|   const size_t p_words = p.sig_words();
  335|       |
  336|  3.39k|   if(size() < p_words + 1) {
  ------------------
  |  Branch (336:7): [True: 143, False: 3.25k]
  ------------------
  337|    143|      grow_to(p_words + 1);
  338|    143|   }
  339|       |
  340|  3.39k|   if(ws.size() < p_words + 1) {
  ------------------
  |  Branch (340:7): [True: 3.39k, False: 0]
  ------------------
  341|  3.39k|      ws.resize(p_words + 1);
  342|  3.39k|   }
  343|       |
  344|  3.39k|   clear_mem(ws.data(), ws.size());
  345|       |
  346|  3.39k|   size_t reductions = 0;
  347|       |
  348|  3.55k|   for(;;) {
  349|  3.55k|      const word borrow = bigint_sub3(ws.data(), _data(), p_words + 1, p._data(), p_words);
  350|  3.55k|      if(borrow > 0) {
  ------------------
  |  Branch (350:10): [True: 3.39k, False: 160]
  ------------------
  351|  3.39k|         break;
  352|  3.39k|      }
  353|       |
  354|    160|      ++reductions;
  355|    160|      swap_reg(ws);
  356|    160|   }
  357|       |
  358|  3.39k|   return reductions;
  359|  3.39k|}
_ZN5Botan6BigInt17assign_from_bytesENSt3__14spanIKhLm18446744073709551615EEE:
  425|  3.42k|void BigInt::assign_from_bytes(std::span<const uint8_t> bytes) {
  426|  3.42k|   clear();
  427|       |
  428|  3.42k|   const size_t length = bytes.size();
  429|  3.42k|   const size_t full_words = length / sizeof(word);
  430|  3.42k|   const size_t extra_bytes = length % sizeof(word);
  431|       |
  432|  3.42k|   secure_vector<word> reg((round_up(full_words + (extra_bytes > 0 ? 1 : 0), 8)));
  ------------------
  |  Branch (432:52): [True: 2.76k, False: 661]
  ------------------
  433|       |
  434|  25.2k|   for(size_t i = 0; i != full_words; ++i) {
  ------------------
  |  Branch (434:22): [True: 21.8k, False: 3.42k]
  ------------------
  435|  21.8k|      reg[i] = load_be<word>(bytes.last<sizeof(word)>());
  436|  21.8k|      bytes = bytes.first(bytes.size() - sizeof(word));
  437|  21.8k|   }
  438|       |
  439|  3.42k|   if(!bytes.empty()) {
  ------------------
  |  Branch (439:7): [True: 2.76k, False: 661]
  ------------------
  440|  2.76k|      BOTAN_ASSERT_NOMSG(extra_bytes == bytes.size());
  ------------------
  |  |   77|  2.76k|   do {                                                                     \
  |  |   78|  2.76k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  2.76k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 2.76k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  2.76k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 2.76k]
  |  |  ------------------
  ------------------
  441|  2.76k|      std::array<uint8_t, sizeof(word)> last_partial_word = {0};
  442|  2.76k|      copy_mem(std::span{last_partial_word}.last(extra_bytes), bytes);
  443|  2.76k|      reg[full_words] = load_be<word>(last_partial_word);
  444|  2.76k|   }
  445|       |
  446|  3.42k|   m_data.swap(reg);
  447|  3.42k|}
_ZN5Botan6BigInt14cond_flip_signEb:
  521|  8.49k|void BigInt::cond_flip_sign(bool predicate) {
  522|       |   // This code is assuming Negative == 0, Positive == 1
  523|       |
  524|  8.49k|   const auto mask = CT::Mask<uint8_t>::expand_bool(predicate);
  525|       |
  526|  8.49k|   const uint8_t current_sign = static_cast<uint8_t>(sign());
  527|       |
  528|  8.49k|   const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign);
  529|       |
  530|  8.49k|   set_sign(static_cast<Sign>(new_sign));
  531|  8.49k|}
_ZNK5Botan6BigInt20_const_time_unpoisonEv:
  559|  47.3k|void BigInt::_const_time_unpoison() const {
  560|  47.3k|   CT::unpoison(m_data.const_data(), m_data.size());
  561|  47.3k|}

_ZN5Botan9ct_divideERKNS_6BigIntES2_RS0_S3_:
   55|  1.70k|void ct_divide(const BigInt& x, const BigInt& y, BigInt& q_out, BigInt& r_out) {
   56|  1.70k|   if(y.is_zero()) {
  ------------------
  |  Branch (56:7): [True: 0, False: 1.70k]
  ------------------
   57|      0|      throw Invalid_Argument("ct_divide: cannot divide by zero");
   58|      0|   }
   59|       |
   60|  1.70k|   const size_t x_words = x.sig_words();
   61|  1.70k|   const size_t y_words = y.sig_words();
   62|       |
   63|  1.70k|   const size_t x_bits = x.bits();
   64|       |
   65|  1.70k|   const size_t r_words = y_words + 1;
   66|       |
   67|  1.70k|   BigInt q = BigInt::with_capacity(x_words);
   68|  1.70k|   BigInt r = BigInt::with_capacity(r_words);
   69|  1.70k|   BigInt t = BigInt::with_capacity(r_words);  // a temporary
   70|       |
   71|   691k|   for(size_t i = 0; i != x_bits; ++i) {
  ------------------
  |  Branch (71:22): [True: 690k, False: 1.70k]
  ------------------
   72|   690k|      const size_t b = x_bits - 1 - i;
   73|   690k|      const bool x_b = x.get_bit(b);
   74|       |
   75|   690k|      bigint_shl1(r.mutable_data(), r_words, r_words, 1);
   76|   690k|      r.conditionally_set_bit(0, x_b);
   77|       |
   78|   690k|      const bool r_gte_y = bigint_sub3(t.mutable_data(), r._data(), r_words, y._data(), y_words) == 0;
   79|       |
   80|   690k|      q.conditionally_set_bit(b, r_gte_y);
   81|   690k|      bigint_cnd_swap(static_cast<word>(r_gte_y), r.mutable_data(), t.mutable_data(), r_words);
   82|   690k|   }
   83|       |
   84|  1.70k|   sign_fixup(x, y, q, r);
   85|  1.70k|   r_out = r;
   86|  1.70k|   q_out = q;
   87|  1.70k|}
_ZN5Botan14ct_divide_wordERKNS_6BigIntEmRS0_Rm:
  129|  1.68k|void ct_divide_word(const BigInt& x, word y, BigInt& q_out, word& r_out) {
  130|  1.68k|   if(y == 0) {
  ------------------
  |  Branch (130:7): [True: 0, False: 1.68k]
  ------------------
  131|      0|      throw Invalid_Argument("ct_divide_word: cannot divide by zero");
  132|      0|   }
  133|       |
  134|  1.68k|   const size_t x_words = x.sig_words();
  135|  1.68k|   const size_t x_bits = x.bits();
  136|       |
  137|  1.68k|   BigInt q = BigInt::with_capacity(x_words);
  138|  1.68k|   word r = 0;
  139|       |
  140|   670k|   for(size_t i = 0; i != x_bits; ++i) {
  ------------------
  |  Branch (140:22): [True: 668k, False: 1.68k]
  ------------------
  141|   668k|      const size_t b = x_bits - 1 - i;
  142|   668k|      const bool x_b = x.get_bit(b);
  143|       |
  144|   668k|      const auto r_carry = CT::Mask<word>::expand_top_bit(r);
  145|       |
  146|   668k|      r <<= 1;
  147|   668k|      r += static_cast<word>(x_b);
  148|       |
  149|   668k|      const auto r_gte_y = CT::Mask<word>::is_gte(r, y) | r_carry;
  150|   668k|      q.conditionally_set_bit(b, r_gte_y.as_bool());
  151|   668k|      r = r_gte_y.select(r - y, r);
  152|   668k|   }
  153|       |
  154|  1.68k|   if(x.signum() < 0) {
  ------------------
  |  Branch (154:7): [True: 0, False: 1.68k]
  ------------------
  155|      0|      q.flip_sign();
  156|      0|      if(r != 0) {
  ------------------
  |  Branch (156:10): [True: 0, False: 0]
  ------------------
  157|      0|         --q;
  158|      0|         r = y - r;
  159|      0|      }
  160|      0|   }
  161|       |
  162|  1.68k|   r_out = r;
  163|  1.68k|   q_out = q;
  164|  1.68k|}
_ZN5Botan14vartime_divideERKNS_6BigIntES2_RS0_S3_:
  332|  3.39k|void vartime_divide(const BigInt& x, const BigInt& y_arg, BigInt& q_out, BigInt& r_out) {
  333|  3.39k|   constexpr size_t WB = WordInfo<word>::bits;
  334|       |
  335|  3.39k|   if(y_arg.is_zero()) {
  ------------------
  |  Branch (335:7): [True: 0, False: 3.39k]
  ------------------
  336|      0|      throw Invalid_Argument("vartime_divide: cannot divide by zero");
  337|      0|   }
  338|       |
  339|  3.39k|   const size_t y_words = y_arg.sig_words();
  340|       |
  341|  3.39k|   BOTAN_ASSERT_NOMSG(y_words > 0);
  ------------------
  |  |   77|  3.39k|   do {                                                                     \
  |  |   78|  3.39k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  3.39k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 3.39k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  3.39k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 3.39k]
  |  |  ------------------
  ------------------
  342|       |
  343|  3.39k|   BigInt y = y_arg;
  344|       |
  345|  3.39k|   BigInt r = x;
  346|  3.39k|   BigInt q = BigInt::zero();
  347|  3.39k|   secure_vector<word> ws;
  348|       |
  349|  3.39k|   r.set_sign(BigInt::Positive);
  350|  3.39k|   y.set_sign(BigInt::Positive);
  351|       |
  352|       |   // Calculate shifts needed to normalize y with high bit set
  353|  3.39k|   const size_t shifts = y.top_bits_free();
  354|       |
  355|  3.39k|   if(shifts > 0) {
  ------------------
  |  Branch (355:7): [True: 2.69k, False: 700]
  ------------------
  356|  2.69k|      y <<= shifts;
  357|  2.69k|      r <<= shifts;
  358|  2.69k|   }
  359|       |
  360|       |   // we know y has not changed size, since we only shifted up to set high bit
  361|  3.39k|   const size_t t = y_words - 1;
  362|  3.39k|   const size_t n = std::max(y_words, r.sig_words()) - 1;  // r may have changed size however
  363|       |
  364|  3.39k|   BOTAN_ASSERT_NOMSG(n >= t);
  ------------------
  |  |   77|  3.39k|   do {                                                                     \
  |  |   78|  3.39k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  3.39k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 3.39k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  3.39k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 3.39k]
  |  |  ------------------
  ------------------
  365|       |
  366|  3.39k|   q.grow_to(n - t + 1);
  367|       |
  368|  3.39k|   word* q_words = q.mutable_data();
  369|       |
  370|  3.39k|   BigInt shifted_y = y << (WB * (n - t));
  371|       |
  372|       |   // Set q_{n-t} to number of times r > shifted_y
  373|  3.39k|   q_words[n - t] = r.reduce_below(shifted_y, ws);
  374|       |
  375|  3.39k|   const word y_t0 = y.word_at(t);
  376|  3.39k|   const word y_t1 = y.word_at(t - 1);
  377|  3.39k|   BOTAN_DEBUG_ASSERT((y_t0 >> (WB - 1)) == 1);
  ------------------
  |  |  130|  3.39k|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  131|  3.39k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (131:15): [Folded, False: 3.39k]
  |  |  ------------------
  ------------------
  378|       |
  379|  3.39k|   const divide_precomp div_y_t0(y_t0);
  380|       |
  381|  20.2k|   for(size_t i = n; i != t; --i) {
  ------------------
  |  Branch (381:22): [True: 16.8k, False: 3.39k]
  ------------------
  382|  16.8k|      const word x_i0 = r.word_at(i);
  383|  16.8k|      const word x_i1 = r.word_at(i - 1);
  384|  16.8k|      const word x_i2 = r.word_at(i - 2);
  385|       |
  386|  16.8k|      word qit = (x_i0 == y_t0) ? WordInfo<word>::max : div_y_t0.vartime_div_2to1(x_i0, x_i1);
  ------------------
  |  Branch (386:18): [True: 402, False: 16.4k]
  ------------------
  387|       |
  388|       |      // Per HAC 14.23, this operation is required at most twice
  389|  18.3k|      for(size_t j = 0; j != 2; ++j) {
  ------------------
  |  Branch (389:25): [True: 18.1k, False: 157]
  ------------------
  390|  18.1k|         if(division_check_vartime(qit, y_t0, y_t1, x_i0, x_i1, x_i2)) {
  ------------------
  |  Branch (390:13): [True: 1.49k, False: 16.6k]
  ------------------
  391|  1.49k|            BOTAN_ASSERT_NOMSG(qit > 0);
  ------------------
  |  |   77|  1.49k|   do {                                                                     \
  |  |   78|  1.49k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|  1.49k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 1.49k]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|  1.49k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 1.49k]
  |  |  ------------------
  ------------------
  392|  1.49k|            qit--;
  393|  16.6k|         } else {
  394|  16.6k|            break;
  395|  16.6k|         }
  396|  18.1k|      }
  397|       |
  398|  16.8k|      shifted_y >>= WB;
  399|       |      // Now shifted_y == y << (WB * (i-t-1))
  400|       |
  401|  16.8k|      if(qit != 0) {
  ------------------
  |  Branch (401:10): [True: 15.0k, False: 1.81k]
  ------------------
  402|  15.0k|         r -= qit * shifted_y;
  403|  15.0k|         if(r.signum() < 0) {
  ------------------
  |  Branch (403:13): [True: 433, False: 14.5k]
  ------------------
  404|    433|            BOTAN_ASSERT_NOMSG(qit > 0);
  ------------------
  |  |   77|    433|   do {                                                                     \
  |  |   78|    433|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|    433|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 433]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|    433|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 433]
  |  |  ------------------
  ------------------
  405|    433|            qit--;
  406|    433|            r += shifted_y;
  407|    433|            BOTAN_ASSERT_NOMSG(r.signum() >= 0);
  ------------------
  |  |   77|    433|   do {                                                                     \
  |  |   78|    433|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   79|    433|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 0, False: 433]
  |  |  ------------------
  |  |   80|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   81|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   82|      0|      }                                                                     \
  |  |   83|    433|   } while(0)
  |  |  ------------------
  |  |  |  Branch (83:12): [Folded, False: 433]
  |  |  ------------------
  ------------------
  408|    433|         }
  409|  15.0k|      }
  410|       |
  411|  16.8k|      q_words[i - t - 1] = qit;
  412|  16.8k|   }
  413|       |
  414|  3.39k|   if(shifts > 0) {
  ------------------
  |  Branch (414:7): [True: 2.69k, False: 700]
  ------------------
  415|  2.69k|      r >>= shifts;
  416|  2.69k|   }
  417|       |
  418|  3.39k|   sign_fixup(x, y_arg, q, r);
  419|       |
  420|  3.39k|   r_out = r;
  421|  3.39k|   q_out = q;
  422|  3.39k|}
divide.cpp:_ZN5Botan12_GLOBAL__N_110sign_fixupERKNS_6BigIntES3_RS1_S4_:
   21|  5.10k|void sign_fixup(const BigInt& x, const BigInt& y, BigInt& q, BigInt& r) {
   22|  5.10k|   q.cond_flip_sign(x.sign() != y.sign());
   23|       |
   24|  5.10k|   if(x.signum() < 0 && r.signum() != 0) {
  ------------------
  |  Branch (24:7): [True: 0, False: 5.10k]
  |  Branch (24:25): [True: 0, False: 0]
  ------------------
   25|      0|      if(y.signum() > 0) {
  ------------------
  |  Branch (25:10): [True: 0, False: 0]
  ------------------
   26|      0|         q -= 1;
   27|      0|      } else {
   28|      0|         q += 1;
   29|      0|      }
   30|      0|      r = y.abs() - r;
   31|      0|   }
   32|  5.10k|}
divide.cpp:_ZN5Botan12_GLOBAL__N_122division_check_vartimeEmmmmmm:
   34|  18.1k|inline bool division_check_vartime(word q, word y2, word y1, word x3, word x2, word x1) {
   35|       |   /*
   36|       |   Compute (y3,y2,y1) = (y2,y1) * q
   37|       |   and return true if (y3,y2,y1) > (x3,x2,x1)
   38|       |   */
   39|       |
   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|   if(x3 != y3) {
  ------------------
  |  Branch (44:7): [True: 8.96k, False: 9.19k]
  ------------------
   45|  8.96k|      return (y3 > x3);
   46|  8.96k|   }
   47|  9.19k|   if(x2 != y2) {
  ------------------
  |  Branch (47:7): [True: 6.21k, False: 2.98k]
  ------------------
   48|  6.21k|      return (y2 > x2);
   49|  6.21k|   }
   50|  2.98k|   return (y1 > x1);
   51|  9.19k|}

_ZN5Botan17bigint_comba_mul4EPmPKmS2_:
   43|     31|void bigint_comba_mul4(word z[8], const word x[4], const word y[4]) {
   44|     31|   word3<word> accum;
   45|       |
   46|     31|   accum.mul(x[0], y[0]);
   47|     31|   z[0] = accum.extract();
   48|     31|   accum.mul(x[0], y[1]);
   49|     31|   accum.mul(x[1], y[0]);
   50|     31|   z[1] = accum.extract();
   51|     31|   accum.mul(x[0], y[2]);
   52|     31|   accum.mul(x[1], y[1]);
   53|     31|   accum.mul(x[2], y[0]);
   54|     31|   z[2] = accum.extract();
   55|     31|   accum.mul(x[0], y[3]);
   56|     31|   accum.mul(x[1], y[2]);
   57|     31|   accum.mul(x[2], y[1]);
   58|     31|   accum.mul(x[3], y[0]);
   59|     31|   z[3] = accum.extract();
   60|     31|   accum.mul(x[1], y[3]);
   61|     31|   accum.mul(x[2], y[2]);
   62|     31|   accum.mul(x[3], y[1]);
   63|     31|   z[4] = accum.extract();
   64|     31|   accum.mul(x[2], y[3]);
   65|     31|   accum.mul(x[3], y[2]);
   66|     31|   z[5] = accum.extract();
   67|     31|   accum.mul(x[3], y[3]);
   68|     31|   z[6] = accum.extract();
   69|     31|   z[7] = accum.extract();
   70|     31|}
_ZN5Botan17bigint_comba_mul6EPmPKmS2_:
  116|     20|void bigint_comba_mul6(word z[12], const word x[6], const word y[6]) {
  117|     20|   word3<word> accum;
  118|       |
  119|     20|   accum.mul(x[0], y[0]);
  120|     20|   z[0] = accum.extract();
  121|     20|   accum.mul(x[0], y[1]);
  122|     20|   accum.mul(x[1], y[0]);
  123|     20|   z[1] = accum.extract();
  124|     20|   accum.mul(x[0], y[2]);
  125|     20|   accum.mul(x[1], y[1]);
  126|     20|   accum.mul(x[2], y[0]);
  127|     20|   z[2] = accum.extract();
  128|     20|   accum.mul(x[0], y[3]);
  129|     20|   accum.mul(x[1], y[2]);
  130|     20|   accum.mul(x[2], y[1]);
  131|     20|   accum.mul(x[3], y[0]);
  132|     20|   z[3] = accum.extract();
  133|     20|   accum.mul(x[0], y[4]);
  134|     20|   accum.mul(x[1], y[3]);
  135|     20|   accum.mul(x[2], y[2]);
  136|     20|   accum.mul(x[3], y[1]);
  137|     20|   accum.mul(x[4], y[0]);
  138|     20|   z[4] = accum.extract();
  139|     20|   accum.mul(x[0], y[5]);
  140|     20|   accum.mul(x[1], y[4]);
  141|     20|   accum.mul(x[2], y[3]);
  142|     20|   accum.mul(x[3], y[2]);
  143|     20|   accum.mul(x[4], y[1]);
  144|     20|   accum.mul(x[5], y[0]);
  145|     20|   z[5] = accum.extract();
  146|     20|   accum.mul(x[1], y[5]);
  147|     20|   accum.mul(x[2], y[4]);
  148|     20|   accum.mul(x[3], y[3]);
  149|     20|   accum.mul(x[4], y[2]);
  150|     20|   accum.mul(x[5], y[1]);
  151|     20|   z[6] = accum.extract();
  152|     20|   accum.mul(x[2], y[5]);
  153|     20|   accum.mul(x[3], y[4]);
  154|     20|   accum.mul(x[4], y[3]);
  155|     20|   accum.mul(x[5], y[2]);
  156|     20|   z[7] = accum.extract();
  157|     20|   accum.mul(x[3], y[5]);
  158|     20|   accum.mul(x[4], y[4]);
  159|     20|   accum.mul(x[5], y[3]);
  160|     20|   z[8] = accum.extract();
  161|     20|   accum.mul(x[4], y[5]);
  162|     20|   accum.mul(x[5], y[4]);
  163|     20|   z[9] = accum.extract();
  164|     20|   accum.mul(x[5], y[5]);
  165|     20|   z[10] = accum.extract();
  166|     20|   z[11] = accum.extract();
  167|     20|}
_ZN5Botan17bigint_comba_mul8EPmPKmS2_:
  353|     20|void bigint_comba_mul8(word z[16], const word x[8], const word y[8]) {
  354|     20|   word3<word> accum;
  355|       |
  356|     20|   accum.mul(x[0], y[0]);
  357|     20|   z[0] = accum.extract();
  358|     20|   accum.mul(x[0], y[1]);
  359|     20|   accum.mul(x[1], y[0]);
  360|     20|   z[1] = accum.extract();
  361|     20|   accum.mul(x[0], y[2]);
  362|     20|   accum.mul(x[1], y[1]);
  363|     20|   accum.mul(x[2], y[0]);
  364|     20|   z[2] = accum.extract();
  365|     20|   accum.mul(x[0], y[3]);
  366|     20|   accum.mul(x[1], y[2]);
  367|     20|   accum.mul(x[2], y[1]);
  368|     20|   accum.mul(x[3], y[0]);
  369|     20|   z[3] = accum.extract();
  370|     20|   accum.mul(x[0], y[4]);
  371|     20|   accum.mul(x[1], y[3]);
  372|     20|   accum.mul(x[2], y[2]);
  373|     20|   accum.mul(x[3], y[1]);
  374|     20|   accum.mul(x[4], y[0]);
  375|     20|   z[4] = accum.extract();
  376|     20|   accum.mul(x[0], y[5]);
  377|     20|   accum.mul(x[1], y[4]);
  378|     20|   accum.mul(x[2], y[3]);
  379|     20|   accum.mul(x[3], y[2]);
  380|     20|   accum.mul(x[4], y[1]);
  381|     20|   accum.mul(x[5], y[0]);
  382|     20|   z[5] = accum.extract();
  383|     20|   accum.mul(x[0], y[6]);
  384|     20|   accum.mul(x[1], y[5]);
  385|     20|   accum.mul(x[2], y[4]);
  386|     20|   accum.mul(x[3], y[3]);
  387|     20|   accum.mul(x[4], y[2]);
  388|     20|   accum.mul(x[5], y[1]);
  389|     20|   accum.mul(x[6], y[0]);
  390|     20|   z[6] = accum.extract();
  391|     20|   accum.mul(x[0], y[7]);
  392|     20|   accum.mul(x[1], y[6]);
  393|     20|   accum.mul(x[2], y[5]);
  394|     20|   accum.mul(x[3], y[4]);
  395|     20|   accum.mul(x[4], y[3]);
  396|     20|   accum.mul(x[5], y[2]);
  397|     20|   accum.mul(x[6], y[1]);
  398|     20|   accum.mul(x[7], y[0]);
  399|     20|   z[7] = accum.extract();
  400|     20|   accum.mul(x[1], y[7]);
  401|     20|   accum.mul(x[2], y[6]);
  402|     20|   accum.mul(x[3], y[5]);
  403|     20|   accum.mul(x[4], y[4]);
  404|     20|   accum.mul(x[5], y[3]);
  405|     20|   accum.mul(x[6], y[2]);
  406|     20|   accum.mul(x[7], y[1]);
  407|     20|   z[8] = accum.extract();
  408|     20|   accum.mul(x[2], y[7]);
  409|     20|   accum.mul(x[3], y[6]);
  410|     20|   accum.mul(x[4], y[5]);
  411|     20|   accum.mul(x[5], y[4]);
  412|     20|   accum.mul(x[6], y[3]);
  413|     20|   accum.mul(x[7], y[2]);
  414|     20|   z[9] = accum.extract();
  415|     20|   accum.mul(x[3], y[7]);
  416|     20|   accum.mul(x[4], y[6]);
  417|     20|   accum.mul(x[5], y[5]);
  418|     20|   accum.mul(x[6], y[4]);
  419|     20|   accum.mul(x[7], y[3]);
  420|     20|   z[10] = accum.extract();
  421|     20|   accum.mul(x[4], y[7]);
  422|     20|   accum.mul(x[5], y[6]);
  423|     20|   accum.mul(x[6], y[5]);
  424|     20|   accum.mul(x[7], y[4]);
  425|     20|   z[11] = accum.extract();
  426|     20|   accum.mul(x[5], y[7]);
  427|     20|   accum.mul(x[6], y[6]);
  428|     20|   accum.mul(x[7], y[5]);
  429|     20|   z[12] = accum.extract();
  430|     20|   accum.mul(x[6], y[7]);
  431|     20|   accum.mul(x[7], y[6]);
  432|     20|   z[13] = accum.extract();
  433|     20|   accum.mul(x[7], y[7]);
  434|     20|   z[14] = accum.extract();
  435|     20|   z[15] = accum.extract();
  436|     20|}
_ZN5Botan17bigint_comba_mul9EPmPKmS2_:
  512|      9|void bigint_comba_mul9(word z[18], const word x[9], const word y[9]) {
  513|      9|   word3<word> accum;
  514|       |
  515|      9|   accum.mul(x[0], y[0]);
  516|      9|   z[0] = accum.extract();
  517|      9|   accum.mul(x[0], y[1]);
  518|      9|   accum.mul(x[1], y[0]);
  519|      9|   z[1] = accum.extract();
  520|      9|   accum.mul(x[0], y[2]);
  521|      9|   accum.mul(x[1], y[1]);
  522|      9|   accum.mul(x[2], y[0]);
  523|      9|   z[2] = accum.extract();
  524|      9|   accum.mul(x[0], y[3]);
  525|      9|   accum.mul(x[1], y[2]);
  526|      9|   accum.mul(x[2], y[1]);
  527|      9|   accum.mul(x[3], y[0]);
  528|      9|   z[3] = accum.extract();
  529|      9|   accum.mul(x[0], y[4]);
  530|      9|   accum.mul(x[1], y[3]);
  531|      9|   accum.mul(x[2], y[2]);
  532|      9|   accum.mul(x[3], y[1]);
  533|      9|   accum.mul(x[4], y[0]);
  534|      9|   z[4] = accum.extract();
  535|      9|   accum.mul(x[0], y[5]);
  536|      9|   accum.mul(x[1], y[4]);
  537|      9|   accum.mul(x[2], y[3]);
  538|      9|   accum.mul(x[3], y[2]);
  539|      9|   accum.mul(x[4], y[1]);
  540|      9|   accum.mul(x[5], y[0]);
  541|      9|   z[5] = accum.extract();
  542|      9|   accum.mul(x[0], y[6]);
  543|      9|   accum.mul(x[1], y[5]);
  544|      9|   accum.mul(x[2], y[4]);
  545|      9|   accum.mul(x[3], y[3]);
  546|      9|   accum.mul(x[4], y[2]);
  547|      9|   accum.mul(x[5], y[1]);
  548|      9|   accum.mul(x[6], y[0]);
  549|      9|   z[6] = accum.extract();
  550|      9|   accum.mul(x[0], y[7]);
  551|      9|   accum.mul(x[1], y[6]);
  552|      9|   accum.mul(x[2], y[5]);
  553|      9|   accum.mul(x[3], y[4]);
  554|      9|   accum.mul(x[4], y[3]);
  555|      9|   accum.mul(x[5], y[2]);
  556|      9|   accum.mul(x[6], y[1]);
  557|      9|   accum.mul(x[7], y[0]);
  558|      9|   z[7] = accum.extract();
  559|      9|   accum.mul(x[0], y[8]);
  560|      9|   accum.mul(x[1], y[7]);
  561|      9|   accum.mul(x[2], y[6]);
  562|      9|   accum.mul(x[3], y[5]);
  563|      9|   accum.mul(x[4], y[4]);
  564|      9|   accum.mul(x[5], y[3]);
  565|      9|   accum.mul(x[6], y[2]);
  566|      9|   accum.mul(x[7], y[1]);
  567|      9|   accum.mul(x[8], y[0]);
  568|      9|   z[8] = accum.extract();
  569|      9|   accum.mul(x[1], y[8]);
  570|      9|   accum.mul(x[2], y[7]);
  571|      9|   accum.mul(x[3], y[6]);
  572|      9|   accum.mul(x[4], y[5]);
  573|      9|   accum.mul(x[5], y[4]);
  574|      9|   accum.mul(x[6], y[3]);
  575|      9|   accum.mul(x[7], y[2]);
  576|      9|   accum.mul(x[8], y[1]);
  577|      9|   z[9] = accum.extract();
  578|      9|   accum.mul(x[2], y[8]);
  579|      9|   accum.mul(x[3], y[7]);
  580|      9|   accum.mul(x[4], y[6]);
  581|      9|   accum.mul(x[5], y[5]);
  582|      9|   accum.mul(x[6], y[4]);
  583|      9|   accum.mul(x[7], y[3]);
  584|      9|   accum.mul(x[8], y[2]);
  585|      9|   z[10] = accum.extract();
  586|      9|   accum.mul(x[3], y[8]);
  587|      9|   accum.mul(x[4], y[7]);
  588|      9|   accum.mul(x[5], y[6]);
  589|      9|   accum.mul(x[6], y[5]);
  590|      9|   accum.mul(x[7], y[4]);
  591|      9|   accum.mul(x[8], y[3]);
  592|      9|   z[11] = accum.extract();
  593|      9|   accum.mul(x[4], y[8]);
  594|      9|   accum.mul(x[5], y[7]);
  595|      9|   accum.mul(x[6], y[6]);
  596|      9|   accum.mul(x[7], y[5]);
  597|      9|   accum.mul(x[8], y[4]);
  598|      9|   z[12] = accum.extract();
  599|      9|   accum.mul(x[5], y[8]);
  600|      9|   accum.mul(x[6], y[7]);
  601|      9|   accum.mul(x[7], y[6]);
  602|      9|   accum.mul(x[8], y[5]);
  603|      9|   z[13] = accum.extract();
  604|      9|   accum.mul(x[6], y[8]);
  605|      9|   accum.mul(x[7], y[7]);
  606|      9|   accum.mul(x[8], y[6]);
  607|      9|   z[14] = accum.extract();
  608|      9|   accum.mul(x[7], y[8]);
  609|      9|   accum.mul(x[8], y[7]);
  610|      9|   z[15] = accum.extract();
  611|      9|   accum.mul(x[8], y[8]);
  612|      9|   z[16] = accum.extract();
  613|      9|   z[17] = accum.extract();
  614|      9|}
_ZN5Botan18bigint_comba_mul16EPmPKmS2_:
  795|     28|void bigint_comba_mul16(word z[32], const word x[16], const word y[16]) {
  796|     28|   word3<word> accum;
  797|       |
  798|     28|   accum.mul(x[0], y[0]);
  799|     28|   z[0] = accum.extract();
  800|     28|   accum.mul(x[0], y[1]);
  801|     28|   accum.mul(x[1], y[0]);
  802|     28|   z[1] = accum.extract();
  803|     28|   accum.mul(x[0], y[2]);
  804|     28|   accum.mul(x[1], y[1]);
  805|     28|   accum.mul(x[2], y[0]);
  806|     28|   z[2] = accum.extract();
  807|     28|   accum.mul(x[0], y[3]);
  808|     28|   accum.mul(x[1], y[2]);
  809|     28|   accum.mul(x[2], y[1]);
  810|     28|   accum.mul(x[3], y[0]);
  811|     28|   z[3] = accum.extract();
  812|     28|   accum.mul(x[0], y[4]);
  813|     28|   accum.mul(x[1], y[3]);
  814|     28|   accum.mul(x[2], y[2]);
  815|     28|   accum.mul(x[3], y[1]);
  816|     28|   accum.mul(x[4], y[0]);
  817|     28|   z[4] = accum.extract();
  818|     28|   accum.mul(x[0], y[5]);
  819|     28|   accum.mul(x[1], y[4]);
  820|     28|   accum.mul(x[2], y[3]);
  821|     28|   accum.mul(x[3], y[2]);
  822|     28|   accum.mul(x[4], y[1]);
  823|     28|   accum.mul(x[5], y[0]);
  824|     28|   z[5] = accum.extract();
  825|     28|   accum.mul(x[0], y[6]);
  826|     28|   accum.mul(x[1], y[5]);
  827|     28|   accum.mul(x[2], y[4]);
  828|     28|   accum.mul(x[3], y[3]);
  829|     28|   accum.mul(x[4], y[2]);
  830|     28|   accum.mul(x[5], y[1]);
  831|     28|   accum.mul(x[6], y[0]);
  832|     28|   z[6] = accum.extract();
  833|     28|   accum.mul(x[0], y[7]);
  834|     28|   accum.mul(x[1], y[6]);
  835|     28|   accum.mul(x[2], y[5]);
  836|     28|   accum.mul(x[3], y[4]);
  837|     28|   accum.mul(x[4], y[3]);
  838|     28|   accum.mul(x[5], y[2]);
  839|     28|   accum.mul(x[6], y[1]);
  840|     28|   accum.mul(x[7], y[0]);
  841|     28|   z[7] = accum.extract();
  842|     28|   accum.mul(x[0], y[8]);
  843|     28|   accum.mul(x[1], y[7]);
  844|     28|   accum.mul(x[2], y[6]);
  845|     28|   accum.mul(x[3], y[5]);
  846|     28|   accum.mul(x[4], y[4]);
  847|     28|   accum.mul(x[5], y[3]);
  848|     28|   accum.mul(x[6], y[2]);
  849|     28|   accum.mul(x[7], y[1]);
  850|     28|   accum.mul(x[8], y[0]);
  851|     28|   z[8] = accum.extract();
  852|     28|   accum.mul(x[0], y[9]);
  853|     28|   accum.mul(x[1], y[8]);
  854|     28|   accum.mul(x[2], y[7]);
  855|     28|   accum.mul(x[3], y[6]);
  856|     28|   accum.mul(x[4], y[5]);
  857|     28|   accum.mul(x[5], y[4]);
  858|     28|   accum.mul(x[6], y[3]);
  859|     28|   accum.mul(x[7], y[2]);
  860|     28|   accum.mul(x[8], y[1]);
  861|     28|   accum.mul(x[9], y[0]);
  862|     28|   z[9] = accum.extract();
  863|     28|   accum.mul(x[0], y[10]);
  864|     28|   accum.mul(x[1], y[9]);
  865|     28|   accum.mul(x[2], y[8]);
  866|     28|   accum.mul(x[3], y[7]);
  867|     28|   accum.mul(x[4], y[6]);
  868|     28|   accum.mul(x[5], y[5]);
  869|     28|   accum.mul(x[6], y[4]);
  870|     28|   accum.mul(x[7], y[3]);
  871|     28|   accum.mul(x[8], y[2]);
  872|     28|   accum.mul(x[9], y[1]);
  873|     28|   accum.mul(x[10], y[0]);
  874|     28|   z[10] = accum.extract();
  875|     28|   accum.mul(x[0], y[11]);
  876|     28|   accum.mul(x[1], y[10]);
  877|     28|   accum.mul(x[2], y[9]);
  878|     28|   accum.mul(x[3], y[8]);
  879|     28|   accum.mul(x[4], y[7]);
  880|     28|   accum.mul(x[5], y[6]);
  881|     28|   accum.mul(x[6], y[5]);
  882|     28|   accum.mul(x[7], y[4]);
  883|     28|   accum.mul(x[8], y[3]);
  884|     28|   accum.mul(x[9], y[2]);
  885|     28|   accum.mul(x[10], y[1]);
  886|     28|   accum.mul(x[11], y[0]);
  887|     28|   z[11] = accum.extract();
  888|     28|   accum.mul(x[0], y[12]);
  889|     28|   accum.mul(x[1], y[11]);
  890|     28|   accum.mul(x[2], y[10]);
  891|     28|   accum.mul(x[3], y[9]);
  892|     28|   accum.mul(x[4], y[8]);
  893|     28|   accum.mul(x[5], y[7]);
  894|     28|   accum.mul(x[6], y[6]);
  895|     28|   accum.mul(x[7], y[5]);
  896|     28|   accum.mul(x[8], y[4]);
  897|     28|   accum.mul(x[9], y[3]);
  898|     28|   accum.mul(x[10], y[2]);
  899|     28|   accum.mul(x[11], y[1]);
  900|     28|   accum.mul(x[12], y[0]);
  901|     28|   z[12] = accum.extract();
  902|     28|   accum.mul(x[0], y[13]);
  903|     28|   accum.mul(x[1], y[12]);
  904|     28|   accum.mul(x[2], y[11]);
  905|     28|   accum.mul(x[3], y[10]);
  906|     28|   accum.mul(x[4], y[9]);
  907|     28|   accum.mul(x[5], y[8]);
  908|     28|   accum.mul(x[6], y[7]);
  909|     28|   accum.mul(x[7], y[6]);
  910|     28|   accum.mul(x[8], y[5]);
  911|     28|   accum.mul(x[9], y[4]);
  912|     28|   accum.mul(x[10], y[3]);
  913|     28|   accum.mul(x[11], y[2]);
  914|     28|   accum.mul(x[12], y[1]);
  915|     28|   accum.mul(x[13], y[0]);
  916|     28|   z[13] = accum.extract();
  917|     28|   accum.mul(x[0], y[14]);
  918|     28|   accum.mul(x[1], y[13]);
  919|     28|   accum.mul(x[2], y[12]);
  920|     28|   accum.mul(x[3], y[11]);
  921|     28|   accum.mul(x[4], y[10]);
  922|     28|   accum.mul(x[5], y[9]);
  923|     28|   accum.mul(x[6], y[8]);
  924|     28|   accum.mul(x[7], y[7]);
  925|     28|   accum.mul(x[8], y[6]);
  926|     28|   accum.mul(x[9], y[5]);
  927|     28|   accum.mul(x[10], y[4]);
  928|     28|   accum.mul(x[11], y[3]);
  929|     28|   accum.mul(x[12], y[2]);
  930|     28|   accum.mul(x[13], y[1]);
  931|     28|   accum.mul(x[14], y[0]);
  932|     28|   z[14] = accum.extract();
  933|     28|   accum.mul(x[0], y[15]);
  934|     28|   accum.mul(x[1], y[14]);
  935|     28|   accum.mul(x[2], y[13]);
  936|     28|   accum.mul(x[3], y[12]);
  937|     28|   accum.mul(x[4], y[11]);
  938|     28|   accum.mul(x[5], y[10]);
  939|     28|   accum.mul(x[6], y[9]);
  940|     28|   accum.mul(x[7], y[8]);
  941|     28|   accum.mul(x[8], y[7]);
  942|     28|   accum.mul(x[9], y[6]);
  943|     28|   accum.mul(x[10], y[5]);
  944|     28|   accum.mul(x[11], y[4]);
  945|     28|   accum.mul(x[12], y[3]);
  946|     28|   accum.mul(x[13], y[2]);
  947|     28|   accum.mul(x[14], y[1]);
  948|     28|   accum.mul(x[15], y[0]);
  949|     28|   z[15] = accum.extract();
  950|     28|   accum.mul(x[1], y[15]);
  951|     28|   accum.mul(x[2], y[14]);
  952|     28|   accum.mul(x[3], y[13]);
  953|     28|   accum.mul(x[4], y[12]);
  954|     28|   accum.mul(x[5], y[11]);
  955|     28|   accum.mul(x[6], y[10]);
  956|     28|   accum.mul(x[7], y[9]);
  957|     28|   accum.mul(x[8], y[8]);
  958|     28|   accum.mul(x[9], y[7]);
  959|     28|   accum.mul(x[10], y[6]);
  960|     28|   accum.mul(x[11], y[5]);
  961|     28|   accum.mul(x[12], y[4]);
  962|     28|   accum.mul(x[13], y[3]);
  963|     28|   accum.mul(x[14], y[2]);
  964|     28|   accum.mul(x[15], y[1]);
  965|     28|   z[16] = accum.extract();
  966|     28|   accum.mul(x[2], y[15]);
  967|     28|   accum.mul(x[3], y[14]);
  968|     28|   accum.mul(x[4], y[13]);
  969|     28|   accum.mul(x[5], y[12]);
  970|     28|   accum.mul(x[6], y[11]);
  971|     28|   accum.mul(x[7], y[10]);
  972|     28|   accum.mul(x[8], y[9]);
  973|     28|   accum.mul(x[9], y[8]);
  974|     28|   accum.mul(x[10], y[7]);
  975|     28|   accum.mul(x[11], y[6]);
  976|     28|   accum.mul(x[12], y[5]);
  977|     28|   accum.mul(x[13], y[4]);
  978|     28|   accum.mul(x[14], y[3]);
  979|     28|   accum.mul(x[15], y[2]);
  980|     28|   z[17] = accum.extract();
  981|     28|   accum.mul(x[3], y[15]);
  982|     28|   accum.mul(x[4], y[14]);
  983|     28|   accum.mul(x[5], y[13]);
  984|     28|   accum.mul(x[6], y[12]);
  985|     28|   accum.mul(x[7], y[11]);
  986|     28|   accum.mul(x[8], y[10]);
  987|     28|   accum.mul(x[9], y[9]);
  988|     28|   accum.mul(x[10], y[8]);
  989|     28|   accum.mul(x[11], y[7]);
  990|     28|   accum.mul(x[12], y[6]);
  991|     28|   accum.mul(x[13], y[5]);
  992|     28|   accum.mul(x[14], y[4]);
  993|     28|   accum.mul(x[15], y[3]);
  994|     28|   z[18] = accum.extract();
  995|     28|   accum.mul(x[4], y[15]);
  996|     28|   accum.mul(x[5], y[14]);
  997|     28|   accum.mul(x[6], y[13]);
  998|     28|   accum.mul(x[7], y[12]);
  999|     28|   accum.mul(x[8], y[11]);
 1000|     28|   accum.mul(x[9], y[10]);
 1001|     28|   accum.mul(x[10], y[9]);
 1002|     28|   accum.mul(x[11], y[8]);
 1003|     28|   accum.mul(x[12], y[7]);
 1004|     28|   accum.mul(x[13], y[6]);
 1005|     28|   accum.mul(x[14], y[5]);
 1006|     28|   accum.mul(x[15], y[4]);
 1007|     28|   z[19] = accum.extract();
 1008|     28|   accum.mul(x[5], y[15]);
 1009|     28|   accum.mul(x[6], y[14]);
 1010|     28|   accum.mul(x[7], y[13]);
 1011|     28|   accum.mul(x[8], y[12]);
 1012|     28|   accum.mul(x[9], y[11]);
 1013|     28|   accum.mul(x[10], y[10]);
 1014|     28|   accum.mul(x[11], y[9]);
 1015|     28|   accum.mul(x[12], y[8]);
 1016|     28|   accum.mul(x[13], y[7]);
 1017|     28|   accum.mul(x[14], y[6]);
 1018|     28|   accum.mul(x[15], y[5]);
 1019|     28|   z[20] = accum.extract();
 1020|     28|   accum.mul(x[6], y[15]);
 1021|     28|   accum.mul(x[7], y[14]);
 1022|     28|   accum.mul(x[8], y[13]);
 1023|     28|   accum.mul(x[9], y[12]);
 1024|     28|   accum.mul(x[10], y[11]);
 1025|     28|   accum.mul(x[11], y[10]);
 1026|     28|   accum.mul(x[12], y[9]);
 1027|     28|   accum.mul(x[13], y[8]);
 1028|     28|   accum.mul(x[14], y[7]);
 1029|     28|   accum.mul(x[15], y[6]);
 1030|     28|   z[21] = accum.extract();
 1031|     28|   accum.mul(x[7], y[15]);
 1032|     28|   accum.mul(x[8], y[14]);
 1033|     28|   accum.mul(x[9], y[13]);
 1034|     28|   accum.mul(x[10], y[12]);
 1035|     28|   accum.mul(x[11], y[11]);
 1036|     28|   accum.mul(x[12], y[10]);
 1037|     28|   accum.mul(x[13], y[9]);
 1038|     28|   accum.mul(x[14], y[8]);
 1039|     28|   accum.mul(x[15], y[7]);
 1040|     28|   z[22] = accum.extract();
 1041|     28|   accum.mul(x[8], y[15]);
 1042|     28|   accum.mul(x[9], y[14]);
 1043|     28|   accum.mul(x[10], y[13]);
 1044|     28|   accum.mul(x[11], y[12]);
 1045|     28|   accum.mul(x[12], y[11]);
 1046|     28|   accum.mul(x[13], y[10]);
 1047|     28|   accum.mul(x[14], y[9]);
 1048|     28|   accum.mul(x[15], y[8]);
 1049|     28|   z[23] = accum.extract();
 1050|     28|   accum.mul(x[9], y[15]);
 1051|     28|   accum.mul(x[10], y[14]);
 1052|     28|   accum.mul(x[11], y[13]);
 1053|     28|   accum.mul(x[12], y[12]);
 1054|     28|   accum.mul(x[13], y[11]);
 1055|     28|   accum.mul(x[14], y[10]);
 1056|     28|   accum.mul(x[15], y[9]);
 1057|     28|   z[24] = accum.extract();
 1058|     28|   accum.mul(x[10], y[15]);
 1059|     28|   accum.mul(x[11], y[14]);
 1060|     28|   accum.mul(x[12], y[13]);
 1061|     28|   accum.mul(x[13], y[12]);
 1062|     28|   accum.mul(x[14], y[11]);
 1063|     28|   accum.mul(x[15], y[10]);
 1064|     28|   z[25] = accum.extract();
 1065|     28|   accum.mul(x[11], y[15]);
 1066|     28|   accum.mul(x[12], y[14]);
 1067|     28|   accum.mul(x[13], y[13]);
 1068|     28|   accum.mul(x[14], y[12]);
 1069|     28|   accum.mul(x[15], y[11]);
 1070|     28|   z[26] = accum.extract();
 1071|     28|   accum.mul(x[12], y[15]);
 1072|     28|   accum.mul(x[13], y[14]);
 1073|     28|   accum.mul(x[14], y[13]);
 1074|     28|   accum.mul(x[15], y[12]);
 1075|     28|   z[27] = accum.extract();
 1076|     28|   accum.mul(x[13], y[15]);
 1077|     28|   accum.mul(x[14], y[14]);
 1078|     28|   accum.mul(x[15], y[13]);
 1079|     28|   z[28] = accum.extract();
 1080|     28|   accum.mul(x[14], y[15]);
 1081|     28|   accum.mul(x[15], y[14]);
 1082|     28|   z[29] = accum.extract();
 1083|     28|   accum.mul(x[15], y[15]);
 1084|     28|   z[30] = accum.extract();
 1085|     28|   z[31] = accum.extract();
 1086|     28|}
_ZN5Botan18bigint_comba_mul24EPmPKmS2_:
 1447|     24|void bigint_comba_mul24(word z[48], const word x[24], const word y[24]) {
 1448|     24|   word3<word> accum;
 1449|       |
 1450|     24|   accum.mul(x[0], y[0]);
 1451|     24|   z[0] = accum.extract();
 1452|     24|   accum.mul(x[0], y[1]);
 1453|     24|   accum.mul(x[1], y[0]);
 1454|     24|   z[1] = accum.extract();
 1455|     24|   accum.mul(x[0], y[2]);
 1456|     24|   accum.mul(x[1], y[1]);
 1457|     24|   accum.mul(x[2], y[0]);
 1458|     24|   z[2] = accum.extract();
 1459|     24|   accum.mul(x[0], y[3]);
 1460|     24|   accum.mul(x[1], y[2]);
 1461|     24|   accum.mul(x[2], y[1]);
 1462|     24|   accum.mul(x[3], y[0]);
 1463|     24|   z[3] = accum.extract();
 1464|     24|   accum.mul(x[0], y[4]);
 1465|     24|   accum.mul(x[1], y[3]);
 1466|     24|   accum.mul(x[2], y[2]);
 1467|     24|   accum.mul(x[3], y[1]);
 1468|     24|   accum.mul(x[4], y[0]);
 1469|     24|   z[4] = accum.extract();
 1470|     24|   accum.mul(x[0], y[5]);
 1471|     24|   accum.mul(x[1], y[4]);
 1472|     24|   accum.mul(x[2], y[3]);
 1473|     24|   accum.mul(x[3], y[2]);
 1474|     24|   accum.mul(x[4], y[1]);
 1475|     24|   accum.mul(x[5], y[0]);
 1476|     24|   z[5] = accum.extract();
 1477|     24|   accum.mul(x[0], y[6]);
 1478|     24|   accum.mul(x[1], y[5]);
 1479|     24|   accum.mul(x[2], y[4]);
 1480|     24|   accum.mul(x[3], y[3]);
 1481|     24|   accum.mul(x[4], y[2]);
 1482|     24|   accum.mul(x[5], y[1]);
 1483|     24|   accum.mul(x[6], y[0]);
 1484|     24|   z[6] = accum.extract();
 1485|     24|   accum.mul(x[0], y[7]);
 1486|     24|   accum.mul(x[1], y[6]);
 1487|     24|   accum.mul(x[2], y[5]);
 1488|     24|   accum.mul(x[3], y[4]);
 1489|     24|   accum.mul(x[4], y[3]);
 1490|     24|   accum.mul(x[5], y[2]);
 1491|     24|   accum.mul(x[6], y[1]);
 1492|     24|   accum.mul(x[7], y[0]);
 1493|     24|   z[7] = accum.extract();
 1494|     24|   accum.mul(x[0], y[8]);
 1495|     24|   accum.mul(x[1], y[7]);
 1496|     24|   accum.mul(x[2], y[6]);
 1497|     24|   accum.mul(x[3], y[5]);
 1498|     24|   accum.mul(x[4], y[4]);
 1499|     24|   accum.mul(x[5], y[3]);
 1500|     24|   accum.mul(x[6], y[2]);
 1501|     24|   accum.mul(x[7], y[1]);
 1502|     24|   accum.mul(x[8], y[0]);
 1503|     24|   z[8] = accum.extract();
 1504|     24|   accum.mul(x[0], y[9]);
 1505|     24|   accum.mul(x[1], y[8]);
 1506|     24|   accum.mul(x[2], y[7]);
 1507|     24|   accum.mul(x[3], y[6]);
 1508|     24|   accum.mul(x[4], y[5]);
 1509|     24|   accum.mul(x[5], y[4]);
 1510|     24|   accum.mul(x[6], y[3]);
 1511|     24|   accum.mul(x[7], y[2]);
 1512|     24|   accum.mul(x[8], y[1]);
 1513|     24|   accum.mul(x[9], y[0]);
 1514|     24|   z[9] = accum.extract();
 1515|     24|   accum.mul(x[0], y[10]);
 1516|     24|   accum.mul(x[1], y[9]);
 1517|     24|   accum.mul(x[2], y[8]);
 1518|     24|   accum.mul(x[3], y[7]);
 1519|     24|   accum.mul(x[4], y[6]);
 1520|     24|   accum.mul(x[5], y[5]);
 1521|     24|   accum.mul(x[6], y[4]);
 1522|     24|   accum.mul(x[7], y[3]);
 1523|     24|   accum.mul(x[8], y[2]);
 1524|     24|   accum.mul(x[9], y[1]);
 1525|     24|   accum.mul(x[10], y[0]);
 1526|     24|   z[10] = accum.extract();
 1527|     24|   accum.mul(x[0], y[11]);
 1528|     24|   accum.mul(x[1], y[10]);
 1529|     24|   accum.mul(x[2], y[9]);
 1530|     24|   accum.mul(x[3], y[8]);
 1531|     24|   accum.mul(x[4], y[7]);
 1532|     24|   accum.mul(x[5], y[6]);
 1533|     24|   accum.mul(x[6], y[5]);
 1534|     24|   accum.mul(x[7], y[4]);
 1535|     24|   accum.mul(x[8], y[3]);
 1536|     24|   accum.mul(x[9], y[2]);
 1537|     24|   accum.mul(x[10], y[1]);
 1538|     24|   accum.mul(x[11], y[0]);
 1539|     24|   z[11] = accum.extract();
 1540|     24|   accum.mul(x[0], y[12]);
 1541|     24|   accum.mul(x[1], y[11]);
 1542|     24|   accum.mul(x[2], y[10]);
 1543|     24|   accum.mul(x[3], y[9]);
 1544|     24|   accum.mul(x[4], y[8]);
 1545|     24|   accum.mul(x[5], y[7]);
 1546|     24|   accum.mul(x[6], y[6]);
 1547|     24|   accum.mul(x[7], y[5]);
 1548|     24|   accum.mul(x[8], y[4]);
 1549|     24|   accum.mul(x[9], y[3]);
 1550|     24|   accum.mul(x[10], y[2]);
 1551|     24|   accum.mul(x[11], y[1]);
 1552|     24|   accum.mul(x[12], y[0]);
 1553|     24|   z[12] = accum.extract();
 1554|     24|   accum.mul(x[0], y[13]);
 1555|     24|   accum.mul(x[1], y[12]);
 1556|     24|   accum.mul(x[2], y[11]);
 1557|     24|   accum.mul(x[3], y[10]);
 1558|     24|   accum.mul(x[4], y[9]);
 1559|     24|   accum.mul(x[5], y[8]);
 1560|     24|   accum.mul(x[6], y[7]);
 1561|     24|   accum.mul(x[7], y[6]);
 1562|     24|   accum.mul(x[8], y[5]);
 1563|     24|   accum.mul(x[9], y[4]);
 1564|     24|   accum.mul(x[10], y[3]);
 1565|     24|   accum.mul(x[11], y[2]);
 1566|     24|   accum.mul(x[12], y[1]);
 1567|     24|   accum.mul(x[13], y[0]);
 1568|     24|   z[13] = accum.extract();
 1569|     24|   accum.mul(x[0], y[14]);
 1570|     24|   accum.mul(x[1], y[13]);
 1571|     24|   accum.mul(x[2], y[12]);
 1572|     24|   accum.mul(x[3], y[11]);
 1573|     24|   accum.mul(x[4], y[10]);
 1574|     24|   accum.mul(x[5], y[9]);
 1575|     24|   accum.mul(x[6], y[8]);
 1576|     24|   accum.mul(x[7], y[7]);
 1577|     24|   accum.mul(x[8], y[6]);
 1578|     24|   accum.mul(x[9], y[5]);
 1579|     24|   accum.mul(x[10], y[4]);
 1580|     24|   accum.mul(x[11], y[3]);
 1581|     24|   accum.mul(x[12], y[2]);
 1582|     24|   accum.mul(x[13], y[1]);
 1583|     24|   accum.mul(x[14], y[0]);
 1584|     24|   z[14] = accum.extract();
 1585|     24|   accum.mul(x[0], y[15]);
 1586|     24|   accum.mul(x[1], y[14]);
 1587|     24|   accum.mul(x[2], y[13]);
 1588|     24|   accum.mul(x[3], y[12]);
 1589|     24|   accum.mul(x[4], y[11]);
 1590|     24|   accum.mul(x[5], y[10]);
 1591|     24|   accum.mul(x[6], y[9]);
 1592|     24|   accum.mul(x[7], y[8]);
 1593|     24|   accum.mul(x[8], y[7]);
 1594|     24|   accum.mul(x[9], y[6]);
 1595|     24|   accum.mul(x[10], y[5]);
 1596|     24|   accum.mul(x[11], y[4]);
 1597|     24|   accum.mul(x[12], y[3]);
 1598|     24|   accum.mul(x[13], y[2]);
 1599|     24|   accum.mul(x[14], y[1]);
 1600|     24|   accum.mul(x[15], y[0]);
 1601|     24|   z[15] = accum.extract();
 1602|     24|   accum.mul(x[0], y[16]);
 1603|     24|   accum.mul(x[1], y[15]);
 1604|     24|   accum.mul(x[2], y[14]);
 1605|     24|   accum.mul(x[3], y[13]);
 1606|     24|   accum.mul(x[4], y[12]);
 1607|     24|   accum.mul(x[5], y[11]);
 1608|     24|   accum.mul(x[6], y[10]);
 1609|     24|   accum.mul(x[7], y[9]);
 1610|     24|   accum.mul(x[8], y[8]);
 1611|     24|   accum.mul(x[9], y[7]);
 1612|     24|   accum.mul(x[10], y[6]);
 1613|     24|   accum.mul(x[11], y[5]);
 1614|     24|   accum.mul(x[12], y[4]);
 1615|     24|   accum.mul(x[13], y[3]);
 1616|     24|   accum.mul(x[14], y[2]);
 1617|     24|   accum.mul(x[15], y[1]);
 1618|     24|   accum.mul(x[16], y[0]);
 1619|     24|   z[16] = accum.extract();
 1620|     24|   accum.mul(x[0], y[17]);
 1621|     24|   accum.mul(x[1], y[16]);
 1622|     24|   accum.mul(x[2], y[15]);
 1623|     24|   accum.mul(x[3], y[14]);
 1624|     24|   accum.mul(x[4], y[13]);
 1625|     24|   accum.mul(x[5], y[12]);
 1626|     24|   accum.mul(x[6], y[11]);
 1627|     24|   accum.mul(x[7], y[10]);
 1628|     24|   accum.mul(x[8], y[9]);
 1629|     24|   accum.mul(x[9], y[8]);
 1630|     24|   accum.mul(x[10], y[7]);
 1631|     24|   accum.mul(x[11], y[6]);
 1632|     24|   accum.mul(x[12], y[5]);
 1633|     24|   accum.mul(x[13], y[4]);
 1634|     24|   accum.mul(x[14], y[3]);
 1635|     24|   accum.mul(x[15], y[2]);
 1636|     24|   accum.mul(x[16], y[1]);
 1637|     24|   accum.mul(x[17], y[0]);
 1638|     24|   z[17] = accum.extract();
 1639|     24|   accum.mul(x[0], y[18]);
 1640|     24|   accum.mul(x[1], y[17]);
 1641|     24|   accum.mul(x[2], y[16]);
 1642|     24|   accum.mul(x[3], y[15]);
 1643|     24|   accum.mul(x[4], y[14]);
 1644|     24|   accum.mul(x[5], y[13]);
 1645|     24|   accum.mul(x[6], y[12]);
 1646|     24|   accum.mul(x[7], y[11]);
 1647|     24|   accum.mul(x[8], y[10]);
 1648|     24|   accum.mul(x[9], y[9]);
 1649|     24|   accum.mul(x[10], y[8]);
 1650|     24|   accum.mul(x[11], y[7]);
 1651|     24|   accum.mul(x[12], y[6]);
 1652|     24|   accum.mul(x[13], y[5]);
 1653|     24|   accum.mul(x[14], y[4]);
 1654|     24|   accum.mul(x[15], y[3]);
 1655|     24|   accum.mul(x[16], y[2]);
 1656|     24|   accum.mul(x[17], y[1]);
 1657|     24|   accum.mul(x[18], y[0]);
 1658|     24|   z[18] = accum.extract();
 1659|     24|   accum.mul(x[0], y[19]);
 1660|     24|   accum.mul(x[1], y[18]);
 1661|     24|   accum.mul(x[2], y[17]);
 1662|     24|   accum.mul(x[3], y[16]);
 1663|     24|   accum.mul(x[4], y[15]);
 1664|     24|   accum.mul(x[5], y[14]);
 1665|     24|   accum.mul(x[6], y[13]);
 1666|     24|   accum.mul(x[7], y[12]);
 1667|     24|   accum.mul(x[8], y[11]);
 1668|     24|   accum.mul(x[9], y[10]);
 1669|     24|   accum.mul(x[10], y[9]);
 1670|     24|   accum.mul(x[11], y[8]);
 1671|     24|   accum.mul(x[12], y[7]);
 1672|     24|   accum.mul(x[13], y[6]);
 1673|     24|   accum.mul(x[14], y[5]);
 1674|     24|   accum.mul(x[15], y[4]);
 1675|     24|   accum.mul(x[16], y[3]);
 1676|     24|   accum.mul(x[17], y[2]);
 1677|     24|   accum.mul(x[18], y[1]);
 1678|     24|   accum.mul(x[19], y[0]);
 1679|     24|   z[19] = accum.extract();
 1680|     24|   accum.mul(x[0], y[20]);
 1681|     24|   accum.mul(x[1], y[19]);
 1682|     24|   accum.mul(x[2], y[18]);
 1683|     24|   accum.mul(x[3], y[17]);
 1684|     24|   accum.mul(x[4], y[16]);
 1685|     24|   accum.mul(x[5], y[15]);
 1686|     24|   accum.mul(x[6], y[14]);
 1687|     24|   accum.mul(x[7], y[13]);
 1688|     24|   accum.mul(x[8], y[12]);
 1689|     24|   accum.mul(x[9], y[11]);
 1690|     24|   accum.mul(x[10], y[10]);
 1691|     24|   accum.mul(x[11], y[9]);
 1692|     24|   accum.mul(x[12], y[8]);
 1693|     24|   accum.mul(x[13], y[7]);
 1694|     24|   accum.mul(x[14], y[6]);
 1695|     24|   accum.mul(x[15], y[5]);
 1696|     24|   accum.mul(x[16], y[4]);
 1697|     24|   accum.mul(x[17], y[3]);
 1698|     24|   accum.mul(x[18], y[2]);
 1699|     24|   accum.mul(x[19], y[1]);
 1700|     24|   accum.mul(x[20], y[0]);
 1701|     24|   z[20] = accum.extract();
 1702|     24|   accum.mul(x[0], y[21]);
 1703|     24|   accum.mul(x[1], y[20]);
 1704|     24|   accum.mul(x[2], y[19]);
 1705|     24|   accum.mul(x[3], y[18]);
 1706|     24|   accum.mul(x[4], y[17]);
 1707|     24|   accum.mul(x[5], y[16]);
 1708|     24|   accum.mul(x[6], y[15]);
 1709|     24|   accum.mul(x[7], y[14]);
 1710|     24|   accum.mul(x[8], y[13]);
 1711|     24|   accum.mul(x[9], y[12]);
 1712|     24|   accum.mul(x[10], y[11]);
 1713|     24|   accum.mul(x[11], y[10]);
 1714|     24|   accum.mul(x[12], y[9]);
 1715|     24|   accum.mul(x[13], y[8]);
 1716|     24|   accum.mul(x[14], y[7]);
 1717|     24|   accum.mul(x[15], y[6]);
 1718|     24|   accum.mul(x[16], y[5]);
 1719|     24|   accum.mul(x[17], y[4]);
 1720|     24|   accum.mul(x[18], y[3]);
 1721|     24|   accum.mul(x[19], y[2]);
 1722|     24|   accum.mul(x[20], y[1]);
 1723|     24|   accum.mul(x[21], y[0]);
 1724|     24|   z[21] = accum.extract();
 1725|     24|   accum.mul(x[0], y[22]);
 1726|     24|   accum.mul(x[1], y[21]);
 1727|     24|   accum.mul(x[2], y[20]);
 1728|     24|   accum.mul(x[3], y[19]);
 1729|     24|   accum.mul(x[4], y[18]);
 1730|     24|   accum.mul(x[5], y[17]);
 1731|     24|   accum.mul(x[6], y[16]);
 1732|     24|   accum.mul(x[7], y[15]);
 1733|     24|   accum.mul(x[8], y[14]);
 1734|     24|   accum.mul(x[9], y[13]);
 1735|     24|   accum.mul(x[10], y[12]);
 1736|     24|   accum.mul(x[11], y[11]);
 1737|     24|   accum.mul(x[12], y[10]);
 1738|     24|   accum.mul(x[13], y[9]);
 1739|     24|   accum.mul(x[14], y[8]);
 1740|     24|   accum.mul(x[15], y[7]);
 1741|     24|   accum.mul(x[16], y[6]);
 1742|     24|   accum.mul(x[17], y[5]);
 1743|     24|   accum.mul(x[18], y[4]);
 1744|     24|   accum.mul(x[19], y[3]);
 1745|     24|   accum.mul(x[20], y[2]);
 1746|     24|   accum.mul(x[21], y[1]);
 1747|     24|   accum.mul(x[22], y[0]);
 1748|     24|   z[22] = accum.extract();
 1749|     24|   accum.mul(x[0], y[23]);
 1750|     24|   accum.mul(x[1], y[22]);
 1751|     24|   accum.mul(x[2], y[21]);
 1752|     24|   accum.mul(x[3], y[20]);
 1753|     24|   accum.mul(x[4], y[19]);
 1754|     24|   accum.mul(x[5], y[18]);
 1755|     24|   accum.mul(x[6], y[17]);
 1756|     24|   accum.mul(x[7], y[16]);
 1757|     24|   accum.mul(x[8], y[15]);
 1758|     24|   accum.mul(x[9], y[14]);
 1759|     24|   accum.mul(x[10], y[13]);
 1760|     24|   accum.mul(x[11], y[12]);
 1761|     24|   accum.mul(x[12], y[11]);
 1762|     24|   accum.mul(x[13], y[10]);
 1763|     24|   accum.mul(x[14], y[9]);
 1764|     24|   accum.mul(x[15], y[8]);
 1765|     24|   accum.mul(x[16], y[7]);
 1766|     24|   accum.mul(x[17], y[6]);
 1767|     24|   accum.mul(x[18], y[5]);
 1768|     24|   accum.mul(x[19], y[4]);
 1769|     24|   accum.mul(x[20], y[3]);
 1770|     24|   accum.mul(x[21], y[2]);
 1771|     24|   accum.mul(x[22], y[1]);
 1772|     24|   accum.mul(x[23], y[0]);
 1773|     24|   z[23] = accum.extract();
 1774|     24|   accum.mul(x[1], y[23]);
 1775|     24|   accum.mul(x[2], y[22]);
 1776|     24|   accum.mul(x[3], y[21]);
 1777|     24|   accum.mul(x[4], y[20]);
 1778|     24|   accum.mul(x[5], y[19]);
 1779|     24|   accum.mul(x[6], y[18]);
 1780|     24|   accum.mul(x[7], y[17]);
 1781|     24|   accum.mul(x[8], y[16]);
 1782|     24|   accum.mul(x[9], y[15]);
 1783|     24|   accum.mul(x[10], y[14]);
 1784|     24|   accum.mul(x[11], y[13]);
 1785|     24|   accum.mul(x[12], y[12]);
 1786|     24|   accum.mul(x[13], y[11]);
 1787|     24|   accum.mul(x[14], y[10]);
 1788|     24|   accum.mul(x[15], y[9]);
 1789|     24|   accum.mul(x[16], y[8]);
 1790|     24|   accum.mul(x[17], y[7]);
 1791|     24|   accum.mul(x[18], y[6]);
 1792|     24|   accum.mul(x[19], y[5]);
 1793|     24|   accum.mul(x[20], y[4]);
 1794|     24|   accum.mul(x[21], y[3]);
 1795|     24|   accum.mul(x[22], y[2]);
 1796|     24|   accum.mul(x[23], y[1]);
 1797|     24|   z[24] = accum.extract();
 1798|     24|   accum.mul(x[2], y[23]);
 1799|     24|   accum.mul(x[3], y[22]);
 1800|     24|   accum.mul(x[4], y[21]);
 1801|     24|   accum.mul(x[5], y[20]);
 1802|     24|   accum.mul(x[6], y[19]);
 1803|     24|   accum.mul(x[7], y[18]);
 1804|     24|   accum.mul(x[8], y[17]);
 1805|     24|   accum.mul(x[9], y[16]);
 1806|     24|   accum.mul(x[10], y[15]);
 1807|     24|   accum.mul(x[11], y[14]);
 1808|     24|   accum.mul(x[12], y[13]);
 1809|     24|   accum.mul(x[13], y[12]);
 1810|     24|   accum.mul(x[14], y[11]);
 1811|     24|   accum.mul(x[15], y[10]);
 1812|     24|   accum.mul(x[16], y[9]);
 1813|     24|   accum.mul(x[17], y[8]);
 1814|     24|   accum.mul(x[18], y[7]);
 1815|     24|   accum.mul(x[19], y[6]);
 1816|     24|   accum.mul(x[20], y[5]);
 1817|     24|   accum.mul(x[21], y[4]);
 1818|     24|   accum.mul(x[22], y[3]);
 1819|     24|   accum.mul(x[23], y[2]);
 1820|     24|   z[25] = accum.extract();
 1821|     24|   accum.mul(x[3], y[23]);
 1822|     24|   accum.mul(x[4], y[22]);
 1823|     24|   accum.mul(x[5], y[21]);
 1824|     24|   accum.mul(x[6], y[20]);
 1825|     24|   accum.mul(x[7], y[19]);
 1826|     24|   accum.mul(x[8], y[18]);
 1827|     24|   accum.mul(x[9], y[17]);
 1828|     24|   accum.mul(x[10], y[16]);
 1829|     24|   accum.mul(x[11], y[15]);
 1830|     24|   accum.mul(x[12], y[14]);
 1831|     24|   accum.mul(x[13], y[13]);
 1832|     24|   accum.mul(x[14], y[12]);
 1833|     24|   accum.mul(x[15], y[11]);
 1834|     24|   accum.mul(x[16], y[10]);
 1835|     24|   accum.mul(x[17], y[9]);
 1836|     24|   accum.mul(x[18], y[8]);
 1837|     24|   accum.mul(x[19], y[7]);
 1838|     24|   accum.mul(x[20], y[6]);
 1839|     24|   accum.mul(x[21], y[5]);
 1840|     24|   accum.mul(x[22], y[4]);
 1841|     24|   accum.mul(x[23], y[3]);
 1842|     24|   z[26] = accum.extract();
 1843|     24|   accum.mul(x[4], y[23]);
 1844|     24|   accum.mul(x[5], y[22]);
 1845|     24|   accum.mul(x[6], y[21]);
 1846|     24|   accum.mul(x[7], y[20]);
 1847|     24|   accum.mul(x[8], y[19]);
 1848|     24|   accum.mul(x[9], y[18]);
 1849|     24|   accum.mul(x[10], y[17]);
 1850|     24|   accum.mul(x[11], y[16]);
 1851|     24|   accum.mul(x[12], y[15]);
 1852|     24|   accum.mul(x[13], y[14]);
 1853|     24|   accum.mul(x[14], y[13]);
 1854|     24|   accum.mul(x[15], y[12]);
 1855|     24|   accum.mul(x[16], y[11]);
 1856|     24|   accum.mul(x[17], y[10]);
 1857|     24|   accum.mul(x[18], y[9]);
 1858|     24|   accum.mul(x[19], y[8]);
 1859|     24|   accum.mul(x[20], y[7]);
 1860|     24|   accum.mul(x[21], y[6]);
 1861|     24|   accum.mul(x[22], y[5]);
 1862|     24|   accum.mul(x[23], y[4]);
 1863|     24|   z[27] = accum.extract();
 1864|     24|   accum.mul(x[5], y[23]);
 1865|     24|   accum.mul(x[6], y[22]);
 1866|     24|   accum.mul(x[7], y[21]);
 1867|     24|   accum.mul(x[8], y[20]);
 1868|     24|   accum.mul(x[9], y[19]);
 1869|     24|   accum.mul(x[10], y[18]);
 1870|     24|   accum.mul(x[11], y[17]);
 1871|     24|   accum.mul(x[12], y[16]);
 1872|     24|   accum.mul(x[13], y[15]);
 1873|     24|   accum.mul(x[14], y[14]);
 1874|     24|   accum.mul(x[15], y[13]);
 1875|     24|   accum.mul(x[16], y[12]);
 1876|     24|   accum.mul(x[17], y[11]);
 1877|     24|   accum.mul(x[18], y[10]);
 1878|     24|   accum.mul(x[19], y[9]);
 1879|     24|   accum.mul(x[20], y[8]);
 1880|     24|   accum.mul(x[21], y[7]);
 1881|     24|   accum.mul(x[22], y[6]);
 1882|     24|   accum.mul(x[23], y[5]);
 1883|     24|   z[28] = accum.extract();
 1884|     24|   accum.mul(x[6], y[23]);
 1885|     24|   accum.mul(x[7], y[22]);
 1886|     24|   accum.mul(x[8], y[21]);
 1887|     24|   accum.mul(x[9], y[20]);
 1888|     24|   accum.mul(x[10], y[19]);
 1889|     24|   accum.mul(x[11], y[18]);
 1890|     24|   accum.mul(x[12], y[17]);
 1891|     24|   accum.mul(x[13], y[16]);
 1892|     24|   accum.mul(x[14], y[15]);
 1893|     24|   accum.mul(x[15], y[14]);
 1894|     24|   accum.mul(x[16], y[13]);
 1895|     24|   accum.mul(x[17], y[12]);
 1896|     24|   accum.mul(x[18], y[11]);
 1897|     24|   accum.mul(x[19], y[10]);
 1898|     24|   accum.mul(x[20], y[9]);
 1899|     24|   accum.mul(x[21], y[8]);
 1900|     24|   accum.mul(x[22], y[7]);
 1901|     24|   accum.mul(x[23], y[6]);
 1902|     24|   z[29] = accum.extract();
 1903|     24|   accum.mul(x[7], y[23]);
 1904|     24|   accum.mul(x[8], y[22]);
 1905|     24|   accum.mul(x[9], y[21]);
 1906|     24|   accum.mul(x[10], y[20]);
 1907|     24|   accum.mul(x[11], y[19]);
 1908|     24|   accum.mul(x[12], y[18]);
 1909|     24|   accum.mul(x[13], y[17]);
 1910|     24|   accum.mul(x[14], y[16]);
 1911|     24|   accum.mul(x[15], y[15]);
 1912|     24|   accum.mul(x[16], y[14]);
 1913|     24|   accum.mul(x[17], y[13]);
 1914|     24|   accum.mul(x[18], y[12]);
 1915|     24|   accum.mul(x[19], y[11]);
 1916|     24|   accum.mul(x[20], y[10]);
 1917|     24|   accum.mul(x[21], y[9]);
 1918|     24|   accum.mul(x[22], y[8]);
 1919|     24|   accum.mul(x[23], y[7]);
 1920|     24|   z[30] = accum.extract();
 1921|     24|   accum.mul(x[8], y[23]);
 1922|     24|   accum.mul(x[9], y[22]);
 1923|     24|   accum.mul(x[10], y[21]);
 1924|     24|   accum.mul(x[11], y[20]);
 1925|     24|   accum.mul(x[12], y[19]);
 1926|     24|   accum.mul(x[13], y[18]);
 1927|     24|   accum.mul(x[14], y[17]);
 1928|     24|   accum.mul(x[15], y[16]);
 1929|     24|   accum.mul(x[16], y[15]);
 1930|     24|   accum.mul(x[17], y[14]);
 1931|     24|   accum.mul(x[18], y[13]);
 1932|     24|   accum.mul(x[19], y[12]);
 1933|     24|   accum.mul(x[20], y[11]);
 1934|     24|   accum.mul(x[21], y[10]);
 1935|     24|   accum.mul(x[22], y[9]);
 1936|     24|   accum.mul(x[23], y[8]);
 1937|     24|   z[31] = accum.extract();
 1938|     24|   accum.mul(x[9], y[23]);
 1939|     24|   accum.mul(x[10], y[22]);
 1940|     24|   accum.mul(x[11], y[21]);
 1941|     24|   accum.mul(x[12], y[20]);
 1942|     24|   accum.mul(x[13], y[19]);
 1943|     24|   accum.mul(x[14], y[18]);
 1944|     24|   accum.mul(x[15], y[17]);
 1945|     24|   accum.mul(x[16], y[16]);
 1946|     24|   accum.mul(x[17], y[15]);
 1947|     24|   accum.mul(x[18], y[14]);
 1948|     24|   accum.mul(x[19], y[13]);
 1949|     24|   accum.mul(x[20], y[12]);
 1950|     24|   accum.mul(x[21], y[11]);
 1951|     24|   accum.mul(x[22], y[10]);
 1952|     24|   accum.mul(x[23], y[9]);
 1953|     24|   z[32] = accum.extract();
 1954|     24|   accum.mul(x[10], y[23]);
 1955|     24|   accum.mul(x[11], y[22]);
 1956|     24|   accum.mul(x[12], y[21]);
 1957|     24|   accum.mul(x[13], y[20]);
 1958|     24|   accum.mul(x[14], y[19]);
 1959|     24|   accum.mul(x[15], y[18]);
 1960|     24|   accum.mul(x[16], y[17]);
 1961|     24|   accum.mul(x[17], y[16]);
 1962|     24|   accum.mul(x[18], y[15]);
 1963|     24|   accum.mul(x[19], y[14]);
 1964|     24|   accum.mul(x[20], y[13]);
 1965|     24|   accum.mul(x[21], y[12]);
 1966|     24|   accum.mul(x[22], y[11]);
 1967|     24|   accum.mul(x[23], y[10]);
 1968|     24|   z[33] = accum.extract();
 1969|     24|   accum.mul(x[11], y[23]);
 1970|     24|   accum.mul(x[12], y[22]);
 1971|     24|   accum.mul(x[13], y[21]);
 1972|     24|   accum.mul(x[14], y[20]);
 1973|     24|   accum.mul(x[15], y[19]);
 1974|     24|   accum.mul(x[16], y[18]);
 1975|     24|   accum.mul(x[17], y[17]);
 1976|     24|   accum.mul(x[18], y[16]);
 1977|     24|   accum.mul(x[19], y[15]);
 1978|     24|   accum.mul(x[20], y[14]);
 1979|     24|   accum.mul(x[21], y[13]);
 1980|     24|   accum.mul(x[22], y[12]);
 1981|     24|   accum.mul(x[23], y[11]);
 1982|     24|   z[34] = accum.extract();
 1983|     24|   accum.mul(x[12], y[23]);
 1984|     24|   accum.mul(x[13], y[22]);
 1985|     24|   accum.mul(x[14], y[21]);
 1986|     24|   accum.mul(x[15], y[20]);
 1987|     24|   accum.mul(x[16], y[19]);
 1988|     24|   accum.mul(x[17], y[18]);
 1989|     24|   accum.mul(x[18], y[17]);
 1990|     24|   accum.mul(x[19], y[16]);
 1991|     24|   accum.mul(x[20], y[15]);
 1992|     24|   accum.mul(x[21], y[14]);
 1993|     24|   accum.mul(x[22], y[13]);
 1994|     24|   accum.mul(x[23], y[12]);
 1995|     24|   z[35] = accum.extract();
 1996|     24|   accum.mul(x[13], y[23]);
 1997|     24|   accum.mul(x[14], y[22]);
 1998|     24|   accum.mul(x[15], y[21]);
 1999|     24|   accum.mul(x[16], y[20]);
 2000|     24|   accum.mul(x[17], y[19]);
 2001|     24|   accum.mul(x[18], y[18]);
 2002|     24|   accum.mul(x[19], y[17]);
 2003|     24|   accum.mul(x[20], y[16]);
 2004|     24|   accum.mul(x[21], y[15]);
 2005|     24|   accum.mul(x[22], y[14]);
 2006|     24|   accum.mul(x[23], y[13]);
 2007|     24|   z[36] = accum.extract();
 2008|     24|   accum.mul(x[14], y[23]);
 2009|     24|   accum.mul(x[15], y[22]);
 2010|     24|   accum.mul(x[16], y[21]);
 2011|     24|   accum.mul(x[17], y[20]);
 2012|     24|   accum.mul(x[18], y[19]);
 2013|     24|   accum.mul(x[19], y[18]);
 2014|     24|   accum.mul(x[20], y[17]);
 2015|     24|   accum.mul(x[21], y[16]);
 2016|     24|   accum.mul(x[22], y[15]);
 2017|     24|   accum.mul(x[23], y[14]);
 2018|     24|   z[37] = accum.extract();
 2019|     24|   accum.mul(x[15], y[23]);
 2020|     24|   accum.mul(x[16], y[22]);
 2021|     24|   accum.mul(x[17], y[21]);
 2022|     24|   accum.mul(x[18], y[20]);
 2023|     24|   accum.mul(x[19], y[19]);
 2024|     24|   accum.mul(x[20], y[18]);
 2025|     24|   accum.mul(x[21], y[17]);
 2026|     24|   accum.mul(x[22], y[16]);
 2027|     24|   accum.mul(x[23], y[15]);
 2028|     24|   z[38] = accum.extract();
 2029|     24|   accum.mul(x[16], y[23]);
 2030|     24|   accum.mul(x[17], y[22]);
 2031|     24|   accum.mul(x[18], y[21]);
 2032|     24|   accum.mul(x[19], y[20]);
 2033|     24|   accum.mul(x[20], y[19]);
 2034|     24|   accum.mul(x[21], y[18]);
 2035|     24|   accum.mul(x[22], y[17]);
 2036|     24|   accum.mul(x[23], y[16]);
 2037|     24|   z[39] = accum.extract();
 2038|     24|   accum.mul(x[17], y[23]);
 2039|     24|   accum.mul(x[18], y[22]);
 2040|     24|   accum.mul(x[19], y[21]);
 2041|     24|   accum.mul(x[20], y[20]);
 2042|     24|   accum.mul(x[21], y[19]);
 2043|     24|   accum.mul(x[22], y[18]);
 2044|     24|   accum.mul(x[23], y[17]);
 2045|     24|   z[40] = accum.extract();
 2046|     24|   accum.mul(x[18], y[23]);
 2047|     24|   accum.mul(x[19], y[22]);
 2048|     24|   accum.mul(x[20], y[21]);
 2049|     24|   accum.mul(x[21], y[20]);
 2050|     24|   accum.mul(x[22], y[19]);
 2051|     24|   accum.mul(x[23], y[18]);
 2052|     24|   z[41] = accum.extract();
 2053|     24|   accum.mul(x[19], y[23]);
 2054|     24|   accum.mul(x[20], y[22]);
 2055|     24|   accum.mul(x[21], y[21]);
 2056|     24|   accum.mul(x[22], y[20]);
 2057|     24|   accum.mul(x[23], y[19]);
 2058|     24|   z[42] = accum.extract();
 2059|     24|   accum.mul(x[20], y[23]);
 2060|     24|   accum.mul(x[21], y[22]);
 2061|     24|   accum.mul(x[22], y[21]);
 2062|     24|   accum.mul(x[23], y[20]);
 2063|     24|   z[43] = accum.extract();
 2064|     24|   accum.mul(x[21], y[23]);
 2065|     24|   accum.mul(x[22], y[22]);
 2066|     24|   accum.mul(x[23], y[21]);
 2067|     24|   z[44] = accum.extract();
 2068|     24|   accum.mul(x[22], y[23]);
 2069|     24|   accum.mul(x[23], y[22]);
 2070|     24|   z[45] = accum.extract();
 2071|     24|   accum.mul(x[23], y[23]);
 2072|     24|   z[46] = accum.extract();
 2073|     24|   z[47] = accum.extract();
 2074|     24|}

_ZN5Botan12basecase_mulEPmmPKmmS2_m:
   20|    120|void basecase_mul(word z[], size_t z_size, const word x[], size_t x_size, const word y[], size_t y_size) {
   21|    120|   if(z_size < x_size + y_size) {
  ------------------
  |  Branch (21:7): [True: 0, False: 120]
  ------------------
   22|      0|      throw Invalid_Argument("basecase_mul z_size too small");
   23|      0|   }
   24|       |
   25|    120|   const size_t x_size_8 = x_size - (x_size % 8);
   26|       |
   27|    120|   zeroize_buffer(z, z_size);
   28|       |
   29|  1.96k|   for(size_t i = 0; i != y_size; ++i) {
  ------------------
  |  Branch (29:22): [True: 1.84k, False: 120]
  ------------------
   30|  1.84k|      const word y_i = y[i];
   31|       |
   32|  1.84k|      word carry = 0;
   33|       |
   34|  4.08k|      for(size_t j = 0; j != x_size_8; j += 8) {
  ------------------
  |  Branch (34:25): [True: 2.24k, False: 1.84k]
  ------------------
   35|  2.24k|         carry = word8_madd3(z + i + j, x + j, y_i, carry);
   36|  2.24k|      }
   37|       |
   38|  7.11k|      for(size_t j = x_size_8; j != x_size; ++j) {
  ------------------
  |  Branch (38:32): [True: 5.26k, False: 1.84k]
  ------------------
   39|  5.26k|         z[i + j] = word_madd3(x[j], y_i, z[i + j], &carry);
   40|  5.26k|      }
   41|       |
   42|  1.84k|      z[x_size + i] = carry;
   43|  1.84k|   }
   44|    120|}
_ZN5Botan10bigint_mulEPmmPKmmmS2_mmS0_m:
  292|    242|                size_t ws_size) {
  293|    242|   zeroize_buffer(z, z_size);
  294|       |
  295|    242|   if(x_sw == 1) {
  ------------------
  |  Branch (295:7): [True: 0, False: 242]
  ------------------
  296|      0|      bigint_linmul3(z, y, y_sw, x[0]);
  297|    242|   } else if(y_sw == 1) {
  ------------------
  |  Branch (297:14): [True: 0, False: 242]
  ------------------
  298|      0|      bigint_linmul3(z, x, x_sw, y[0]);
  299|    242|   } else if(sized_for_comba_mul<4>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (299:14): [True: 31, False: 211]
  ------------------
  300|     31|      bigint_comba_mul4(z, x, y);
  301|    211|   } else if(sized_for_comba_mul<6>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (301:14): [True: 20, False: 191]
  ------------------
  302|     20|      bigint_comba_mul6(z, x, y);
  303|    191|   } else if(sized_for_comba_mul<8>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (303:14): [True: 20, False: 171]
  ------------------
  304|     20|      bigint_comba_mul8(z, x, y);
  305|    171|   } else if(sized_for_comba_mul<9>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (305:14): [True: 9, False: 162]
  ------------------
  306|      9|      bigint_comba_mul9(z, x, y);
  307|    162|   } else if(sized_for_comba_mul<16>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (307:14): [True: 22, False: 140]
  ------------------
  308|     22|      bigint_comba_mul16(z, x, y);
  309|    140|   } else if(sized_for_comba_mul<24>(x_sw, x_size, y_sw, y_size, z_size)) {
  ------------------
  |  Branch (309:14): [True: 24, False: 116]
  ------------------
  310|     24|      bigint_comba_mul24(z, x, y);
  311|    116|   } else if(x_sw < KARATSUBA_MULTIPLY_THRESHOLD || y_sw < KARATSUBA_MULTIPLY_THRESHOLD || workspace == nullptr) {
  ------------------
  |  Branch (311:14): [True: 71, False: 45]
  |  Branch (311:53): [True: 40, False: 5]
  |  Branch (311:92): [True: 0, False: 5]
  ------------------
  312|    111|      basecase_mul(z, z_size, x, x_sw, y, y_sw);
  313|    111|   } else {
  314|      5|      const size_t N = karatsuba_size(z_size, x_size, x_sw, y_size, y_sw);
  315|       |
  316|      5|      if(N > 0 && z_size >= 2 * N && ws_size >= 2 * N) {
  ------------------
  |  Branch (316:10): [True: 5, False: 0]
  |  Branch (316:19): [True: 5, False: 0]
  |  Branch (316:38): [True: 5, False: 0]
  ------------------
  317|      5|         karatsuba_mul(z, x, y, N, workspace);
  318|      5|      } else {
  319|      0|         basecase_mul(z, z_size, x, x_sw, y, y_sw);
  320|      0|      }
  321|      5|   }
  322|    242|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_114karatsuba_sizeEmmmmm:
  203|      5|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|      5|   if(x_sw > x_size || x_sw > y_size || y_sw > x_size || y_sw > y_size) {
  ------------------
  |  Branch (204:7): [True: 0, False: 5]
  |  Branch (204:24): [True: 0, False: 5]
  |  Branch (204:41): [True: 0, False: 5]
  |  Branch (204:58): [True: 0, False: 5]
  ------------------
  205|      0|      return 0;
  206|      0|   }
  207|       |
  208|      5|   if(((x_size == x_sw) && (x_size % 2 != 0)) || ((y_size == y_sw) && (y_size % 2 != 0))) {
  ------------------
  |  Branch (208:8): [True: 0, False: 5]
  |  Branch (208:28): [True: 0, False: 0]
  |  Branch (208:51): [True: 0, False: 5]
  |  Branch (208:71): [True: 0, False: 0]
  ------------------
  209|      0|      return 0;
  210|      0|   }
  211|       |
  212|      5|   const size_t start = (x_sw > y_sw) ? x_sw : y_sw;
  ------------------
  |  Branch (212:25): [True: 2, False: 3]
  ------------------
  213|      5|   const size_t end = (x_size < y_size) ? x_size : y_size;
  ------------------
  |  Branch (213:23): [True: 5, False: 0]
  ------------------
  214|       |
  215|      5|   if(start == end) {
  ------------------
  |  Branch (215:7): [True: 0, False: 5]
  ------------------
  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|      8|   for(size_t j = start; j <= end; ++j) {
  ------------------
  |  Branch (222:26): [True: 8, False: 0]
  ------------------
  223|      8|      if(j % 2 != 0) {
  ------------------
  |  Branch (223:10): [True: 3, False: 5]
  ------------------
  224|      3|         continue;
  225|      3|      }
  226|       |
  227|      5|      if(2 * j > z_size) {
  ------------------
  |  Branch (227:10): [True: 0, False: 5]
  ------------------
  228|      0|         return 0;
  229|      0|      }
  230|       |
  231|      5|      if(x_sw <= j && j <= x_size && y_sw <= j && j <= y_size) {
  ------------------
  |  Branch (231:10): [True: 5, False: 0]
  |  Branch (231:23): [True: 5, False: 0]
  |  Branch (231:38): [True: 5, False: 0]
  |  Branch (231:51): [True: 5, False: 0]
  ------------------
  232|      5|         if(j % 4 == 2 && (j + 2) <= x_size && (j + 2) <= y_size && 2 * (j + 2) <= z_size) {
  ------------------
  |  Branch (232:13): [True: 3, False: 2]
  |  Branch (232:27): [True: 3, False: 0]
  |  Branch (232:48): [True: 3, False: 0]
  |  Branch (232:69): [True: 3, False: 0]
  ------------------
  233|      3|            return j + 2;
  234|      3|         }
  235|      2|         return j;
  236|      5|      }
  237|      5|   }
  238|       |
  239|      0|   return 0;
  240|      5|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_113karatsuba_mulEPmPKmS3_mS1_:
   80|     20|void karatsuba_mul(word z[], const word x[], const word y[], size_t N, word workspace[]) {
   81|     20|   if(N < KARATSUBA_MULTIPLY_THRESHOLD || N % 2 != 0) {
  ------------------
  |  Branch (81:7): [True: 15, False: 5]
  |  Branch (81:43): [True: 0, False: 5]
  ------------------
   82|     15|      switch(N) {
   83|      0|         case 6:
  ------------------
  |  Branch (83:10): [True: 0, False: 15]
  ------------------
   84|      0|            return bigint_comba_mul6(z, x, y);
   85|      0|         case 8:
  ------------------
  |  Branch (85:10): [True: 0, False: 15]
  ------------------
   86|      0|            return bigint_comba_mul8(z, x, y);
   87|      0|         case 9:
  ------------------
  |  Branch (87:10): [True: 0, False: 15]
  ------------------
   88|      0|            return bigint_comba_mul9(z, x, y);
   89|      6|         case 16:
  ------------------
  |  Branch (89:10): [True: 6, False: 9]
  ------------------
   90|      6|            return bigint_comba_mul16(z, x, y);
   91|      0|         case 24:
  ------------------
  |  Branch (91:10): [True: 0, False: 15]
  ------------------
   92|      0|            return bigint_comba_mul24(z, x, y);
   93|      9|         default:
  ------------------
  |  Branch (93:10): [True: 9, False: 6]
  ------------------
   94|      9|            return basecase_mul(z, 2 * N, x, N, y, N);
   95|     15|      }
   96|     15|   }
   97|       |
   98|      5|   const size_t N2 = N / 2;
   99|       |
  100|      5|   const word* x0 = x;
  101|      5|   const word* x1 = x + N2;
  102|      5|   const word* y0 = y;
  103|      5|   const word* y1 = y + N2;
  104|      5|   word* z0 = z;
  105|      5|   word* z1 = z + N;
  106|       |
  107|      5|   word* ws0 = workspace;
  108|      5|   word* ws1 = workspace + N;
  109|       |
  110|      5|   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|      5|   const auto cmp0 = bigint_sub_abs(z0, x0, x1, N2, workspace);
  123|      5|   const auto cmp1 = bigint_sub_abs(z1, y1, y0, N2, workspace);
  124|      5|   const auto neg_mask = ~(cmp0 ^ cmp1);
  125|       |
  126|      5|   karatsuba_mul(ws0, z0, z1, N2, ws1);
  127|       |
  128|       |   // Compute X_lo * Y_lo
  129|      5|   karatsuba_mul(z0, x0, y0, N2, ws1);
  130|       |
  131|       |   // Compute X_hi * Y_hi
  132|      5|   karatsuba_mul(z1, x1, y1, N2, ws1);
  133|       |
  134|      5|   const word ws_carry = bigint_add3(ws1, z0, N, z1, N);
  135|      5|   word z_carry = bigint_add2(z + N2, N, ws1, N);
  136|       |
  137|      5|   z_carry += bigint_add2(z + N + N2, N2, &ws_carry, 1);
  138|      5|   bigint_add2(z + N + N2, N2, &z_carry, 1);
  139|       |
  140|      5|   zeroize_buffer(workspace + N, N2);
  141|       |
  142|      5|   bigint_cnd_add(neg_mask.value(), z + N2, workspace, 2 * N - N2);
  143|      5|   bigint_cnd_sub((~neg_mask).value(), z + N2, workspace, 2 * N - N2);
  144|      5|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm4EEEbmmmmm:
  272|    242|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|    242|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 73, False: 169]
  |  Branch (273:26): [True: 73, False: 0]
  |  Branch (273:42): [True: 31, False: 42]
  |  Branch (273:56): [True: 31, False: 0]
  |  Branch (273:72): [True: 31, False: 0]
  ------------------
  274|    242|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm6EEEbmmmmm:
  272|    211|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|    211|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 62, False: 149]
  |  Branch (273:26): [True: 62, False: 0]
  |  Branch (273:42): [True: 20, False: 42]
  |  Branch (273:56): [True: 20, False: 0]
  |  Branch (273:72): [True: 20, False: 0]
  ------------------
  274|    211|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm8EEEbmmmmm:
  272|    191|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|    191|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 69, False: 122]
  |  Branch (273:26): [True: 69, False: 0]
  |  Branch (273:42): [True: 20, False: 49]
  |  Branch (273:56): [True: 20, False: 0]
  |  Branch (273:72): [True: 20, False: 0]
  ------------------
  274|    191|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm9EEEbmmmmm:
  272|    171|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|    171|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 56, False: 115]
  |  Branch (273:26): [True: 19, False: 37]
  |  Branch (273:42): [True: 9, False: 10]
  |  Branch (273:56): [True: 9, False: 0]
  |  Branch (273:72): [True: 9, False: 0]
  ------------------
  274|    171|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm16EEEbmmmmm:
  272|    162|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|    162|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 75, False: 87]
  |  Branch (273:26): [True: 38, False: 37]
  |  Branch (273:42): [True: 22, False: 16]
  |  Branch (273:56): [True: 22, False: 0]
  |  Branch (273:72): [True: 22, False: 0]
  ------------------
  274|    162|}
mp_karat.cpp:_ZN5Botan12_GLOBAL__N_119sized_for_comba_mulILm24EEEbmmmmm:
  272|    140|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|    140|   return (x_sw <= SZ && x_size >= SZ && y_sw <= SZ && y_size >= SZ && z_size >= 2 * SZ);
  ------------------
  |  Branch (273:12): [True: 76, False: 64]
  |  Branch (273:26): [True: 30, False: 46]
  |  Branch (273:42): [True: 24, False: 6]
  |  Branch (273:56): [True: 24, False: 0]
  |  Branch (273:72): [True: 24, False: 0]
  ------------------
  274|    140|}

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

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

