_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEmEET_S2_:
   28|   373M|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|   373M|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|   373M|   return static_cast<T>(0) - top;
   31|   373M|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEmEET_S2_:
   37|   323M|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|   323M|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|   323M|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEmEET_S2_S2_S2_:
  217|   191M|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  218|       |   //return (mask & a) | (~mask & b);
  219|   191M|   return (b ^ (mask & (a ^ b)));
  220|   191M|}
_ZN5Botan17ct_if_is_zero_retITkNSt3__117unsigned_integralEmEEmT_m:
   45|   238M|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|   238M|   const T a = ~x & (x - 1);
   51|   238M|   const size_t a_top = static_cast<size_t>(CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1)));
   52|   238M|   const size_t mask = static_cast<size_t>(0) - a_top;
   53|   238M|   return mask & s;
   54|   238M|}
_ZN5Botan8high_bitITkNSt3__117unsigned_integralEmEEmT_:
   73|  6.78k|BOTAN_FORCE_INLINE constexpr size_t high_bit(T n) {
   74|  6.78k|   size_t hb = 0;
   75|       |
   76|  47.5k|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (76:38): [True: 40.7k, False: 6.78k]
  ------------------
   77|       |      // Equivalent to: ((n >> s) == 0) ? 0 : s;
   78|  40.7k|      const size_t z = s - ct_if_is_zero_ret<T>(n >> s, s);
   79|  40.7k|      hb += z;
   80|  40.7k|      n >>= z;
   81|  40.7k|   }
   82|       |
   83|  6.78k|   hb += static_cast<size_t>(n);
   84|       |
   85|  6.78k|   return hb;
   86|  6.78k|}
_ZN5Botan13ceil_divisionITkNSt3__117unsigned_integralEmEET_S2_S2_:
  167|  6.54k|BOTAN_FORCE_INLINE constexpr T ceil_division(T a, T b) {
  168|       |   // Same as `(a + b - 1) / b` but avoids possible overflow
  169|  6.54k|   return a / b + ((a % b != 0) ? 1 : 0);
  ------------------
  |  Branch (169:20): [True: 6.18k, False: 367]
  ------------------
  170|  6.54k|}
_ZN5Botan10ct_is_zeroITkNSt3__117unsigned_integralEhEET_S2_:
   37|   884k|BOTAN_FORCE_INLINE constexpr T ct_is_zero(T x) {
   38|   884k|   return ct_expand_top_bit<T>(~x & (x - 1));
   39|   884k|}
_ZN5Botan17ct_expand_top_bitITkNSt3__117unsigned_integralEhEET_S2_:
   28|   884k|BOTAN_FORCE_INLINE constexpr T ct_expand_top_bit(T a) {
   29|   884k|   const T top = CT::value_barrier<T>(a >> (sizeof(T) * 8 - 1));
   30|   884k|   return static_cast<T>(0) - top;
   31|   884k|}
_ZN5Botan6chooseITkNSt3__117unsigned_integralEhEET_S2_S2_S2_:
  217|   884k|BOTAN_FORCE_INLINE constexpr T choose(T mask, T a, T b) {
  218|       |   //return (mask & a) | (~mask & b);
  219|   884k|   return (b ^ (mask & (a ^ b)));
  220|   884k|}
_ZN5Botan3ctzITkNSt3__117unsigned_integralEmEEmT_:
  115|  33.9M|BOTAN_FORCE_INLINE constexpr size_t ctz(T n) {
  116|       |   /*
  117|       |   * If n == 0 then this function will compute 8*sizeof(T)-1, so
  118|       |   * initialize lb to 1 if n == 0 to produce the expected result.
  119|       |   */
  120|  33.9M|   size_t lb = ct_if_is_zero_ret<T>(n, 1);
  121|       |
  122|   237M|   for(size_t s = 8 * sizeof(T) / 2; s > 0; s /= 2) {
  ------------------
  |  Branch (122:38): [True: 203M, False: 33.9M]
  ------------------
  123|   203M|      const T range = (static_cast<T>(1) << s) - 1;
  124|       |      // Equivalent to: ((n & range) == 0) ? s : 0;
  125|   203M|      const size_t z = ct_if_is_zero_ret<T>(n & range, s);
  126|   203M|      lb += z;
  127|   203M|      n >>= z;
  128|   203M|   }
  129|       |
  130|  33.9M|   return lb;
  131|  33.9M|}

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

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

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

_ZN5Botan2CT4MaskImE5is_gtEmm:
  458|  20.5k|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskImE5is_ltEmm:
  450|  50.0M|      static constexpr Mask<T> is_lt(T x, T y) {
  451|  50.0M|         T u = x ^ ((x ^ y) | ((x - y) ^ x));
  452|  50.0M|         return Mask<T>::expand_top_bit(u);
  453|  50.0M|      }
_ZN5Botan2CT4MaskImE14expand_top_bitEm:
  415|  50.1M|      static constexpr Mask<T> expand_top_bit(T v) { return Mask<T>(ct_expand_top_bit<T>(v)); }
_ZN5Botan2CT4MaskImEC2Em:
  637|   198M|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskImE13if_set_returnEm:
  538|   213M|      constexpr T if_set_return(T x) const { return value() & x; }
_ZNK5Botan2CT4MaskImE5valueEv:
  630|   528M|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZN5Botan2CT4MaskImE6is_gteEmm:
  468|   109k|      static constexpr Mask<T> is_gte(T x, T y) { return ~Mask<T>::is_lt(x, y); }
_ZNK5Botan2CT4MaskImEcoEv:
  533|  48.1M|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZN5Botan2CT6Choice9from_maskEm:
  303|  1.76M|      constexpr static Choice from_mask(underlying_type v) { return Choice(v); }
_ZNK5Botan2CT6ChoicentEv:
  309|   883k|      constexpr Choice operator!() const { return Choice(~value()); }
_ZNK5Botan2CT6ChoiceaaERKS1_:
  311|   883k|      constexpr Choice operator&&(const Choice& other) const { return Choice(value() & other.value()); }
_ZNK5Botan2CT6Choice7as_boolEv:
  329|   883k|      constexpr bool as_bool() const { return m_value != 0; }
_ZNK5Botan2CT6Choice5valueEv:
  332|  2.65M|      constexpr underlying_type value() const { return value_barrier(m_value); }
_ZN5Botan2CT6ChoiceC2Em:
  341|  3.53M|      constexpr explicit Choice(underlying_type v) : m_value(CT::value_barrier<underlying_type>(v)) {}
_ZN5Botan2CT4MaskImE7is_zeroEm:
  437|  99.2M|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT4MaskImE6expandEm:
  392|  48.0M|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZNK5Botan2CT4MaskImE6selectEmm:
  548|   191M|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT8unpoisonImEEvPKT_m:
   67|  11.7M|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|  11.7M|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  151|  11.7M|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   75|  11.7M|}
_ZN5Botan2CT8unpoisonITkNSt3__18integralEmEEvRKT_:
  112|  10.7M|constexpr void unpoison(const T& p) {
  113|  10.7M|   unpoison(&p, 1);
  114|  10.7M|}
_ZNK5Botan2CT4MaskImE16unpoisoned_valueEv:
  598|  1.77M|      constexpr T unpoisoned_value() const {
  599|  1.77M|         T r = value();
  600|  1.77M|         CT::unpoison(r);
  601|  1.77M|         return r;
  602|  1.77M|      }
_ZNK5Botan2CT4MaskImE9as_choiceEv:
  619|  1.76M|      constexpr CT::Choice as_choice() const {
  620|  1.76M|         if constexpr(sizeof(T) >= sizeof(Choice::underlying_type)) {
  621|  1.76M|            return CT::Choice::from_mask(static_cast<Choice::underlying_type>(unpoisoned_value()));
  622|       |         } else {
  623|       |            return CT::Choice::from_int(unpoisoned_value());
  624|       |         }
  625|  1.76M|      }
_ZN5Botan2CTorENS0_4MaskImEES2_:
  528|   112k|      friend constexpr Mask<T> operator|(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() | y.value()); }
_ZN5Botan2CT4MaskImE8is_equalEmm:
  442|  50.8M|      static constexpr Mask<T> is_equal(T x, T y) {
  443|  50.8M|         const T diff = value_barrier(x) ^ value_barrier(y);
  444|  50.8M|         return Mask<T>::is_zero(diff);
  445|  50.8M|      }
_ZN5Botan2CT20conditional_copy_memImEENS0_4MaskIT_EES3_PS3_PKS3_S7_m:
  738|    152|constexpr inline Mask<T> conditional_copy_mem(T cnd, T* dest, const T* if_set, const T* if_unset, size_t elems) {
  739|    152|   const auto mask = CT::Mask<T>::expand(cnd);
  740|    152|   return CT::conditional_copy_mem(mask, dest, if_set, if_unset, elems);
  741|    152|}
_ZN5Botan2CT20conditional_copy_memImEENS0_4MaskIT_EES4_PS3_PKS3_S7_m:
  732|    152|constexpr inline Mask<T> conditional_copy_mem(Mask<T> mask, T* dest, const T* if_set, const T* if_unset, size_t elems) {
  733|    152|   mask.select_n(dest, if_set, if_unset, elems);
  734|    152|   return mask;
  735|    152|}
_ZNK5Botan2CT4MaskImE8select_nEPmPKmS5_m:
  565|    152|      constexpr void select_n(T output[], const T x[], const T y[], size_t len) const {
  566|    152|         const T mask = value();
  567|  3.27k|         for(size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (567:28): [True: 3.12k, False: 152]
  ------------------
  568|  3.12k|            output[i] = choose(mask, x[i], y[i]);
  569|  3.12k|         }
  570|    152|      }
_ZNK5Botan2CT4MaskImE7as_boolEv:
  614|  7.64k|      constexpr bool as_bool() const { return unpoisoned_value() != 0; }
_ZNK5Botan2CT4MaskImE11select_maskES2_S2_:
  559|  34.4k|      Mask<T> select_mask(Mask<T> x, Mask<T> y) const { return Mask<T>(select(x.value(), y.value())); }
_ZN5Botan2CT4MaskImEoRES2_:
  510|  33.9M|      Mask<T>& operator|=(Mask<T> o) {
  511|  33.9M|         m_mask |= o.value();
  512|  33.9M|         return (*this);
  513|  33.9M|      }
_ZN5Botan2CT4MaskImEaNES2_:
  494|  6.75k|      Mask<T>& operator&=(Mask<T> o) {
  495|  6.75k|         m_mask &= o.value();
  496|  6.75k|         return (*this);
  497|  6.75k|      }
_ZN5Botan2CT4MaskImE11expand_boolEb:
  397|   883k|      static constexpr Mask<T> expand_bool(bool v) { return Mask<T>::expand(static_cast<T>(v)); }
_ZN5Botan2CT4MaskIhE11expand_boolEb:
  397|   884k|      static constexpr Mask<T> expand_bool(bool v) { return Mask<T>::expand(static_cast<T>(v)); }
_ZN5Botan2CT4MaskIhE6expandEh:
  392|   884k|      static constexpr Mask<T> expand(T v) { return ~Mask<T>::is_zero(value_barrier<T>(v)); }
_ZN5Botan2CT4MaskIhE7is_zeroEh:
  437|   884k|      static constexpr Mask<T> is_zero(T x) { return Mask<T>(ct_is_zero<T>(value_barrier<T>(x))); }
_ZN5Botan2CT4MaskIhEC2Eh:
  637|  1.76M|      constexpr explicit Mask(T m) : m_mask(m) {}
_ZNK5Botan2CT4MaskIhEcoEv:
  533|   884k|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskIhE5valueEv:
  630|  1.76M|      constexpr T value() const { return value_barrier<T>(m_mask); }
_ZNK5Botan2CT4MaskIhE6selectEhh:
  548|   884k|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT6poisonImEEvPKT_m:
   56|  1.87k|constexpr inline void poison(const T* p, size_t n) {
   57|       |#if defined(BOTAN_HAS_VALGRIND)
   58|       |   if(!std::is_constant_evaluated()) {
   59|       |      VALGRIND_MAKE_MEM_UNDEFINED(p, n * sizeof(T));
   60|       |   }
   61|       |#endif
   62|       |
   63|  1.87k|   BOTAN_UNUSED(p, n);
  ------------------
  |  |  151|  1.87k|#define BOTAN_UNUSED Botan::ignore_params
  ------------------
   64|  1.87k|}
_ZN5Botan2CTanENS0_4MaskImEES2_:
  518|  9.35k|      friend constexpr Mask<T> operator&(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() & y.value()); }
_ZN5Botan2CTeoENS0_4MaskImEES2_:
  523|     76|      friend constexpr Mask<T> operator^(Mask<T> x, Mask<T> y) { return Mask<T>(x.value() ^ y.value()); }
_ZN5Botan2CT9all_zerosImEENS0_4MaskIT_EEPKS3_m:
  785|  1.87k|constexpr inline CT::Mask<T> all_zeros(const T elem[], size_t len) {
  786|  1.87k|   T sum = 0;
  787|  10.4k|   for(size_t i = 0; i != len; ++i) {
  ------------------
  |  Branch (787:22): [True: 8.61k, False: 1.87k]
  ------------------
  788|  8.61k|      sum |= elem[i];
  789|  8.61k|   }
  790|  1.87k|   return CT::Mask<T>::is_zero(sum);
  791|  1.87k|}
_ZN5Botan2CT4MaskImE15if_set_zero_outEPmm:
  575|  1.87k|      constexpr void if_set_zero_out(T buf[], size_t elems) {
  576|  10.4k|         for(size_t i = 0; i != elems; ++i) {
  ------------------
  |  Branch (576:28): [True: 8.61k, False: 1.87k]
  ------------------
  577|  8.61k|            buf[i] = this->if_not_set_return(buf[i]);
  578|  8.61k|         }
  579|  1.87k|      }
_ZNK5Botan2CT4MaskImE17if_not_set_returnEm:
  543|  34.0M|      constexpr T if_not_set_return(T x) const { return ~value() & x; }
_ZN5Botan2CT8unpoisonITkNS0_19custom_unpoisonableENS_6BigIntEEEvRKT_:
  143|  2.63k|constexpr void unpoison(const T& x) {
  144|  2.63k|   x._const_time_unpoison();
  145|  2.63k|}
_ZN5Botan2CT4MaskImE7clearedEv:
  387|   945k|      static constexpr Mask<T> cleared() { return Mask<T>(0); }

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

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

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

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

_ZNK5Botan14divide_precompImE14divmod_2to1_ctEmm:
  731|  6.47k|      inline constexpr std::pair<W, W> divmod_2to1_ct(W n1, W n0) const {
  732|       |         /*
  733|       |         * Scale the numerator to match the normalized divisor; the scaling cancels
  734|       |         * in the quotient and is removed from the remainder by the final shift.
  735|       |         */
  736|  6.47k|         n1 <<= m_shift;
  737|  6.47k|         const size_t rshift = WordInfo<W>::bits - m_shift;
  738|       |         /*
  739|       |         * We can't just `n0 >> rshift` because m_shift may be 0 (high bit divisor)
  740|       |         * in which case rshift will be the maximum bit length, and >> by the maximum
  741|       |         * bitlength is undefined behavior despite having an entirely obvious meaning.
  742|       |         *
  743|       |         * However we know m_shift is not equal to the bit length of the word, because
  744|       |         * that would imply that the divisor is 0. Thus rshift must be >= 1. So split
  745|       |         * the shift into two phases (first rshift-1, then 1)
  746|       |         */
  747|  6.47k|         n1 |= (n0 >> 1) >> (rshift - 1);
  748|  6.47k|         n0 <<= m_shift;
  749|       |
  750|  6.47k|         const auto [q, scaled_r] = div2by1_preinv(n1, n0, m_norm_divisor, m_reciprocal);
  751|  6.47k|         const W r = scaled_r >> m_shift;
  752|  6.47k|         return std::make_pair(q, r);
  753|  6.47k|      }
_ZN5Botan14divide_precompImE14div2by1_preinvEmmmm:
  782|  6.47k|      static constexpr std::pair<W, W> div2by1_preinv(W u1, W u0, W D, W v) {
  783|       |         // Steps 1-3: <q1,q0> = v*u1; <q1,q0> += <u1,u0>; q1 += 1
  784|  6.47k|         W q1 = u0;
  785|  6.47k|         const W q0 = word_madd2(u1, v, &q1);  // <q1,q0> = u1*v + u0
  786|  6.47k|         q1 += u1 + 1;
  787|       |
  788|       |         // Step 4
  789|  6.47k|         W r = u0 - q1 * D;
  790|       |
  791|       |         // Steps 5-7: If r >= q0 { q1 -= 1; r += d; }
  792|  6.47k|         const auto fix_down = CT::Mask<W>::is_gt(r, q0);
  793|  6.47k|         q1 -= fix_down.if_set_return(1);
  794|  6.47k|         r += fix_down.if_set_return(D);
  795|       |
  796|       |         // Steps 8-10: if r >= D { q1 += 1; r -= D; }
  797|  6.47k|         const auto fix_up = CT::Mask<W>::is_gte(r, D);
  798|  6.47k|         q1 += fix_up.if_set_return(1);
  799|  6.47k|         r -= fix_up.if_set_return(D);
  800|       |
  801|       |         // Step 11
  802|  6.47k|         return std::make_pair(q1, r);
  803|  6.47k|      }
_ZN5Botan18reciprocal_word_ctITkNS_8WordTypeEmEET_S1_:
  649|  1.61k|constexpr W reciprocal_word_ct(W D) {
  650|  1.61k|   BOTAN_DEBUG_ASSERT((D & WordInfo<W>::top_bit) != 0);
  ------------------
  |  |  137|  1.61k|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  138|  1.61k|      } while(0)
  |  |  ------------------
  |  |  |  Branch (138:15): [Folded, False: 1.61k]
  |  |  ------------------
  ------------------
  651|       |
  652|       |   // Bit serial long division of ((~D) || (2^b - 1)) / D, with all of the
  653|       |   // conditional logic computed via masks
  654|  1.61k|   W remainder = static_cast<W>(~D);
  655|  1.61k|   W quotient = 0;
  656|       |
  657|   104k|   for(size_t i = 0; i != WordInfo<W>::bits; ++i) {
  ------------------
  |  Branch (657:22): [True: 103k, False: 1.61k]
  ------------------
  658|   103k|      const auto carry = CT::Mask<W>::expand_top_bit(remainder);
  659|   103k|      remainder = static_cast<W>((remainder << 1) | 1);
  660|   103k|      quotient <<= 1;
  661|       |
  662|   103k|      const auto sub = carry | CT::Mask<W>::is_gte(remainder, D);
  663|   103k|      remainder -= sub.if_set_return(D);
  664|   103k|      quotient |= sub.if_set_return(1);
  665|   103k|   }
  666|       |
  667|  1.61k|   return quotient;
  668|  1.61k|}
_ZN5Botan14divide_precompImE5setupEm:
  694|  1.61k|      static constexpr divide_precomp setup(W divisor) {
  695|  1.61k|         const size_t shift = WordInfo<W>::bits - high_bit(divisor);
  696|  1.61k|         const W norm_divisor = divisor << shift;
  697|  1.61k|         const W reciprocal = reciprocal_word_ct(norm_divisor);
  698|  1.61k|         return divide_precomp(divisor, shift, norm_divisor, reciprocal);
  699|  1.61k|      }
_ZN5Botan11bigint_add2ITkNS_8WordTypeEmEET_PS1_mPKS1_m:
   97|  1.45M|inline constexpr auto bigint_add2(W x[], size_t x_size, const W y[], size_t y_size) -> W {
   98|  1.45M|   W carry = 0;
   99|       |
  100|  1.45M|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   71|  1.45M|   do {                                                                                 \
  |  |   72|  1.45M|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|  1.45M|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 1.45M]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|  1.45M|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 1.45M]
  |  |  ------------------
  ------------------
  101|       |
  102|  1.45M|   const size_t blocks = y_size - (y_size % 8);
  103|       |
  104|  6.40M|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (104:22): [True: 4.95M, False: 1.45M]
  ------------------
  105|  4.95M|      carry = word8_add2(x + i, y + i, carry);
  106|  4.95M|   }
  107|       |
  108|  5.94M|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (108:27): [True: 4.49M, False: 1.45M]
  ------------------
  109|  4.49M|      x[i] = word_add(x[i], y[i], &carry);
  110|  4.49M|   }
  111|       |
  112|  9.38M|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (112:27): [True: 7.93M, False: 1.45M]
  ------------------
  113|  7.93M|      x[i] = word_add(x[i], static_cast<W>(0), &carry);
  114|  7.93M|   }
  115|       |
  116|  1.45M|   return carry;
  117|  1.45M|}
_ZN5Botan10bigint_cmpITkNS_8WordTypeEmEEiPKT_mS3_m:
  462|  1.88M|inline constexpr int32_t bigint_cmp(const W x[], size_t x_size, const W y[], size_t y_size) {
  463|  1.88M|   static_assert(sizeof(W) >= sizeof(uint32_t), "Size assumption");
  464|       |
  465|  1.88M|   const W LT = static_cast<W>(-1);
  466|  1.88M|   const W EQ = 0;
  467|  1.88M|   const W GT = 1;
  468|       |
  469|  1.88M|   const size_t common_elems = std::min(x_size, y_size);
  470|       |
  471|  1.88M|   W result = EQ;  // until found otherwise
  472|       |
  473|  51.7M|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (473:22): [True: 49.9M, False: 1.88M]
  ------------------
  474|  49.9M|      const auto is_eq = CT::Mask<W>::is_equal(x[i], y[i]);
  475|  49.9M|      const auto is_lt = CT::Mask<W>::is_lt(x[i], y[i]);
  476|       |
  477|  49.9M|      result = is_eq.select(result, is_lt.select(LT, GT));
  478|  49.9M|   }
  479|       |
  480|  1.88M|   if(x_size < y_size) {
  ------------------
  |  Branch (480:7): [True: 114k, False: 1.77M]
  ------------------
  481|   114k|      W mask = 0;
  482|   541k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (482:30): [True: 427k, False: 114k]
  ------------------
  483|   427k|         mask |= y[i];
  484|   427k|      }
  485|       |
  486|       |      // If any bits were set in high part of y, then x < y
  487|   114k|      result = CT::Mask<W>::is_zero(mask).select(result, LT);
  488|  1.77M|   } else if(y_size < x_size) {
  ------------------
  |  Branch (488:14): [True: 295k, False: 1.47M]
  ------------------
  489|   295k|      W mask = 0;
  490|  3.29M|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (490:30): [True: 3.00M, False: 295k]
  ------------------
  491|  3.00M|         mask |= x[i];
  492|  3.00M|      }
  493|       |
  494|       |      // If any bits were set in high part of x, then x > y
  495|   295k|      result = CT::Mask<W>::is_zero(mask).select(result, GT);
  496|   295k|   }
  497|       |
  498|  1.88M|   CT::unpoison(result);
  499|  1.88M|   BOTAN_DEBUG_ASSERT(result == LT || result == GT || result == EQ);
  ------------------
  |  |  137|  1.88M|      do { /* NOLINT(*-avoid-do-while) */ \
  |  |  138|  1.88M|      } while(0)
  |  |  ------------------
  |  |  |  Branch (138:15): [Folded, False: 1.88M]
  |  |  ------------------
  ------------------
  500|  1.88M|   return static_cast<int32_t>(result);
  501|  1.88M|}
_ZN5Botan11bigint_sub2ITkNS_8WordTypeEmEET_PS1_mPKS1_m:
  151|   810k|inline constexpr auto bigint_sub2(W x[], size_t x_size, const W y[], size_t y_size) -> W {
  152|   810k|   W borrow = 0;
  153|       |
  154|   810k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   71|   810k|   do {                                                                                 \
  |  |   72|   810k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|   810k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 810k]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|   810k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 810k]
  |  |  ------------------
  ------------------
  155|       |
  156|   810k|   const size_t blocks = y_size - (y_size % 8);
  157|       |
  158|  2.39M|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (158:22): [True: 1.58M, False: 810k]
  ------------------
  159|  1.58M|      borrow = word8_sub2(x + i, y + i, borrow);
  160|  1.58M|   }
  161|       |
  162|  3.01M|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (162:27): [True: 2.20M, False: 810k]
  ------------------
  163|  2.20M|      x[i] = word_sub(x[i], y[i], &borrow);
  164|  2.20M|   }
  165|       |
  166|  3.60M|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (166:27): [True: 2.79M, False: 810k]
  ------------------
  167|  2.79M|      x[i] = word_sub(x[i], static_cast<W>(0), &borrow);
  168|  2.79M|   }
  169|       |
  170|   810k|   return borrow;
  171|   810k|}
_ZN5Botan15bigint_sub2_revITkNS_8WordTypeEmEEvPT_PKS1_m:
  177|   533k|inline constexpr void bigint_sub2_rev(W x[], const W y[], size_t y_size) {
  178|   533k|   W borrow = 0;
  179|       |
  180|  18.6M|   for(size_t i = 0; i != y_size; ++i) {
  ------------------
  |  Branch (180:22): [True: 18.1M, False: 533k]
  ------------------
  181|  18.1M|      x[i] = word_sub(y[i], x[i], &borrow);
  182|  18.1M|   }
  183|       |
  184|   533k|   BOTAN_ASSERT(borrow == 0, "y must be greater than x");
  ------------------
  |  |   71|   533k|   do {                                                                                 \
  |  |   72|   533k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|   533k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 533k]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|   533k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 533k]
  |  |  ------------------
  ------------------
  185|   533k|}
_ZN5Botan11bigint_sub3ITkNS_8WordTypeEmEET_PS1_PKS1_mS4_m:
  195|  58.6k|inline constexpr auto bigint_sub3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W {
  196|  58.6k|   W borrow = 0;
  197|       |
  198|  58.6k|   BOTAN_ASSERT(x_size >= y_size, "Expected sizes");
  ------------------
  |  |   71|  58.6k|   do {                                                                                 \
  |  |   72|  58.6k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|  58.6k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 58.6k]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|  58.6k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 58.6k]
  |  |  ------------------
  ------------------
  199|       |
  200|  58.6k|   const size_t blocks = y_size - (y_size % 8);
  201|       |
  202|  59.2k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (202:22): [True: 579, False: 58.6k]
  ------------------
  203|    579|      borrow = word8_sub3(z + i, x + i, y + i, borrow);
  204|    579|   }
  205|       |
  206|  64.2k|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (206:27): [True: 5.61k, False: 58.6k]
  ------------------
  207|  5.61k|      z[i] = word_sub(x[i], y[i], &borrow);
  208|  5.61k|   }
  209|       |
  210|   125k|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (210:27): [True: 66.7k, False: 58.6k]
  ------------------
  211|  66.7k|      z[i] = word_sub(x[i], static_cast<W>(0), &borrow);
  212|  66.7k|   }
  213|       |
  214|  58.6k|   return borrow;
  215|  58.6k|}
_ZN5Botan11bigint_add3ITkNS_8WordTypeEmEET_PS1_PKS1_mS4_m:
  123|   917k|inline constexpr auto bigint_add3(W z[], const W x[], size_t x_size, const W y[], size_t y_size) -> W {
  124|   917k|   if(x_size < y_size) {
  ------------------
  |  Branch (124:7): [True: 91.8k, False: 825k]
  ------------------
  125|  91.8k|      return bigint_add3(z, y, y_size, x, x_size);
  126|  91.8k|   }
  127|       |
  128|   825k|   W carry = 0;
  129|       |
  130|   825k|   const size_t blocks = y_size - (y_size % 8);
  131|       |
  132|  2.02M|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (132:22): [True: 1.19M, False: 825k]
  ------------------
  133|  1.19M|      carry = word8_add3(z + i, x + i, y + i, carry);
  134|  1.19M|   }
  135|       |
  136|  2.98M|   for(size_t i = blocks; i != y_size; ++i) {
  ------------------
  |  Branch (136:27): [True: 2.15M, False: 825k]
  ------------------
  137|  2.15M|      z[i] = word_add(x[i], y[i], &carry);
  138|  2.15M|   }
  139|       |
  140|  1.12M|   for(size_t i = y_size; i != x_size; ++i) {
  ------------------
  |  Branch (140:27): [True: 302k, False: 825k]
  ------------------
  141|   302k|      z[i] = word_add(x[i], static_cast<W>(0), &carry);
  142|   302k|   }
  143|       |
  144|   825k|   return carry;
  145|   917k|}
_ZN5Botan14bigint_cnd_addITkNS_8WordTypeEmEET_S1_PS1_PKS1_m:
   48|  2.87M|inline constexpr W bigint_cnd_add(W cnd, W x[], const W y[], size_t size) {
   49|  2.87M|   const auto mask = CT::Mask<W>::expand(cnd).value();
   50|       |
   51|  2.87M|   W carry = 0;
   52|       |
   53|  75.7M|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (53:22): [True: 72.8M, False: 2.87M]
  ------------------
   54|  72.8M|      x[i] = word_add(x[i], y[i] & mask, &carry);
   55|  72.8M|   }
   56|       |
   57|  2.87M|   return (mask & carry);
   58|  2.87M|}
_ZN5Botan14bigint_linmul3ITkNS_8WordTypeEmEEvPT_PKS1_mS1_:
  419|  1.43k|inline constexpr void bigint_linmul3(W z[], const W x[], size_t x_size, W y) {
  420|  1.43k|   const size_t blocks = x_size - (x_size % 8);
  421|       |
  422|  1.43k|   W carry = 0;
  423|       |
  424|  2.06k|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (424:22): [True: 630, False: 1.43k]
  ------------------
  425|    630|      carry = word8_linmul3(z + i, x + i, y, carry);
  426|    630|   }
  427|       |
  428|  4.41k|   for(size_t i = blocks; i != x_size; ++i) {
  ------------------
  |  Branch (428:27): [True: 2.97k, False: 1.43k]
  ------------------
  429|  2.97k|      z[i] = word_madd2(x[i], y, &carry);
  430|  2.97k|   }
  431|       |
  432|  1.43k|   z[x_size] = carry;
  433|  1.43k|}
_ZN5Botan14divide_precompImEC2Emmmm:
  771|  1.61k|            m_divisor(divisor), m_shift(shift), m_norm_divisor(norm_divisor), m_reciprocal(reciprocal) {}
_ZN5Botan11bigint_shr1ITkNS_8WordTypeEmEEvPT_mm:
  334|  6.43M|inline constexpr void bigint_shr1(W x[], size_t x_size, size_t shift) {
  335|  6.43M|   const size_t word_shift = shift / WordInfo<W>::bits;
  336|  6.43M|   const size_t bit_shift = shift % WordInfo<W>::bits;
  337|       |
  338|  6.43M|   const size_t top = x_size >= word_shift ? (x_size - word_shift) : 0;
  ------------------
  |  Branch (338:23): [True: 6.43M, False: 0]
  ------------------
  339|       |
  340|  6.43M|   if(top > 0) {
  ------------------
  |  Branch (340:7): [True: 6.43M, False: 0]
  ------------------
  341|  6.43M|      unchecked_copy_memory(x, x + word_shift, top);
  342|  6.43M|   }
  343|  6.43M|   zeroize_buffer(x + top, std::min(word_shift, x_size));
  344|       |
  345|  6.43M|   const auto carry_mask = CT::Mask<W>::expand(bit_shift);
  346|  6.43M|   const W carry_shift = carry_mask.if_set_return(WordInfo<W>::bits - bit_shift);
  347|       |
  348|  6.43M|   W carry = 0;
  349|       |
  350|   211M|   for(size_t i = 0; i != top; ++i) {
  ------------------
  |  Branch (350:22): [True: 204M, False: 6.43M]
  ------------------
  351|   204M|      const W w = x[top - i - 1];
  352|   204M|      x[top - i - 1] = (w >> bit_shift) | carry;
  353|   204M|      carry = carry_mask.if_set_return(w << carry_shift);
  354|   204M|   }
  355|  6.43M|}
_ZN5Botan11bigint_shr2ITkNS_8WordTypeEmEEvPT_mPKS1_mm:
  381|  1.63k|inline constexpr void bigint_shr2(W y[], size_t y_size, const W x[], size_t x_size, size_t shift) {
  382|  1.63k|   const size_t word_shift = shift / WordInfo<W>::bits;
  383|  1.63k|   const size_t bit_shift = shift % WordInfo<W>::bits;
  384|  1.63k|   const size_t new_size = x_size < word_shift ? 0 : (x_size - word_shift);
  ------------------
  |  Branch (384:28): [True: 0, False: 1.63k]
  ------------------
  385|       |
  386|  1.63k|   BOTAN_ASSERT_NOMSG(new_size <= y_size);
  ------------------
  |  |   84|  1.63k|   do {                                                                     \
  |  |   85|  1.63k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.63k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.63k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.63k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.63k]
  |  |  ------------------
  ------------------
  387|       |
  388|  1.63k|   if(new_size > 0) {
  ------------------
  |  Branch (388:7): [True: 1.63k, False: 0]
  ------------------
  389|  1.63k|      unchecked_copy_memory(y, x + word_shift, new_size);
  390|  1.63k|   }
  391|  1.63k|   zeroize_buffer(y + new_size, y_size - new_size);
  392|       |
  393|  1.63k|   const auto carry_mask = CT::Mask<W>::expand(bit_shift);
  394|  1.63k|   const W carry_shift = carry_mask.if_set_return(WordInfo<W>::bits - bit_shift);
  395|       |
  396|  1.63k|   W carry = 0;
  397|  9.30k|   for(size_t i = new_size; i > 0; --i) {
  ------------------
  |  Branch (397:29): [True: 7.67k, False: 1.63k]
  ------------------
  398|  7.67k|      W w = y[i - 1];
  399|  7.67k|      y[i - 1] = (w >> bit_shift) | carry;
  400|  7.67k|      carry = carry_mask.if_set_return(w << carry_shift);
  401|  7.67k|   }
  402|  1.63k|}
_ZN5Botan15bigint_ct_is_eqITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPKS3_mS6_m:
  542|  1.95k|inline constexpr auto bigint_ct_is_eq(const W x[], size_t x_size, const W y[], size_t y_size) -> CT::Mask<W> {
  543|  1.95k|   const size_t common_elems = std::min(x_size, y_size);
  544|       |
  545|  1.95k|   W diff = 0;
  546|       |
  547|  21.6k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (547:22): [True: 19.6k, False: 1.95k]
  ------------------
  548|  19.6k|      diff |= (x[i] ^ y[i]);
  549|  19.6k|   }
  550|       |
  551|       |   // If any bits were set in high part of x/y, then they are not equal
  552|  1.95k|   if(x_size < y_size) {
  ------------------
  |  Branch (552:7): [True: 892, False: 1.06k]
  ------------------
  553|  20.6k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (553:30): [True: 19.7k, False: 892]
  ------------------
  554|  19.7k|         diff |= y[i];
  555|  19.7k|      }
  556|  1.06k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (556:14): [True: 513, False: 551]
  ------------------
  557|  2.80k|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (557:30): [True: 2.28k, False: 513]
  ------------------
  558|  2.28k|         diff |= x[i];
  559|  2.28k|      }
  560|    513|   }
  561|       |
  562|  1.95k|   return CT::Mask<W>::is_zero(diff);
  563|  1.95k|}
_ZN5Botan15bigint_ct_is_ltITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPKS3_mS6_mb:
  510|  3.80k|   -> CT::Mask<W> {
  511|  3.80k|   const size_t common_elems = std::min(x_size, y_size);
  512|       |
  513|  3.80k|   auto is_lt = CT::Mask<W>::expand(lt_or_equal);
  514|       |
  515|  38.2k|   for(size_t i = 0; i != common_elems; i++) {
  ------------------
  |  Branch (515:22): [True: 34.4k, False: 3.80k]
  ------------------
  516|  34.4k|      const auto eq = CT::Mask<W>::is_equal(x[i], y[i]);
  517|  34.4k|      const auto lt = CT::Mask<W>::is_lt(x[i], y[i]);
  518|  34.4k|      is_lt = eq.select_mask(is_lt, lt);
  519|  34.4k|   }
  520|       |
  521|  3.80k|   if(x_size < y_size) {
  ------------------
  |  Branch (521:7): [True: 1.73k, False: 2.07k]
  ------------------
  522|  1.73k|      W mask = 0;
  523|  12.9k|      for(size_t i = x_size; i != y_size; i++) {
  ------------------
  |  Branch (523:30): [True: 11.1k, False: 1.73k]
  ------------------
  524|  11.1k|         mask |= y[i];
  525|  11.1k|      }
  526|       |      // If any bits were set in high part of y, then is_lt should be forced true
  527|  1.73k|      is_lt |= CT::Mask<W>::expand(mask);
  528|  2.07k|   } else if(y_size < x_size) {
  ------------------
  |  Branch (528:14): [True: 17, False: 2.05k]
  ------------------
  529|     17|      W mask = 0;
  530|    211|      for(size_t i = y_size; i != x_size; i++) {
  ------------------
  |  Branch (530:30): [True: 194, False: 17]
  ------------------
  531|    194|         mask |= x[i];
  532|    194|      }
  533|       |
  534|       |      // If any bits were set in high part of x, then is_lt should be false
  535|     17|      is_lt &= CT::Mask<W>::is_zero(mask);
  536|     17|   }
  537|       |
  538|  3.80k|   return is_lt;
  539|  3.80k|}
_ZN5Botan15bigint_cnd_swapITkNS_8WordTypeEmEEvT_PS1_S2_m:
   32|   956k|inline constexpr void bigint_cnd_swap(W cnd, W x[], W y[], size_t size) {
   33|   956k|   const auto mask = CT::Mask<W>::expand(cnd);
   34|       |
   35|  25.2M|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (35:22): [True: 24.2M, False: 956k]
  ------------------
   36|  24.2M|      const W a = x[i];
   37|  24.2M|      const W b = y[i];
   38|  24.2M|      x[i] = mask.select(b, a);
   39|  24.2M|      y[i] = mask.select(a, b);
   40|  24.2M|   }
   41|   956k|}
_ZN5Botan13bigint_submulITkNS_8WordTypeEmEET_PS1_PKS1_mS1_:
  442|  2.33k|inline constexpr auto bigint_submul(W z[], const W y[], size_t N, W q) -> W {
  443|  2.33k|   W mul_carry = 0;
  444|  2.33k|   W borrow = 0;
  445|       |
  446|  28.6k|   for(size_t i = 0; i != N; ++i) {
  ------------------
  |  Branch (446:22): [True: 26.3k, False: 2.33k]
  ------------------
  447|  26.3k|      const W t = word_madd2(y[i], q, &mul_carry);
  448|  26.3k|      z[i] = word_sub(z[i], t, &borrow);
  449|  26.3k|   }
  450|       |
  451|       |   // Both mul_carry <= W_max - 1 and borrow <= 1, so this cannot overflow
  452|  2.33k|   return mul_carry + borrow;
  453|  2.33k|}
_ZN5Botan14bigint_sub_absITkNS_8WordTypeEmEENS_2CT4MaskIT_EEPS3_PKS3_S7_mS5_:
  282|    152|inline constexpr auto bigint_sub_abs(W z[], const W x[], const W y[], size_t N, W ws[]) -> CT::Mask<W> {
  283|       |   // Subtract in both direction then conditional copy out the result
  284|       |
  285|    152|   W* ws0 = ws;
  286|    152|   W* ws1 = ws + N;
  287|       |
  288|    152|   W borrow0 = 0;
  289|    152|   W borrow1 = 0;
  290|       |
  291|    152|   const size_t blocks = N - (N % 8);
  292|       |
  293|    516|   for(size_t i = 0; i != blocks; i += 8) {
  ------------------
  |  Branch (293:22): [True: 364, False: 152]
  ------------------
  294|    364|      borrow0 = word8_sub3(ws0 + i, x + i, y + i, borrow0);
  295|    364|      borrow1 = word8_sub3(ws1 + i, y + i, x + i, borrow1);
  296|    364|   }
  297|       |
  298|    360|   for(size_t i = blocks; i != N; ++i) {
  ------------------
  |  Branch (298:27): [True: 208, False: 152]
  ------------------
  299|    208|      ws0[i] = word_sub(x[i], y[i], &borrow0);
  300|    208|      ws1[i] = word_sub(y[i], x[i], &borrow1);
  301|    208|   }
  302|       |
  303|    152|   return CT::conditional_copy_mem(borrow0, z, ws1, ws0, N);
  304|    152|}
_ZN5Botan14bigint_cnd_subITkNS_8WordTypeEmEET_S1_PS1_PKS1_m:
   65|  1.91M|inline constexpr auto bigint_cnd_sub(W cnd, W x[], const W y[], size_t size) -> W {
   66|  1.91M|   const auto mask = CT::Mask<W>::expand(cnd).value();
   67|       |
   68|  1.91M|   W carry = 0;
   69|       |
   70|  50.4M|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (70:22): [True: 48.5M, False: 1.91M]
  ------------------
   71|  48.5M|      x[i] = word_sub(x[i], y[i] & mask, &carry);
   72|  48.5M|   }
   73|       |
   74|  1.91M|   return (mask & carry);
   75|  1.91M|}
_ZN5Botan14bigint_cnd_absITkNS_8WordTypeEmEEvT_PS1_m:
   83|   956k|inline constexpr void bigint_cnd_abs(W cnd, W x[], size_t size) {
   84|   956k|   const auto mask = CT::Mask<W>::expand(cnd);
   85|       |
   86|   956k|   W carry = mask.if_set_return(1);
   87|  25.2M|   for(size_t i = 0; i != size; ++i) {
  ------------------
  |  Branch (87:22): [True: 24.2M, False: 956k]
  ------------------
   88|  24.2M|      const W z = word_add(~x[i], static_cast<W>(0), &carry);
   89|  24.2M|      x[i] = mask.select(z, x[i]);
   90|  24.2M|   }
   91|   956k|}

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

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

_ZN5BotanltERKNS_6BigIntEm:
 1413|  3.90k|inline bool operator<(const BigInt& a, word b) {
 1414|  3.90k|   return (a.cmp_word(b) < 0);
 1415|  3.90k|}
_ZN5BotaneqERKNS_6BigIntEm:
 1373|  4.71k|inline bool operator==(const BigInt& a, word b) {
 1374|  4.71k|   return (a.cmp_word(b) == 0);
 1375|  4.71k|}
_ZNK5Botan6BigInt7is_evenEv:
  481|  9.09k|      bool is_even() const { return !get_bit(0); }
_ZNK5Botan6BigInt7get_bitEm:
  549|  2.92M|      bool get_bit(size_t n) const { return ((word_at(n / (sizeof(word) * 8)) >> (n % (sizeof(word) * 8))) & 1) == 1; }
_ZNK5Botan6BigInt7word_atEm:
  601|  75.4M|      word word_at(size_t n) const { return m_data.get_word_at(n); }
_ZNK5Botan6BigInt4Data11get_word_atEm:
 1099|  75.4M|            word get_word_at(size_t n) const {
 1100|  75.4M|               if(n < m_reg.size()) {
  ------------------
  |  Branch (1100:19): [True: 74.4M, False: 1.00M]
  ------------------
 1101|  74.4M|                  return m_reg[n];
 1102|  74.4M|               }
 1103|  1.00M|               return 0;
 1104|  75.4M|            }
_ZN5Botan6BigIntC2ERKS0_:
   88|  6.93k|      BigInt(const BigInt& other) = default;
_ZNK5Botan6BigInt7is_zeroEv:
  510|  2.45M|      bool is_zero() const { return sig_words() == 0; }
_ZNK5Botan6BigInt9sig_wordsEv:
  687|  16.3M|      size_t sig_words() const { return m_data.sig_words(); }
_ZNK5Botan6BigInt4Data9sig_wordsEv:
 1163|  16.3M|            size_t sig_words() const {
 1164|  16.3M|               if(m_sig_words == sig_words_npos) {
  ------------------
  |  Branch (1164:19): [True: 7.12M, False: 9.21M]
  ------------------
 1165|  7.12M|                  m_sig_words = calc_sig_words();
 1166|  7.12M|               }
 1167|  16.3M|               return m_sig_words;
 1168|  16.3M|            }
_ZNK5Botan6BigInt6is_oddEv:
  487|  2.03M|      bool is_odd() const { return get_bit(0); }
_ZN5BotangeERKNS_6BigIntES2_:
 1343|   478k|inline bool operator>=(const BigInt& a, const BigInt& b) {
 1344|   478k|   return (a.cmp(b) >= 0);
 1345|   478k|}
_ZN5BotanneERKNS_6BigIntEm:
 1383|  1.94k|inline bool operator!=(const BigInt& a, word b) {
 1384|  1.94k|   return (a.cmp_word(b) != 0);
 1385|  1.94k|}
_ZNK5Botan6BigInt6signumEv:
  493|  1.96M|      int signum() const {
  494|  1.96M|         if(sig_words() == 0) {
  ------------------
  |  Branch (494:13): [True: 1.38k, False: 1.96M]
  ------------------
  495|  1.38k|            return 0;
  496|  1.38k|         }
  497|  1.96M|         return (sign() == Negative) ? -1 : 1;
  ------------------
  |  Branch (497:17): [True: 1.85k, False: 1.96M]
  ------------------
  498|  1.96M|      }
_ZNK5Botan6BigInt4signEv:
  641|  12.8M|      Sign sign() const { return (m_signedness); }
_ZN5Botan6BigIntC2EOS0_:
  183|  5.03k|      BigInt(BigInt&& other) noexcept { this->swap(other); }
_ZN5Botan6BigInt4swapERS0_:
  207|   891k|      void swap(BigInt& other) noexcept {
  208|   891k|         m_data.swap(other.m_data);
  209|   891k|         std::swap(m_signedness, other.m_signedness);
  210|   891k|      }
_ZN5Botan6BigInt4Data4swapERS1_:
 1151|   891k|            void swap(Data& other) noexcept {
 1152|   891k|               m_reg.swap(other.m_reg);
 1153|   891k|               std::swap(m_sig_words, other.m_sig_words);
 1154|   891k|            }
_ZN5BotanneERKNS_6BigIntES2_:
 1323|  1.95k|inline bool operator!=(const BigInt& a, const BigInt& b) {
 1324|  1.95k|   return !a.is_equal(b);
 1325|  1.95k|}
_ZN5Botan6BigIntD2Ev:
  185|   931k|      ~BigInt() { _const_time_unpoison(); }
_ZN5Botan6BigInt4zeroEv:
   50|  4.86k|      static BigInt zero() { return BigInt(); }
_ZN5Botan6BigInt3oneEv:
   55|  2.63k|      static BigInt one() { return BigInt::from_u64(1); }
_ZN5Botan6BigIntaSEOS0_:
  190|   886k|      BigInt& operator=(BigInt&& other) noexcept {
  191|   886k|         if(this != &other) {
  ------------------
  |  Branch (191:13): [True: 886k, False: 0]
  ------------------
  192|   886k|            this->swap(other);
  193|   886k|         }
  194|       |
  195|   886k|         return (*this);
  196|   886k|      }
_ZN5Botan6BigInt8swap_regERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  218|  2.33k|      BOTAN_DEPRECATED("Deprecated no replacement") void swap_reg(secure_vector<word>& reg) {
  219|  2.33k|         m_data.swap(reg);
  220|       |         // sign left unchanged
  221|  2.33k|      }
_ZN5Botan6BigInt3subEPKmmNS0_4SignE:
  358|  2.10M|      BigInt& sub(const word y[], size_t y_words, Sign sign) {
  359|  2.10M|         return add(y, y_words, sign == Positive ? Negative : Positive);
  ------------------
  |  Branch (359:33): [True: 1.67M, False: 429k]
  ------------------
  360|  2.10M|      }
_ZN5Botan6BigInt5clearEv:
  441|  4.06k|      void clear() {
  442|  4.06k|         m_data.set_to_zero();
  443|  4.06k|         m_signedness = Positive;
  444|  4.06k|      }
_ZN5Botan6BigInt7set_bitEm:
  516|  1.13k|      void set_bit(size_t n) { conditionally_set_bit(n, true); }
_ZN5Botan6BigInt21conditionally_set_bitEmb:
  526|   883k|      void conditionally_set_bit(size_t n, bool set_it) {
  527|   883k|         const size_t which = n / (sizeof(word) * 8);
  528|   883k|         const word mask = static_cast<word>(set_it) << (n % (sizeof(word) * 8));
  529|   883k|         m_data.set_word_at(which, word_at(which) | mask);
  530|   883k|      }
_ZN5Botan6BigInt9mask_bitsEm:
  542|  6.39k|      BOTAN_DEPRECATED("Deprecated no replacement") void mask_bits(size_t n) { m_data.mask_bits(n); }
_ZN5Botan6BigInt11set_word_atEmm:
  608|  18.8M|      BOTAN_DEPRECATED("Deprecated no replacement") void set_word_at(size_t i, word w) { m_data.set_word_at(i, w); }
_ZNK5Botan6BigInt12reverse_signEv:
  647|   884k|      Sign reverse_sign() const {
  648|   884k|         if(sign() == Positive) {
  ------------------
  |  Branch (648:13): [True: 884k, False: 0]
  ------------------
  649|   884k|            return Negative;
  650|   884k|         }
  651|      0|         return Positive;
  652|   884k|      }
_ZN5Botan6BigInt8set_signENS0_4SignE:
  663|  2.31M|      void set_sign(Sign sign) {
  664|  2.31M|         if(sign == Negative && is_zero()) {
  ------------------
  |  Branch (664:13): [True: 1.97M, False: 331k]
  |  Branch (664:33): [True: 0, False: 1.97M]
  ------------------
  665|      0|            sign = Positive;
  666|      0|         }
  667|       |
  668|  2.31M|         m_signedness = sign;
  669|  2.31M|      }
_ZNK5Botan6BigInt4sizeEv:
  681|  40.5M|      size_t size() const { return m_data.size(); }
_ZN5Botan6BigInt12mutable_dataEv:
  712|  5.95M|      BOTAN_DEPRECATED("Deprecated no replacement") word* mutable_data() { return m_data.mutable_data(); }
_ZNK5Botan6BigInt4dataEv:
  718|   117k|      BOTAN_DEPRECATED("Deprecated no replacement") const word* data() const { return m_data.const_data(); }
_ZNK5Botan6BigInt7grow_toEm:
  738|  3.68M|      BOTAN_DEPRECATED("Deprecated no replacement") void grow_to(size_t n) const { m_data.grow_to(n); }
_ZN5Botan6BigInt10power_of_2Em:
  906|  1.13k|      static BigInt power_of_2(size_t n) {
  907|  1.13k|         BigInt b;
  908|  1.13k|         b.set_bit(n);
  909|  1.13k|         return b;
  910|  1.13k|      }
_ZNK5Botan6BigInt5_dataEv:
 1033|  7.80M|      const word* _data() const { return m_data.const_data(); }
_ZN5Botan6BigInt11_from_wordsERNSt3__16vectorImNS_16secure_allocatorImEEEE:
 1052|  3.22k|      static BigInt _from_words(secure_vector<word>& words) {
 1053|  3.22k|         BigInt bn;
 1054|  3.22k|         bn.m_data.swap(words);
 1055|  3.22k|         return bn;
 1056|  3.22k|      }
_ZN5Botan6BigInt4Data12mutable_dataEv:
 1083|  10.4M|            word* mutable_data() {
 1084|  10.4M|               invalidate_sig_words();
 1085|  10.4M|               return m_reg.data();
 1086|  10.4M|            }
_ZNK5Botan6BigInt4Data10const_dataEv:
 1088|  8.86M|            const word* const_data() const { return m_reg.data(); }
_ZN5Botan6BigInt4Data11set_word_atEmm:
 1106|  19.7M|            void set_word_at(size_t i, word w) {
 1107|  19.7M|               invalidate_sig_words();
 1108|  19.7M|               if(i >= m_reg.size()) {
  ------------------
  |  Branch (1108:19): [True: 11.9k, False: 19.7M]
  ------------------
 1109|  11.9k|                  if(w == 0) {
  ------------------
  |  Branch (1109:22): [True: 4.28k, False: 7.65k]
  ------------------
 1110|  4.28k|                     return;
 1111|  4.28k|                  }
 1112|  7.65k|                  grow_to(i + 1);
 1113|  7.65k|               }
 1114|  19.7M|               m_reg[i] = w;
 1115|  19.7M|            }
_ZNK5Botan6BigInt4Data7grow_toEm:
 1126|  3.69M|            void grow_to(size_t n) const {
 1127|  3.69M|               if(n > size()) {
  ------------------
  |  Branch (1127:19): [True: 902k, False: 2.79M]
  ------------------
 1128|   902k|                  if(n <= m_reg.capacity()) {
  ------------------
  |  Branch (1128:22): [True: 28, False: 902k]
  ------------------
 1129|     28|                     m_reg.resize(n);
 1130|   902k|                  } else {
 1131|   902k|                     m_reg.resize(n + (8 - (n % 8)));
 1132|   902k|                  }
 1133|   902k|               }
 1134|  3.69M|            }
_ZNK5Botan6BigInt4Data4sizeEv:
 1136|  49.7M|            size_t size() const { return m_reg.size(); }
_ZN5Botan6BigInt4Data4swapERNSt3__16vectorImNS_16secure_allocatorImEEEE:
 1156|  9.47k|            void swap(secure_vector<word>& reg) noexcept {
 1157|  9.47k|               m_reg.swap(reg);
 1158|  9.47k|               invalidate_sig_words();
 1159|  9.47k|            }
_ZNK5Botan6BigInt4Data20invalidate_sig_wordsEv:
 1161|  30.2M|            void invalidate_sig_words() const noexcept { m_sig_words = sig_words_npos; }
_ZN5BotanmiERKNS_6BigIntES2_:
 1219|   884k|inline BigInt operator-(const BigInt& x, const BigInt& y) {
 1220|   884k|   return BigInt::add2(x, y._data(), y.sig_words(), y.reverse_sign());
 1221|   884k|}
_ZN5BotanltERKNS_6BigIntES2_:
 1353|  3.80k|inline bool operator<(const BigInt& a, const BigInt& b) {
 1354|  3.80k|   return a.is_less_than(b);
 1355|  3.80k|}
_ZN5BotangeERKNS_6BigIntEm:
 1403|  1.87k|inline bool operator>=(const BigInt& a, word b) {
 1404|  1.87k|   return (a.cmp_word(b) >= 0);
 1405|  1.87k|}
_ZN5BotangtERKNS_6BigIntEm:
 1423|  3.86k|inline bool operator>(const BigInt& a, word b) {
 1424|  3.86k|   return (a.cmp_word(b) > 0);
 1425|  3.86k|}
_ZN5Botan6BigIntC2Ev:
   45|   908k|      BigInt() = default;

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

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

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

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

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

_Z4fuzzNSt3__14spanIKhLm18446744073709551615EEE:
   76|  1.97k|void fuzz(std::span<const uint8_t> in) {
   77|  1.97k|   static const size_t max_bits = 4096;
   78|       |
   79|  1.97k|   if(in.size() > 2 * max_bits / 8) {
  ------------------
  |  Branch (79:7): [True: 17, False: 1.95k]
  ------------------
   80|     17|      return;
   81|     17|   }
   82|       |
   83|  1.95k|   const Botan::BigInt x = Botan::BigInt::from_bytes(in.subspan(0, in.size() / 2));
   84|  1.95k|   const Botan::BigInt mod = Botan::BigInt::from_bytes(in.subspan(in.size() / 2, in.size() - in.size() / 2));
   85|       |
   86|  1.95k|   if(mod < 2) {
  ------------------
  |  Branch (86:7): [True: 3, False: 1.95k]
  ------------------
   87|      3|      return;
   88|      3|   }
   89|       |
   90|  1.95k|   const Botan::BigInt lib = Botan::inverse_mod(x, mod);
   91|  1.95k|   const Botan::BigInt ref = ref_inverse_mod(x, mod);
   92|       |
   93|  1.95k|   if(ref != lib) {
  ------------------
  |  Branch (93:7): [True: 0, False: 1.95k]
  ------------------
   94|      0|      FUZZER_WRITE_AND_CRASH("X = " << x.to_hex_string() << "\n"
  ------------------
  |  |   70|      0|   do {                                                                                                       \
  |  |   71|      0|      std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; /* NOLINT(*-macro-paren*) */ \
  |  |   72|      0|      abort();                                                                                                \
  |  |   73|      0|   } while(0)
  |  |  ------------------
  |  |  |  Branch (73:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
   95|      0|                                    << "Mod = " << mod.to_hex_string() << "\n"
   96|      0|                                    << "GCD(X,Mod) = " << gcd(x, mod).to_hex_string() << "\n"
   97|      0|                                    << "RefInv(X,Mod) = " << ref.to_hex_string() << "\n"
   98|      0|                                    << "LibInv(X,Mod)  = " << lib.to_hex_string() << "\n"
   99|      0|                                    << "RefCheck = " << ((x * ref) % mod).to_hex_string() << "\n"
  100|      0|                                    << "LibCheck  = " << ((x * lib) % mod).to_hex_string() << "\n");
  101|      0|   }
  102|  1.95k|}
invert.cpp:_ZN12_GLOBAL__N_115ref_inverse_modERKN5Botan6BigIntES3_:
   12|  1.95k|Botan::BigInt ref_inverse_mod(const Botan::BigInt& n, const Botan::BigInt& mod) {
   13|  1.95k|   if(n == 0 || mod < 2) {
  ------------------
  |  Branch (13:7): [True: 10, False: 1.94k]
  |  Branch (13:17): [True: 0, False: 1.94k]
  ------------------
   14|     10|      return 0;
   15|     10|   }
   16|  1.94k|   if(n.is_even() && mod.is_even()) {
  ------------------
  |  Branch (16:7): [True: 123, False: 1.82k]
  |  Branch (16:22): [True: 5, False: 118]
  ------------------
   17|      5|      return 0;
   18|      5|   }
   19|  1.94k|   Botan::BigInt u = mod;
   20|  1.94k|   Botan::BigInt v = n;
   21|  1.94k|   Botan::BigInt A = 1;
   22|  1.94k|   Botan::BigInt B = 0;
   23|  1.94k|   Botan::BigInt C = 0;
   24|  1.94k|   Botan::BigInt D = 1;
   25|       |
   26|   473k|   while(!u.is_zero()) {
  ------------------
  |  Branch (26:10): [True: 471k, False: 1.94k]
  ------------------
   27|   471k|      const size_t u_zero_bits = Botan::low_zero_bits(u);
   28|   471k|      u >>= u_zero_bits;
   29|  1.20M|      for(size_t i = 0; i != u_zero_bits; ++i) {
  ------------------
  |  Branch (29:25): [True: 735k, False: 471k]
  ------------------
   30|   735k|         if(A.is_odd() || B.is_odd()) {
  ------------------
  |  Branch (30:13): [True: 393k, False: 342k]
  |  Branch (30:27): [True: 8.67k, False: 334k]
  ------------------
   31|   401k|            A += n;
   32|   401k|            B -= mod;
   33|   401k|         }
   34|   735k|         A >>= 1;
   35|   735k|         B >>= 1;
   36|   735k|      }
   37|       |
   38|   471k|      const size_t v_zero_bits = Botan::low_zero_bits(v);
   39|   471k|      v >>= v_zero_bits;
   40|  1.08M|      for(size_t i = 0; i != v_zero_bits; ++i) {
  ------------------
  |  Branch (40:25): [True: 612k, False: 471k]
  ------------------
   41|   612k|         if(C.is_odd() || D.is_odd()) {
  ------------------
  |  Branch (41:13): [True: 273k, False: 339k]
  |  Branch (41:27): [True: 11.3k, False: 327k]
  ------------------
   42|   284k|            C += n;
   43|   284k|            D -= mod;
   44|   284k|         }
   45|   612k|         C >>= 1;
   46|   612k|         D >>= 1;
   47|   612k|      }
   48|       |
   49|   471k|      if(u >= v) {
  ------------------
  |  Branch (49:10): [True: 166k, False: 304k]
  ------------------
   50|   166k|         u -= v;
   51|   166k|         A -= C;
   52|   166k|         B -= D;
   53|   304k|      } else {
   54|   304k|         v -= u;
   55|   304k|         C -= A;
   56|   304k|         D -= B;
   57|   304k|      }
   58|   471k|   }
   59|       |
   60|  1.94k|   if(v != 1) {
  ------------------
  |  Branch (60:7): [True: 391, False: 1.55k]
  ------------------
   61|    391|      return 0;  // no modular inverse
   62|    391|   }
   63|       |
   64|  2.79k|   while(D.signum() < 0) {
  ------------------
  |  Branch (64:10): [True: 1.24k, False: 1.55k]
  ------------------
   65|  1.24k|      D += mod;
   66|  1.24k|   }
   67|  4.21k|   while(D >= mod) {
  ------------------
  |  Branch (67:10): [True: 2.66k, False: 1.55k]
  ------------------
   68|  2.66k|      D -= mod;
   69|  2.66k|   }
   70|       |
   71|  1.55k|   return D;
   72|  1.94k|}

_ZN5Botan6BigIntpLERKS0_:
   16|   688k|BigInt& BigInt::operator+=(const BigInt& y) {
   17|   688k|   if(&y == this) {
  ------------------
  |  Branch (17:7): [True: 0, False: 688k]
  ------------------
   18|      0|      return *this <<= 1;
   19|      0|   }
   20|   688k|   return add(y._data(), y.sig_words(), y.sign());
   21|   688k|}
_ZN5Botan6BigIntmIERKS0_:
   23|  2.10M|BigInt& BigInt::operator-=(const BigInt& y) {
   24|  2.10M|   if(&y == this) {
  ------------------
  |  Branch (24:7): [True: 0, False: 2.10M]
  ------------------
   25|      0|      this->clear();
   26|      0|      this->set_sign(Positive);
   27|      0|      return *this;
   28|      0|   }
   29|  2.10M|   return sub(y._data(), y.sig_words(), y.sign());
   30|  2.10M|}
_ZN5Botan6BigInt3addEPKmmNS0_4SignE:
   32|  2.79M|BigInt& BigInt::add(const word y[], size_t y_words, Sign y_sign) {
   33|  2.79M|   const size_t x_sw = sig_words();
   34|       |
   35|  2.79M|   grow_to(std::max(x_sw, y_words) + 1);
   36|       |
   37|  2.79M|   if(sign() == y_sign) {
  ------------------
  |  Branch (37:7): [True: 1.44M, False: 1.34M]
  ------------------
   38|  1.44M|      const word carry = bigint_add2(mutable_data(), size() - 1, y, y_words);
   39|  1.44M|      mutable_data()[size() - 1] += carry;
   40|  1.44M|   } else {
   41|  1.34M|      const int32_t relative_size = bigint_cmp(_data(), x_sw, y, y_words);
   42|       |
   43|  1.34M|      if(relative_size >= 0) {
  ------------------
  |  Branch (43:10): [True: 810k, False: 533k]
  ------------------
   44|       |         // *this >= y
   45|   810k|         bigint_sub2(mutable_data(), x_sw, y, y_words);
   46|   810k|      } else {
   47|       |         // *this < y: compute *this = y - *this
   48|   533k|         bigint_sub2_rev(mutable_data(), y, y_words);
   49|   533k|      }
   50|       |
   51|  1.34M|      if(relative_size < 0) {
  ------------------
  |  Branch (51:10): [True: 533k, False: 810k]
  ------------------
   52|   533k|         set_sign(y_sign);
   53|   810k|      } else if(relative_size == 0) {
  ------------------
  |  Branch (53:17): [True: 4.51k, False: 806k]
  ------------------
   54|  4.51k|         set_sign(Positive);
   55|  4.51k|      }
   56|  1.34M|   }
   57|       |
   58|  2.79M|   return (*this);
   59|  2.79M|}
_ZN5Botan6BigIntmLERKS0_:
  160|  1.13k|BigInt& BigInt::operator*=(const BigInt& y) {
  161|  1.13k|   secure_vector<word> ws;
  162|  1.13k|   return this->mul(y, ws);
  163|  1.13k|}
_ZN5Botan6BigInt3mulERKS0_RNSt3__16vectorImNS_16secure_allocatorImEEEE:
  165|  1.13k|BigInt& BigInt::mul(const BigInt& y, secure_vector<word>& ws) {
  166|  1.13k|   const size_t x_sw = sig_words();
  167|  1.13k|   const size_t y_sw = y.sig_words();
  168|  1.13k|   set_sign((sign() == y.sign()) ? Positive : Negative);
  ------------------
  |  Branch (168:13): [True: 1.13k, False: 0]
  ------------------
  169|       |
  170|  1.13k|   if(x_sw == 0 || y_sw == 0) {
  ------------------
  |  Branch (170:7): [True: 144, False: 988]
  |  Branch (170:20): [True: 0, False: 988]
  ------------------
  171|    144|      clear();
  172|    144|      set_sign(Positive);
  173|    988|   } else if(x_sw == 1 && y_sw > 0) {
  ------------------
  |  Branch (173:14): [True: 533, False: 455]
  |  Branch (173:27): [True: 533, False: 0]
  ------------------
  174|    533|      grow_to(y_sw + 1);
  175|    533|      bigint_linmul3(mutable_data(), y._data(), y_sw, word_at(0));
  176|    533|   } else {
  177|    455|      const size_t new_size = x_sw + y_sw + 1;
  178|    455|      if(ws.size() < new_size) {
  ------------------
  |  Branch (178:10): [True: 455, False: 0]
  ------------------
  179|    455|         ws.resize(new_size);
  180|    455|      }
  181|    455|      secure_vector<word> z_reg(new_size);
  182|       |
  183|    455|      bigint_mul(z_reg.data(), z_reg.size(), _data(), size(), x_sw, y._data(), y.size(), y_sw, ws.data(), ws.size());
  184|       |
  185|    455|      this->swap_reg(z_reg);
  186|    455|   }
  187|       |
  188|  1.13k|   return (*this);
  189|  1.13k|}
_ZN5Botan6BigIntrSEm:
  287|  4.52M|BigInt& BigInt::operator>>=(size_t shift) {
  288|  4.52M|   bigint_shr1(m_data.mutable_data(), m_data.size(), shift);
  289|       |
  290|  4.52M|   if(sig_words() == 0 && m_signedness == Negative) {
  ------------------
  |  Branch (290:7): [True: 54.6k, False: 4.46M]
  |  Branch (290:27): [True: 0, False: 54.6k]
  ------------------
  291|      0|      m_signedness = Positive;
  292|      0|   }
  293|       |
  294|  4.52M|   return (*this);
  295|  4.52M|}

_ZN5Botan6BigInt4add2ERKS0_PKmmNS0_4SignE:
   20|   884k|BigInt BigInt::add2(const BigInt& x, const word y[], size_t y_size, BigInt::Sign y_sign) {
   21|   884k|   const size_t x_sw = x.sig_words();
   22|       |
   23|   884k|   BigInt z = BigInt::with_capacity(std::max(x_sw, y_size) + 1);
   24|       |
   25|   884k|   if(x.sign() == y_sign) {
  ------------------
  |  Branch (25:7): [True: 825k, False: 59.0k]
  ------------------
   26|   825k|      const word carry = bigint_add3(z.mutable_data(), x._data(), x_sw, y, y_size);
   27|   825k|      z.mutable_data()[std::max(x_sw, y_size)] += carry;
   28|   825k|      z.set_sign(x.sign());
   29|   825k|   } else {
   30|  59.0k|      const int32_t relative_size = bigint_cmp(x.data(), x_sw, y, y_size);
   31|       |
   32|  59.0k|      if(relative_size < 0) {
  ------------------
  |  Branch (32:10): [True: 57.0k, False: 1.98k]
  ------------------
   33|       |         // x < y so z = abs(y - x)
   34|       |         // NOLINTNEXTLINE(*-suspicious-call-argument) intentionally swapping x and y here
   35|  57.0k|         bigint_sub3(z.mutable_data(), y, y_size, x.data(), x_sw);
   36|  57.0k|         z.set_sign(y_sign);
   37|  57.0k|      } else if(relative_size == 0) {
  ------------------
  |  Branch (37:17): [True: 409, False: 1.57k]
  ------------------
   38|       |         // Positive zero (nothing to do in this case)
   39|  1.57k|      } 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|  1.57k|         y_size = std::min(x_sw, y_size);
   46|  1.57k|         bigint_sub3(z.mutable_data(), x.data(), x_sw, y, y_size);
   47|  1.57k|         z.set_sign(x.sign());
   48|  1.57k|      }
   49|  59.0k|   }
   50|       |
   51|   884k|   return z;
   52|   884k|}
_ZN5BotanmlERKNS_6BigIntES2_:
   57|  1.13k|BigInt operator*(const BigInt& x, const BigInt& y) {
   58|  1.13k|   const size_t x_sw = x.sig_words();
   59|  1.13k|   const size_t y_sw = y.sig_words();
   60|       |
   61|  1.13k|   BigInt z = BigInt::with_capacity(x.size() + y.size());
   62|       |
   63|  1.13k|   if(x_sw == 1 && y_sw > 0) {
  ------------------
  |  Branch (63:7): [True: 661, False: 471]
  |  Branch (63:20): [True: 608, False: 53]
  ------------------
   64|    608|      bigint_linmul3(z.mutable_data(), y._data(), y_sw, x.word_at(0));
   65|    608|   } else if(y_sw == 1 && x_sw > 0) {
  ------------------
  |  Branch (65:14): [True: 20, False: 504]
  |  Branch (65:27): [True: 20, False: 0]
  ------------------
   66|     20|      bigint_linmul3(z.mutable_data(), x._data(), x_sw, y.word_at(0));
   67|    504|   } else if(x_sw > 0 && y_sw > 0) {
  ------------------
  |  Branch (67:14): [True: 504, False: 0]
  |  Branch (67:26): [True: 431, False: 73]
  ------------------
   68|    431|      secure_vector<word> workspace(z.size());
   69|       |
   70|    431|      bigint_mul(z.mutable_data(),
   71|    431|                 z.size(),
   72|    431|                 x._data(),
   73|    431|                 x.size(),
   74|    431|                 x_sw,
   75|    431|                 y._data(),
   76|    431|                 y.size(),
   77|    431|                 y_sw,
   78|    431|                 workspace.data(),
   79|    431|                 workspace.size());
   80|    431|   }
   81|       |
   82|  1.13k|   z.cond_flip_sign(x_sw > 0 && y_sw > 0 && x.sign() != y.sign());
  ------------------
  |  Branch (82:21): [True: 1.13k, False: 0]
  |  Branch (82:33): [True: 1.05k, False: 73]
  |  Branch (82:45): [True: 612, False: 447]
  ------------------
   83|       |
   84|  1.13k|   return z;
   85|  1.13k|}
_ZN5BotanrsERKNS_6BigIntEm:
  209|  1.63k|BigInt operator>>(const BigInt& x, size_t shift) {
  210|  1.63k|   const size_t shift_words = shift / WordInfo<word>::bits;
  211|  1.63k|   const size_t x_sw = x.sig_words();
  212|       |
  213|  1.63k|   if(shift_words >= x_sw) {
  ------------------
  |  Branch (213:7): [True: 0, False: 1.63k]
  ------------------
  214|      0|      return BigInt::zero();
  215|      0|   }
  216|       |
  217|  1.63k|   const size_t new_size = x_sw - shift_words;
  218|  1.63k|   BigInt y = BigInt::with_capacity(new_size);
  219|  1.63k|   bigint_shr2(y.mutable_data(), new_size, x._data(), x_sw, shift);
  220|       |
  221|  1.63k|   if(x.signum() < 0 && y.is_zero()) {
  ------------------
  |  Branch (221:7): [True: 0, False: 1.63k]
  |  Branch (221:25): [True: 0, False: 0]
  ------------------
  222|      0|      y.set_sign(BigInt::Positive);
  223|  1.63k|   } else {
  224|  1.63k|      y.set_sign(x.sign());
  225|  1.63k|   }
  226|       |
  227|  1.63k|   return y;
  228|  1.63k|}

_ZN5Botan6BigIntC2Em:
   18|  10.8k|BigInt::BigInt(uint64_t n) {
   19|  10.8k|   if constexpr(sizeof(word) == 8) {
   20|  10.8k|      m_data.set_word_at(0, static_cast<word>(n));
   21|       |   } else {
   22|       |      m_data.set_word_at(1, static_cast<word>(n >> 32));
   23|       |      m_data.set_word_at(0, static_cast<word>(n));
   24|       |   }
   25|  10.8k|}
_ZN5Botan6BigInt8from_u64Em:
   28|  2.63k|BigInt BigInt::from_u64(uint64_t n) {
   29|  2.63k|   return BigInt(n);
   30|  2.63k|}
_ZN5Botan6BigInt13with_capacityEm:
   49|   887k|BigInt BigInt::with_capacity(size_t size) {
   50|   887k|   BigInt bn;
   51|   887k|   bn.grow_to(size);
   52|   887k|   return bn;
   53|   887k|}
_ZN5Botan6BigInt10from_bytesENSt3__14spanIKhLm18446744073709551615EEE:
   81|  3.91k|BigInt BigInt::from_bytes(std::span<const uint8_t> input) {
   82|  3.91k|   BigInt r;
   83|  3.91k|   r.assign_from_bytes(input);
   84|  3.91k|   return r;
   85|  3.91k|}
_ZNK5Botan6BigInt8cmp_wordEm:
  120|  16.3k|int32_t BigInt::cmp_word(word other) const {
  121|  16.3k|   if(signum() < 0) {
  ------------------
  |  Branch (121:7): [True: 0, False: 16.3k]
  ------------------
  122|      0|      return -1;  // other is positive ...
  123|      0|   }
  124|       |
  125|  16.3k|   const size_t sw = this->sig_words();
  126|  16.3k|   if(sw > 1) {
  ------------------
  |  Branch (126:7): [True: 8.27k, False: 8.02k]
  ------------------
  127|  8.27k|      return 1;  // must be larger since other is just one word ...
  128|  8.27k|   }
  129|       |
  130|  8.02k|   return bigint_cmp(this->_data(), sw, &other, 1);
  131|  16.3k|}
_ZNK5Botan6BigInt3cmpERKS0_b:
  136|   478k|int32_t BigInt::cmp(const BigInt& other, bool check_signs) const {
  137|   478k|   if(check_signs) {
  ------------------
  |  Branch (137:7): [True: 478k, False: 0]
  ------------------
  138|   478k|      if(other.signum() >= 0 && this->signum() < 0) {
  ------------------
  |  Branch (138:10): [True: 478k, False: 0]
  |  Branch (138:33): [True: 0, False: 478k]
  ------------------
  139|      0|         return -1;
  140|      0|      }
  141|       |
  142|   478k|      if(other.signum() < 0 && this->signum() >= 0) {
  ------------------
  |  Branch (142:10): [True: 0, False: 478k]
  |  Branch (142:32): [True: 0, False: 0]
  ------------------
  143|      0|         return 1;
  144|      0|      }
  145|       |
  146|   478k|      if(other.signum() < 0 && this->signum() < 0) {
  ------------------
  |  Branch (146:10): [True: 0, False: 478k]
  |  Branch (146:32): [True: 0, False: 0]
  ------------------
  147|      0|         return (-bigint_cmp(this->_data(), this->size(), other._data(), other.size()));
  148|      0|      }
  149|   478k|   }
  150|       |
  151|   478k|   return bigint_cmp(this->_data(), this->size(), other._data(), other.size());
  152|   478k|}
_ZNK5Botan6BigInt8is_equalERKS0_:
  154|  1.95k|bool BigInt::is_equal(const BigInt& other) const {
  155|  1.95k|   if(this->sign() != other.sign()) {
  ------------------
  |  Branch (155:7): [True: 0, False: 1.95k]
  ------------------
  156|      0|      return false;
  157|      0|   }
  158|       |
  159|  1.95k|   return bigint_ct_is_eq(this->_data(), this->size(), other._data(), other.size()).as_bool();
  160|  1.95k|}
_ZNK5Botan6BigInt12is_less_thanERKS0_:
  162|  3.80k|bool BigInt::is_less_than(const BigInt& other) const {
  163|  3.80k|   if(this->signum() < 0 && other.signum() >= 0) {
  ------------------
  |  Branch (163:7): [True: 0, False: 3.80k]
  |  Branch (163:29): [True: 0, False: 0]
  ------------------
  164|      0|      return true;
  165|      0|   }
  166|       |
  167|  3.80k|   if(this->signum() >= 0 && other.signum() < 0) {
  ------------------
  |  Branch (167:7): [True: 3.80k, False: 0]
  |  Branch (167:30): [True: 0, False: 3.80k]
  ------------------
  168|      0|      return false;
  169|      0|   }
  170|       |
  171|  3.80k|   if(other.signum() < 0 && this->signum() < 0) {
  ------------------
  |  Branch (171:7): [True: 0, False: 3.80k]
  |  Branch (171:29): [True: 0, False: 0]
  ------------------
  172|      0|      return bigint_ct_is_lt(other._data(), other.size(), this->_data(), this->size()).as_bool();
  173|      0|   }
  174|       |
  175|  3.80k|   return bigint_ct_is_lt(this->_data(), this->size(), other._data(), other.size()).as_bool();
  176|  3.80k|}
_ZN5Botan6BigInt4Data11set_to_zeroEv:
  189|  4.06k|void BigInt::Data::set_to_zero() {
  190|  4.06k|   m_reg.resize(m_reg.capacity());
  191|  4.06k|   clear_mem(m_reg.data(), m_reg.size());
  192|  4.06k|   m_sig_words = 0;
  193|  4.06k|}
_ZN5Botan6BigInt4Data9mask_bitsEm:
  195|  6.39k|void BigInt::Data::mask_bits(size_t n) {
  196|  6.39k|   if(n == 0) {
  ------------------
  |  Branch (196:7): [True: 0, False: 6.39k]
  ------------------
  197|      0|      return set_to_zero();
  198|      0|   }
  199|       |
  200|  6.39k|   const size_t top_word = n / WordInfo<word>::bits;
  201|       |
  202|  6.39k|   if(top_word < size()) {
  ------------------
  |  Branch (202:7): [True: 6.24k, False: 146]
  ------------------
  203|  6.24k|      const word mask = (static_cast<word>(1) << (n % WordInfo<word>::bits)) - 1;
  204|  6.24k|      const size_t len = size() - (top_word + 1);
  205|  6.24k|      if(len > 0) {
  ------------------
  |  Branch (205:10): [True: 6.05k, False: 190]
  ------------------
  206|  6.05k|         clear_mem(&m_reg[top_word + 1], len);
  207|  6.05k|      }
  208|  6.24k|      m_reg[top_word] &= mask;
  209|  6.24k|      invalidate_sig_words();
  210|  6.24k|   }
  211|  6.39k|}
_ZNK5Botan6BigInt4Data14calc_sig_wordsEv:
  213|  7.12M|size_t BigInt::Data::calc_sig_words() const {
  214|  7.12M|   const size_t sz = m_reg.size();
  215|  7.12M|   size_t sig = sz;
  216|       |
  217|  7.12M|   word sub = 1;
  218|       |
  219|   231M|   for(size_t i = 0; i != sz; ++i) {
  ------------------
  |  Branch (219:22): [True: 224M, False: 7.12M]
  ------------------
  220|   224M|      const word w = m_reg[sz - i - 1];
  221|   224M|      sub &= ct_is_zero(w);
  222|   224M|      sig -= sub;
  223|   224M|   }
  224|       |
  225|       |   /*
  226|       |   * This depends on the data so is poisoned, but unpoison it here as
  227|       |   * later conditionals are made on the size.
  228|       |   */
  229|  7.12M|   CT::unpoison(sig);
  230|       |
  231|  7.12M|   return sig;
  232|  7.12M|}
_ZNK5Botan6BigInt13top_bits_freeEv:
  296|  3.56k|size_t BigInt::top_bits_free() const {
  297|  3.56k|   const size_t words = sig_words();
  298|       |
  299|  3.56k|   const word top_word = word_at(words - 1);
  300|  3.56k|   const size_t bits_used = high_bit(CT::value_barrier(top_word));
  301|  3.56k|   CT::unpoison(bits_used);
  302|  3.56k|   return WordInfo<word>::bits - bits_used;
  303|  3.56k|}
_ZNK5Botan6BigInt4bitsEv:
  305|  3.56k|size_t BigInt::bits() const {
  306|  3.56k|   const size_t words = sig_words();
  307|       |
  308|  3.56k|   if(words == 0) {
  ------------------
  |  Branch (308:7): [True: 0, False: 3.56k]
  ------------------
  309|      0|      return 0;
  310|      0|   }
  311|       |
  312|  3.56k|   const size_t full_words = (words - 1) * WordInfo<word>::bits;
  313|  3.56k|   const size_t top_bits = WordInfo<word>::bits - top_bits_free();
  314|       |
  315|  3.56k|   return full_words + top_bits;
  316|  3.56k|}
_ZNK5Botan6BigInt3absEv:
  384|    281|BigInt BigInt::abs() const {
  385|    281|   BigInt x = (*this);
  386|    281|   x.set_sign(Positive);
  387|    281|   return x;
  388|    281|}
_ZN5Botan6BigInt17assign_from_bytesENSt3__14spanIKhLm18446744073709551615EEE:
  423|  3.91k|void BigInt::assign_from_bytes(std::span<const uint8_t> bytes) {
  424|  3.91k|   clear();
  425|       |
  426|  3.91k|   const size_t length = bytes.size();
  427|  3.91k|   const size_t full_words = length / sizeof(word);
  428|  3.91k|   const size_t extra_bytes = length % sizeof(word);
  429|       |
  430|  3.91k|   const size_t total_words = full_words + (extra_bytes > 0 ? 1 : 0);
  ------------------
  |  Branch (430:45): [True: 2.92k, False: 994]
  ------------------
  431|       |
  432|  3.91k|   secure_vector<word> reg(8 * ceil_division<size_t>(total_words, 8));
  433|       |
  434|  30.1k|   for(size_t i = 0; i != full_words; ++i) {
  ------------------
  |  Branch (434:22): [True: 26.2k, False: 3.91k]
  ------------------
  435|  26.2k|      reg[i] = load_be<word>(bytes.last<sizeof(word)>());
  436|  26.2k|      bytes = bytes.first(bytes.size() - sizeof(word));
  437|  26.2k|   }
  438|       |
  439|  3.91k|   if(!bytes.empty()) {
  ------------------
  |  Branch (439:7): [True: 2.92k, False: 994]
  ------------------
  440|  2.92k|      BOTAN_ASSERT_NOMSG(extra_bytes == bytes.size());
  ------------------
  |  |   84|  2.92k|   do {                                                                     \
  |  |   85|  2.92k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  2.92k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 2.92k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  2.92k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 2.92k]
  |  |  ------------------
  ------------------
  441|  2.92k|      std::array<uint8_t, sizeof(word)> last_partial_word = {0};
  442|  2.92k|      copy_mem(std::span{last_partial_word}.last(extra_bytes), bytes);
  443|  2.92k|      reg[full_words] = load_be<word>(last_partial_word);
  444|  2.92k|   }
  445|       |
  446|  3.91k|   m_data.swap(reg);
  447|  3.91k|}
_ZN5Botan6BigInt11ct_cond_addEbRKS0_:
  449|    144|void BigInt::ct_cond_add(bool predicate, const BigInt& value) {
  450|    144|   if(this->signum() < 0 || value.signum() < 0) {
  ------------------
  |  Branch (450:7): [True: 0, False: 144]
  |  Branch (450:29): [True: 0, False: 144]
  ------------------
  451|      0|      throw Invalid_Argument("BigInt::ct_cond_add requires both values to be positive");
  452|      0|   }
  453|    144|   const size_t v_words = value.sig_words();
  454|       |
  455|       |   // The carry can propagate through every existing word of *this, so the
  456|       |   // output needs one slot above whichever input is wider.
  457|    144|   this->grow_to(std::max(this->size(), v_words) + 1);
  458|       |
  459|    144|   const auto mask = CT::Mask<word>::expand(static_cast<word>(predicate)).value();
  460|       |
  461|    144|   word carry = 0;
  462|       |
  463|    144|   word* x = this->mutable_data();
  464|    144|   const word* y = value._data();
  465|       |
  466|  1.50k|   for(size_t i = 0; i != v_words; ++i) {
  ------------------
  |  Branch (466:22): [True: 1.35k, False: 144]
  ------------------
  467|  1.35k|      x[i] = word_add(x[i], y[i] & mask, &carry);
  468|  1.35k|   }
  469|       |
  470|  6.18k|   for(size_t i = v_words; i != size(); ++i) {
  ------------------
  |  Branch (470:28): [True: 6.04k, False: 144]
  ------------------
  471|  6.04k|      x[i] = word_add(x[i], static_cast<word>(0), &carry);
  472|  6.04k|   }
  473|    144|}
_ZN5Botan6BigInt14cond_flip_signEb:
  521|   884k|void BigInt::cond_flip_sign(bool predicate) {
  522|       |   // This code is assuming Negative == 0, Positive == 1
  523|       |
  524|   884k|   const auto mask = CT::Mask<uint8_t>::expand_bool(predicate);
  525|       |
  526|   884k|   const uint8_t current_sign = static_cast<uint8_t>(sign());
  527|       |
  528|   884k|   const uint8_t new_sign = mask.select(current_sign ^ 1, current_sign);
  529|       |
  530|   884k|   set_sign(static_cast<Sign>(new_sign));
  531|   884k|}
_ZN5Botan6BigInt14ct_cond_assignEbRKS0_:
  533|   883k|void BigInt::ct_cond_assign(bool predicate, const BigInt& other) {
  534|   883k|   const size_t t_words = size();
  535|   883k|   const size_t o_words = other.size();
  536|       |
  537|   883k|   if(t_words < o_words) {
  ------------------
  |  Branch (537:7): [True: 120, False: 883k]
  ------------------
  538|    120|      grow_to(o_words);
  539|    120|   }
  540|       |
  541|   883k|   const size_t r_words = std::max(t_words, o_words);
  542|       |
  543|   883k|   const auto mask = CT::Mask<word>::expand_bool(predicate);
  544|       |
  545|  19.7M|   for(size_t i = 0; i != r_words; ++i) {
  ------------------
  |  Branch (545:22): [True: 18.8M, False: 883k]
  ------------------
  546|  18.8M|      const word o_word = other.word_at(i);
  547|  18.8M|      const word t_word = this->word_at(i);
  548|  18.8M|      this->set_word_at(i, mask.select(o_word, t_word));
  549|  18.8M|   }
  550|       |
  551|   883k|   const auto same_sign = CT::Mask<word>::is_equal(sign(), other.sign()).as_choice();
  552|   883k|   cond_flip_sign((mask.as_choice() && !same_sign).as_bool());
  553|   883k|}
_ZNK5Botan6BigInt20_const_time_unpoisonEv:
  559|   934k|void BigInt::_const_time_unpoison() const {
  560|   934k|   CT::unpoison(m_data.const_data(), m_data.size());
  561|   934k|}

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

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

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

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

_ZN5Botan19inverse_mod_generalERKNS_6BigIntES2_:
  180|  1.93k|std::optional<BigInt> inverse_mod_general(const BigInt& x, const BigInt& mod) {
  181|  1.93k|   BOTAN_ARG_CHECK(x > 0, "x must be greater than zero");
  ------------------
  |  |   35|  1.93k|   do {                                                          \
  |  |   36|  1.93k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  1.93k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 1.93k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  1.93k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 1.93k]
  |  |  ------------------
  ------------------
  182|  1.93k|   BOTAN_ARG_CHECK(mod > 0, "mod must be greater than zero");
  ------------------
  |  |   35|  1.93k|   do {                                                          \
  |  |   36|  1.93k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  1.93k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 1.93k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  1.93k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 1.93k]
  |  |  ------------------
  ------------------
  183|  1.93k|   BOTAN_ARG_CHECK(x < mod, "x must be less than m");
  ------------------
  |  |   35|  1.93k|   do {                                                          \
  |  |   36|  1.93k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  1.93k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 1.93k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  1.93k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 1.93k]
  |  |  ------------------
  ------------------
  184|       |
  185|       |   // Easy case where gcd > 1 so no inverse exists
  186|  1.93k|   if(x.is_even() && mod.is_even()) {
  ------------------
  |  Branch (186:7): [True: 94, False: 1.83k]
  |  Branch (186:22): [True: 0, False: 94]
  ------------------
  187|      0|      return std::nullopt;
  188|      0|   }
  189|       |
  190|  1.93k|   if(mod.is_odd()) {
  ------------------
  |  Branch (190:7): [True: 246, False: 1.68k]
  ------------------
  191|    246|      BigInt z = inverse_mod_odd_modulus(x, mod);
  192|    246|      if(z.is_zero()) {
  ------------------
  |  Branch (192:10): [True: 27, False: 219]
  ------------------
  193|     27|         return std::nullopt;
  194|    219|      } else {
  195|    219|         return z;
  196|    219|      }
  197|    246|   }
  198|       |
  199|       |   // If x is even and mod is even we already returned 0
  200|       |   // If x is even and mod is odd we jumped directly to odd-modulus algo
  201|  1.68k|   BOTAN_ASSERT_NOMSG(x.is_odd());
  ------------------
  |  |   84|  1.68k|   do {                                                                     \
  |  |   85|  1.68k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.68k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
  202|       |
  203|  1.68k|   const size_t mod_lz = low_zero_bits(mod);
  204|  1.68k|   BOTAN_ASSERT_NOMSG(mod_lz > 0);
  ------------------
  |  |   84|  1.68k|   do {                                                                     \
  |  |   85|  1.68k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.68k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
  205|  1.68k|   const size_t mod_bits = mod.bits();
  206|  1.68k|   BOTAN_ASSERT_NOMSG(mod_bits > mod_lz);
  ------------------
  |  |   84|  1.68k|   do {                                                                     \
  |  |   85|  1.68k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.68k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.68k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.68k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.68k]
  |  |  ------------------
  ------------------
  207|       |
  208|  1.68k|   if(mod_lz == mod_bits - 1) {
  ------------------
  |  Branch (208:7): [True: 55, False: 1.63k]
  ------------------
  209|       |      // In this case we are performing an inversion modulo 2^k
  210|     55|      auto z = inverse_mod_pow2(x, mod_lz);
  211|     55|      if(z.is_zero()) {
  ------------------
  |  Branch (211:10): [True: 0, False: 55]
  ------------------
  212|      0|         return std::nullopt;
  213|     55|      } else {
  214|     55|         return z;
  215|     55|      }
  216|     55|   }
  217|       |
  218|  1.63k|   if(mod_lz == 1) {
  ------------------
  |  Branch (218:7): [True: 182, False: 1.44k]
  ------------------
  219|       |      /*
  220|       |      Inversion modulo 2*o is an easier special case of CRT
  221|       |
  222|       |      This is exactly the main CRT flow below but taking advantage of
  223|       |      the fact that any odd number ^-1 modulo 2 is 1. As a result both
  224|       |      inv_2k and c can be taken to be 1, m2k is 2, and h is always
  225|       |      either 0 or 1, and its value depends only on the low bit of inv_o.
  226|       |
  227|       |      This is worth special casing because we generate RSA primes such
  228|       |      that phi(n) is of this form. However this only works for keys
  229|       |      that we generated in this way; pre-existing keys will typically
  230|       |      fall back to the general algorithm below.
  231|       |      */
  232|       |
  233|    182|      const BigInt o = mod >> 1;
  234|    182|      const BigInt inv_o = inverse_mod_odd_modulus(ct_modulo(x, o), o);
  235|       |
  236|       |      // No modular inverse in this case:
  237|    182|      if(inv_o == 0) {
  ------------------
  |  Branch (237:10): [True: 38, False: 144]
  ------------------
  238|     38|         return std::nullopt;
  239|     38|      }
  240|       |
  241|    144|      BigInt h = inv_o;
  242|    144|      h.ct_cond_add(!inv_o.get_bit(0), o);
  243|    144|      return h;
  244|    182|   }
  245|       |
  246|       |   /*
  247|       |   * In this case we are performing an inversion modulo 2^k*o for
  248|       |   * some k >= 2 and some odd (not necessarily prime) integer.
  249|       |   * Compute the inversions modulo 2^k and modulo o, then combine them
  250|       |   * using CRT, which is possible because 2^k and o are relatively prime.
  251|       |   */
  252|       |
  253|  1.44k|   const BigInt o = mod >> mod_lz;
  254|  1.44k|   const BigInt inv_o = inverse_mod_odd_modulus(ct_modulo(x, o), o);
  255|  1.44k|   const BigInt inv_2k = inverse_mod_pow2(x, mod_lz);
  256|       |
  257|       |   // No modular inverse in this case:
  258|  1.44k|   if(inv_o == 0 || inv_2k == 0) {
  ------------------
  |  Branch (258:7): [True: 317, False: 1.13k]
  |  Branch (258:21): [True: 0, False: 1.13k]
  ------------------
  259|    317|      return std::nullopt;
  260|    317|   }
  261|       |
  262|  1.13k|   const BigInt m2k = BigInt::power_of_2(mod_lz);
  263|       |   // Compute the CRT parameter
  264|  1.13k|   const BigInt c = inverse_mod_pow2(o, mod_lz);
  265|       |
  266|       |   // This should never happen; o is odd so gcd is 1 and inverse mod 2^k exists
  267|  1.13k|   BOTAN_ASSERT_NOMSG(c.signum() != 0);
  ------------------
  |  |   84|  1.13k|   do {                                                                     \
  |  |   85|  1.13k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.13k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.13k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.13k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.13k]
  |  |  ------------------
  ------------------
  268|       |
  269|       |   // Compute h = c*(inv_2k-inv_o) mod 2^k
  270|  1.13k|   BigInt h = c * (inv_2k - inv_o);
  271|  1.13k|   const bool h_neg = h.signum() < 0;
  272|  1.13k|   h.set_sign(BigInt::Positive);
  273|  1.13k|   h.mask_bits(mod_lz);
  274|  1.13k|   const bool h_nonzero = h.signum() != 0;
  275|  1.13k|   h.ct_cond_assign(h_nonzero && h_neg, m2k - h);
  ------------------
  |  Branch (275:21): [True: 988, False: 144]
  |  Branch (275:34): [True: 541, False: 447]
  ------------------
  276|       |
  277|       |   // Return result inv_o + h * o
  278|  1.13k|   h *= o;
  279|  1.13k|   h += inv_o;
  280|  1.13k|   return h;
  281|  1.44k|}
_ZN5Botan11inverse_modERKNS_6BigIntES2_:
  386|  2.21k|BigInt inverse_mod(const BigInt& n, const BigInt& mod) {
  387|  2.21k|   BOTAN_ARG_CHECK(mod.signum() > 0, "Modulus must be positive");
  ------------------
  |  |   35|  2.21k|   do {                                                          \
  |  |   36|  2.21k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  2.21k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 2.21k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  2.21k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 2.21k]
  |  |  ------------------
  ------------------
  388|  2.21k|   BOTAN_ARG_CHECK(n.signum() >= 0, "Value cannot be negative");
  ------------------
  |  |   35|  2.21k|   do {                                                          \
  |  |   36|  2.21k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */              \
  |  |   37|  2.21k|      if(!(expr)) {                                              \
  |  |  ------------------
  |  |  |  Branch (37:10): [True: 0, False: 2.21k]
  |  |  ------------------
  |  |   38|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */     \
  |  |   39|      0|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   40|      0|      }                                                          \
  |  |   41|  2.21k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (41:12): [Folded, False: 2.21k]
  |  |  ------------------
  ------------------
  389|       |
  390|  2.21k|   if(n.is_zero() || (n.is_even() && mod.is_even())) {
  ------------------
  |  Branch (390:7): [True: 19, False: 2.20k]
  |  Branch (390:23): [True: 163, False: 2.03k]
  |  Branch (390:38): [True: 5, False: 158]
  ------------------
  391|     24|      return BigInt::zero();
  392|     24|   }
  393|       |
  394|  2.19k|   if(n >= mod) {
  ------------------
  |  Branch (394:7): [True: 263, False: 1.93k]
  ------------------
  395|    263|      return inverse_mod(ct_modulo(n, mod), mod);
  396|    263|   }
  397|       |
  398|  1.93k|   return inverse_mod_general(n, mod).value_or(BigInt::zero());
  399|  2.19k|}
mod_inv.cpp:_ZN5Botan12_GLOBAL__N_123inverse_mod_odd_modulusERKNS_6BigIntES3_:
   21|  1.87k|BigInt inverse_mod_odd_modulus(const BigInt& n, const BigInt& mod) {
   22|       |   // Caller should assure these preconditions:
   23|  1.87k|   BOTAN_ASSERT_NOMSG(n.signum() >= 0);
  ------------------
  |  |   84|  1.87k|   do {                                                                     \
  |  |   85|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.87k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.87k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
   24|  1.87k|   BOTAN_ASSERT_NOMSG(mod.signum() > 0);
  ------------------
  |  |   84|  1.87k|   do {                                                                     \
  |  |   85|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.87k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.87k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
   25|  1.87k|   BOTAN_ASSERT_NOMSG(n < mod);
  ------------------
  |  |   84|  1.87k|   do {                                                                     \
  |  |   85|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.87k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.87k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
   26|  1.87k|   BOTAN_ASSERT_NOMSG(mod >= 3 && mod.is_odd());
  ------------------
  |  |   84|  1.87k|   do {                                                                     \
  |  |   85|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  3.75k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:12): [True: 1.87k, False: 0]
  |  |  |  Branch (86:12): [True: 1.87k, False: 0]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
   27|       |
   28|       |   /*
   29|       |   This uses a modular inversion algorithm designed by Niels Möller
   30|       |   and implemented in Nettle. The same algorithm was later also
   31|       |   adapted to GMP in mpn_sec_invert.
   32|       |
   33|       |   It can be easily implemented in a way that does not depend on
   34|       |   secret branches or memory lookups, providing resistance against
   35|       |   some forms of side channel attack.
   36|       |
   37|       |   There is also a description of the algorithm in Appendix 5 of "Fast
   38|       |   Software Polynomial Multiplication on ARM Processors using the NEON Engine"
   39|       |   by Danilo Câmara, Conrado P. L. Gouvêa, Julio López, and Ricardo
   40|       |   Dahab in LNCS 8182
   41|       |      https://inria.hal.science/hal-01506572/document
   42|       |
   43|       |   Thanks to Niels for creating the algorithm, explaining some things
   44|       |   about it, and the reference to the paper.
   45|       |   */
   46|       |
   47|  1.87k|   const size_t mod_words = mod.sig_words();
   48|  1.87k|   BOTAN_ASSERT(mod_words > 0, "Not empty");
  ------------------
  |  |   71|  1.87k|   do {                                                                                 \
  |  |   72|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|  1.87k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 1.87k]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
   49|       |
   50|  1.87k|   secure_vector<word> tmp_mem(5 * mod_words);
   51|       |
   52|  1.87k|   word* v_w = &tmp_mem[0];  // NOLINT(readability-container-data-pointer)
   53|  1.87k|   word* u_w = &tmp_mem[1 * mod_words];
   54|  1.87k|   word* b_w = &tmp_mem[2 * mod_words];
   55|  1.87k|   word* a_w = &tmp_mem[3 * mod_words];
   56|  1.87k|   word* mp1o2 = &tmp_mem[4 * mod_words];
   57|       |
   58|  1.87k|   copy_mem(a_w, n._data(), std::min(n.size(), mod_words));
   59|  1.87k|   copy_mem(b_w, mod._data(), std::min(mod.size(), mod_words));
   60|  1.87k|   u_w[0] = 1;
   61|       |   // v_w = 0
   62|       |
   63|       |   // compute (mod + 1) / 2 which [because mod is odd] is equal to
   64|       |   // (mod / 2) + 1
   65|  1.87k|   copy_mem(mp1o2, mod._data(), std::min(mod.size(), mod_words));
   66|  1.87k|   bigint_shr1(mp1o2, mod_words, 1);
   67|  1.87k|   const word carry = bigint_add2(mp1o2, mod_words, u_w, 1);
   68|  1.87k|   BOTAN_ASSERT_NOMSG(carry == 0);
  ------------------
  |  |   84|  1.87k|   do {                                                                     \
  |  |   85|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                         \
  |  |   86|  1.87k|      if(!(expr)) {                                                         \
  |  |  ------------------
  |  |  |  Branch (86:10): [True: 0, False: 1.87k]
  |  |  ------------------
  |  |   87|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                \
  |  |   88|      0|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   89|      0|      }                                                                     \
  |  |   90|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
   69|       |
   70|  1.87k|   CT::poison(tmp_mem.data(), tmp_mem.size());
   71|       |
   72|       |   // Only n.bits() + mod.bits() iterations are required, but avoid leaking the size of n
   73|  1.87k|   const size_t execs = 2 * mod.bits();
   74|       |
   75|   958k|   for(size_t i = 0; i != execs; ++i) {
  ------------------
  |  Branch (75:22): [True: 956k, False: 1.87k]
  ------------------
   76|   956k|      const word odd_a = a_w[0] & 1;
   77|       |
   78|       |      //if(odd_a) a -= b
   79|   956k|      const word underflow = bigint_cnd_sub(odd_a, a_w, b_w, mod_words);
   80|       |
   81|       |      //if(underflow) { b -= a; a = abs(a); swap(u, v); }
   82|   956k|      bigint_cnd_add(underflow, b_w, a_w, mod_words);
   83|   956k|      bigint_cnd_abs(underflow, a_w, mod_words);
   84|   956k|      bigint_cnd_swap(underflow, u_w, v_w, mod_words);
   85|       |
   86|       |      // a >>= 1
   87|   956k|      bigint_shr1(a_w, mod_words, 1);
   88|       |
   89|       |      //if(odd_a) u -= v;
   90|   956k|      const word borrow = bigint_cnd_sub(odd_a, u_w, v_w, mod_words);
   91|       |
   92|       |      // if(borrow) u += p
   93|   956k|      bigint_cnd_add(borrow, u_w, mod._data(), mod_words);
   94|       |
   95|   956k|      const word odd_u = u_w[0] & 1;
   96|       |
   97|       |      // u >>= 1
   98|   956k|      bigint_shr1(u_w, mod_words, 1);
   99|       |
  100|       |      //if(odd_u) u += mp1o2;
  101|   956k|      bigint_cnd_add(odd_u, u_w, mp1o2, mod_words);
  102|   956k|   }
  103|       |
  104|  1.87k|   const auto a_is_0 = CT::all_zeros(a_w, mod_words);
  105|       |
  106|  1.87k|   auto b_is_1 = CT::Mask<word>::is_equal(b_w[0], 1);
  107|  8.61k|   for(size_t i = 1; i != mod_words; ++i) {
  ------------------
  |  Branch (107:22): [True: 6.73k, False: 1.87k]
  ------------------
  108|  6.73k|      b_is_1 &= CT::Mask<word>::is_zero(b_w[i]);
  109|  6.73k|   }
  110|       |
  111|  1.87k|   BOTAN_ASSERT(a_is_0.as_bool(), "A is zero");
  ------------------
  |  |   71|  1.87k|   do {                                                                                 \
  |  |   72|  1.87k|      /* NOLINTNEXTLINE(*-simplify-boolean-expr) */                                     \
  |  |   73|  1.87k|      if(!(expr)) {                                                                     \
  |  |  ------------------
  |  |  |  Branch (73:10): [True: 0, False: 1.87k]
  |  |  ------------------
  |  |   74|      0|         /* NOLINTNEXTLINE(bugprone-lambda-function-name) */                            \
  |  |   75|      0|         Botan::assertion_failure(#expr, assertion_made, __func__, __FILE__, __LINE__); \
  |  |   76|      0|      }                                                                                 \
  |  |   77|  1.87k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (77:12): [Folded, False: 1.87k]
  |  |  ------------------
  ------------------
  112|       |
  113|       |   // if b != 1 then gcd(n,mod) > 1 and inverse does not exist
  114|       |   // in which case zero out the result to indicate this
  115|  1.87k|   (~b_is_1).if_set_zero_out(v_w, mod_words);
  116|       |
  117|       |   /*
  118|       |   * We've placed the result in the lowest words of the temp buffer.
  119|       |   * So just clear out the other values and then give that buffer to a
  120|       |   * BigInt.
  121|       |   */
  122|  1.87k|   clear_mem(&tmp_mem[mod_words], 4 * mod_words);
  123|       |
  124|  1.87k|   CT::unpoison(tmp_mem.data(), tmp_mem.size());
  125|       |
  126|  1.87k|   BigInt r;
  127|  1.87k|   r.swap_reg(tmp_mem);
  128|  1.87k|   return r;
  129|  1.87k|}
mod_inv.cpp:_ZN5Botan12_GLOBAL__N_116inverse_mod_pow2ERKNS_6BigIntEm:
  131|  2.63k|BigInt inverse_mod_pow2(const BigInt& a1, size_t k) {
  132|       |   /*
  133|       |   * From "A New Algorithm for Inversion mod p^k" by Çetin Kaya Koç
  134|       |   * https://eprint.iacr.org/2017/411.pdf sections 5 and 7.
  135|       |   */
  136|       |
  137|  2.63k|   if(a1.is_even() || k == 0) {
  ------------------
  |  Branch (137:7): [True: 0, False: 2.63k]
  |  Branch (137:23): [True: 0, False: 2.63k]
  ------------------
  138|      0|      return BigInt::zero();
  139|      0|   }
  140|  2.63k|   if(k == 1) {
  ------------------
  |  Branch (140:7): [True: 6, False: 2.63k]
  ------------------
  141|      6|      return BigInt::one();
  142|      6|   }
  143|       |
  144|  2.63k|   BigInt a = a1;
  145|  2.63k|   a.mask_bits(k);
  146|       |
  147|  2.63k|   BigInt b = BigInt::one();
  148|  2.63k|   BigInt X = BigInt::zero();
  149|  2.63k|   BigInt newb;
  150|       |
  151|  2.63k|   const size_t a_words = a.sig_words();
  152|       |
  153|       |   /*
  154|       |   Hide the exact value of k. k is anyway known to word length
  155|       |   granularity because of the length of a, so no point in doing more
  156|       |   than this.
  157|       |   */
  158|  2.63k|   const size_t k_words = ceil_division(k, WordInfo<word>::bits);
  159|  2.63k|   const size_t iter = k_words * WordInfo<word>::bits;
  160|       |
  161|  2.63k|   X.grow_to(k_words);
  162|  2.63k|   b.grow_to(a_words);
  163|       |
  164|   884k|   for(size_t i = 0; i != iter; ++i) {
  ------------------
  |  Branch (164:22): [True: 882k, False: 2.63k]
  ------------------
  165|   882k|      const bool b0 = b.get_bit(0);
  166|   882k|      X.conditionally_set_bit(i, b0);
  167|   882k|      newb = b - a;
  168|   882k|      b.ct_cond_assign(b0, newb);
  169|   882k|      b >>= 1;
  170|   882k|   }
  171|       |
  172|  2.63k|   X.mask_bits(k);
  173|       |
  174|  2.63k|   CT::unpoison(X);
  175|  2.63k|   return X;
  176|  2.63k|}

_ZN5Botan13low_zero_bitsERKNS_6BigIntE:
  194|   945k|size_t low_zero_bits(const BigInt& n) {
  195|   945k|   size_t low_zero = 0;
  196|       |
  197|   945k|   auto seen_nonempty_word = CT::Mask<word>::cleared();
  198|       |
  199|  34.9M|   for(size_t i = 0; i != n.size(); ++i) {
  ------------------
  |  Branch (199:22): [True: 33.9M, False: 945k]
  ------------------
  200|  33.9M|      const word x = n.word_at(i);
  201|       |
  202|       |      // ctz(0) will return sizeof(word)
  203|  33.9M|      const size_t tz_x = ctz(x);
  204|       |
  205|       |      // if x > 0 we want to count tz_x in total but not any
  206|       |      // further words, so set the mask after the addition
  207|  33.9M|      low_zero += seen_nonempty_word.if_not_set_return(tz_x);
  208|       |
  209|  33.9M|      seen_nonempty_word |= CT::Mask<word>::expand(x);
  210|  33.9M|   }
  211|       |
  212|       |   // if we saw no words with x > 0 then n == 0 and the value we have
  213|       |   // computed is meaningless. Instead return BigInt::zero() in that case.
  214|   945k|   return static_cast<size_t>(seen_nonempty_word.if_set_return(low_zero));
  215|   945k|}

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

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

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

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

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

