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

_ZN5Botan14expand_top_bitImEET_S1_Qsr3std11is_integralIS1_EE5value:
   25|  8.55M|{
   26|  8.55M|   return static_cast<T>(0) - (a >> (sizeof(T) * 8 - 1));
   27|  8.55M|}
_ZN5Botan6chooseImEET_S1_S1_S1_:
  180|  47.0M|inline constexpr T choose(T mask, T a, T b) {
  181|       |   //return (mask & a) | (~mask & b);
  182|  47.0M|   return (b ^ (mask & (a ^ b)));
  183|  47.0M|}
_ZN5Botan8majorityImEET_S1_S1_S1_:
  186|  21.3M|inline constexpr T majority(T a, T b, T c) {
  187|       |   /*
  188|       |   Considering each bit of a, b, c individually
  189|       |
  190|       |   If a xor b is set, then c is the deciding vote.
  191|       |
  192|       |   If a xor b is not set then either a and b are both set or both unset.
  193|       |   In either case the value of c doesn't matter, and examining b (or a)
  194|       |   allows us to determine which case we are in.
  195|       |   */
  196|  21.3M|   return choose(a ^ b, c, b);
  197|  21.3M|}

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

_ZNK5Botan2CT4MaskImE5valueEv:
  283|  8.55M|      constexpr T value() const { return m_mask; }
_ZNK5Botan2CT4MaskImEcoEv:
  219|  4.27M|      constexpr Mask<T> operator~() const { return Mask<T>(~value()); }
_ZNK5Botan2CT4MaskImE6selectEmm:
  234|  4.27M|      constexpr T select(T x, T y) const { return choose(value(), x, y); }
_ZN5Botan2CT4MaskImE6is_lteEmm:
  149|  4.27M|      static constexpr Mask<T> is_lte(T x, T y) { return ~Mask<T>::is_gt(x, y); }
_ZN5Botan2CT4MaskImE5is_gtEmm:
  144|  4.27M|      static constexpr Mask<T> is_gt(T x, T y) { return Mask<T>::is_lt(y, x); }
_ZN5Botan2CT4MaskImEC2Em:
  286|  12.8M|      constexpr Mask(T m) : m_mask(m) {}
_ZN5Botan2CT4MaskImE5is_ltEmm:
  139|  8.55M|      static constexpr Mask<T> is_lt(T x, T y) { return Mask<T>(expand_top_bit<T>(x ^ ((x ^ y) | ((x - y) ^ x)))); }
_ZNK5Botan2CT4MaskImE13if_set_returnEm:
  224|  4.27M|      constexpr T if_set_return(T x) const { return m_mask & x; }

_ZN5Botan8FE_25519C2ESt16initializer_listIiE:
   37|  1.53k|      FE_25519(std::initializer_list<int32_t> x) {
   38|  1.53k|         if(x.size() != 10) {
  ------------------
  |  Branch (38:13): [True: 0, False: 1.53k]
  ------------------
   39|      0|            throw Invalid_Argument("Invalid FE_25519 initializer list");
   40|      0|         }
   41|  1.53k|         copy_mem(m_fe, x.begin(), 10);
   42|  1.53k|      }

_ZN16botan_rng_structC2ENSt3__110unique_ptrIN5Botan21RandomNumberGeneratorENS0_14default_deleteIS3_EEEE:
   53|  4.17k|         explicit NAME(std::unique_ptr<TYPE> x) : botan_struct(std::move(x)) {} \
_ZNK9Botan_FFI12botan_structIN5Botan21RandomNumberGeneratorELj1224866241EE8magic_okEv:
   42|  4.17k|      bool magic_ok() const { return (m_magic == MAGIC); }
_ZN9Botan_FFI12botan_structIN5Botan21RandomNumberGeneratorELj1224866241EEC2ENSt3__110unique_ptrIS2_NS4_14default_deleteIS2_EEEE:
   35|  4.17k|      botan_struct(std::unique_ptr<T> obj) : m_magic(MAGIC), m_obj(std::move(obj)) {}
_ZN9Botan_FFI12botan_structIN5Botan21RandomNumberGeneratorELj1224866241EED2Ev:
   37|  4.17k|      virtual ~botan_struct() {
   38|  4.17k|         m_magic = 0;
   39|  4.17k|         m_obj.reset();
   40|  4.17k|      }
_ZN9Botan_FFI17ffi_delete_objectIN5Botan21RandomNumberGeneratorELj1224866241EEEiPNS_12botan_structIT_XT0_EEEPKc:
  127|  4.17k|int ffi_delete_object(botan_struct<T, M>* obj, const char* func_name) {
  128|  4.17k|   return ffi_guard_thunk(func_name, [=]() -> int {
  129|       |      // ignore delete of null objects
  130|  4.17k|      if(obj == nullptr) {
  131|  4.17k|         return BOTAN_FFI_SUCCESS;
  132|  4.17k|      }
  133|       |
  134|  4.17k|      if(obj->magic_ok() == false) {
  135|  4.17k|         return BOTAN_FFI_ERROR_INVALID_OBJECT;
  136|  4.17k|      }
  137|       |
  138|  4.17k|      delete obj;
  139|  4.17k|      return BOTAN_FFI_SUCCESS;
  140|  4.17k|   });
  141|  4.17k|}
_ZZN9Botan_FFI17ffi_delete_objectIN5Botan21RandomNumberGeneratorELj1224866241EEEiPNS_12botan_structIT_XT0_EEEPKcENKUlvE_clEv:
  128|  4.17k|   return ffi_guard_thunk(func_name, [=]() -> int {
  129|       |      // ignore delete of null objects
  130|  4.17k|      if(obj == nullptr) {
  ------------------
  |  Branch (130:10): [True: 0, False: 4.17k]
  ------------------
  131|      0|         return BOTAN_FFI_SUCCESS;
  132|      0|      }
  133|       |
  134|  4.17k|      if(obj->magic_ok() == false) {
  ------------------
  |  Branch (134:10): [True: 0, False: 4.17k]
  ------------------
  135|      0|         return BOTAN_FFI_ERROR_INVALID_OBJECT;
  136|      0|      }
  137|       |
  138|  4.17k|      delete obj;
  139|  4.17k|      return BOTAN_FFI_SUCCESS;
  140|  4.17k|   });

_ZN5Botan6detail9store_anyILNS0_10EndiannessE0ENS0_10AutoDetectETkNS0_20unsigned_integralishEmQoosr3stdE7same_asIS3_T0_Esr3stdE7same_asIT1_S4_EEEvS5_Ph:
  677|   116k|inline constexpr void store_any(T in, uint8_t out[]) {
  678|       |   // asserts that *out points to enough bytes to write into
  679|   116k|   store_any<endianness, InT>(in, std::span<uint8_t, sizeof(T)>(out, sizeof(T)));
  680|   116k|}
_ZN5Botan6detail9store_anyILNS0_10EndiannessE0ENS0_10AutoDetectETkNS0_20unsigned_integralishEmTkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm8EEEQsr3stdE7same_asIS3_T0_EEEvT1_OT2_:
  612|   116k|inline constexpr void store_any(T in, OutR&& out_range) {
  613|   116k|   store_any<endianness, T>(in, std::forward<OutR>(out_range));
  614|   116k|}
_ZN5Botan6detail9store_anyILNS0_10EndiannessE0ETkNSt3__117unsigned_integralEmTkNS_6ranges23contiguous_output_rangeIhEENS3_4spanIhLm8EEEEEvT0_OT1_:
  491|  1.05M|inline constexpr void store_any(InT in, OutR&& out_range) {
  492|  1.05M|   ranges::assert_exact_byte_length<sizeof(InT)>(out_range);
  493|  1.05M|   std::span out{out_range};
  494|       |
  495|       |   // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  496|       |   // internally to copy ranges on a byte-by-byte basis, which is not allowed
  497|       |   // in a `constexpr` context.
  498|  1.05M|   if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (498:7): [Folded, False: 1.05M]
  ------------------
  499|      0|      return fallback_store_any<endianness, InT>(in, std::forward<OutR>(out_range));
  500|  1.05M|   } else {
  501|       |      if constexpr(sizeof(InT) == 1) {
  502|       |         out[0] = static_cast<uint8_t>(in);
  503|       |      } else if constexpr(is_native(endianness)) {
  504|       |         typecast_copy(out, in);
  505|  1.05M|      } else if constexpr(is_opposite(endianness)) {
  506|  1.05M|         typecast_copy(out, reverse_bytes(in));
  507|       |      } else {
  508|       |         static_assert(native_endianness_is_unknown<endianness>());
  509|       |         return fallback_store_any<endianness, InT>(in, std::forward<OutR>(out_range));
  510|       |      }
  511|  1.05M|   }
  512|  1.05M|}
_ZN5Botan6detail8load_anyILNS0_10EndiannessE0ETkNSt3__117unsigned_integralEmTkNS_6ranges16contiguous_rangeIhEENS3_4spanIKhLm8EEEEET0_OT1_:
  248|  4.27M|inline constexpr OutT load_any(InR&& in_range) {
  249|  4.27M|   ranges::assert_exact_byte_length<sizeof(OutT)>(in_range);
  250|  4.27M|   std::span in{in_range};
  251|       |
  252|       |   // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  253|       |   // internally to copy ranges on a byte-by-byte basis, which is not allowed
  254|       |   // in a `constexpr` context.
  255|  4.27M|   if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (255:7): [Folded, False: 4.27M]
  ------------------
  256|      0|      return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  257|  4.27M|   } else {
  258|       |      if constexpr(sizeof(OutT) == 1) {
  259|       |         return static_cast<OutT>(in[0]);
  260|       |      } else if constexpr(is_native(endianness)) {
  261|       |         return typecast_copy<OutT>(in);
  262|  4.27M|      } else if constexpr(is_opposite(endianness)) {
  263|  4.27M|         return reverse_bytes(typecast_copy<OutT>(in));
  264|       |      } else {
  265|       |         static_assert(native_endianness_is_unknown<endianness>());
  266|       |         return fallback_load_any<endianness, OutT>(std::forward<InR>(in_range));
  267|       |      }
  268|  4.27M|   }
  269|  4.27M|}
_ZN5Botan7load_beImJPKhiEEEDaDpOT0_:
  471|  4.27M|inline constexpr auto load_be(ParamTs&&... params) {
  472|  4.27M|   return detail::load_any<detail::Endianness::Big, OutT>(std::forward<ParamTs>(params)...);
  473|  4.27M|}
_ZN5Botan6detail8load_anyILNS0_10EndiannessE0ETkNS0_20unsigned_integralishEmEET0_PKhm:
  421|  4.27M|inline constexpr OutT load_any(const uint8_t in[], size_t off) {
  422|       |   // asserts that *in points to enough bytes to read at offset off
  423|  4.27M|   constexpr size_t out_size = sizeof(OutT);
  424|  4.27M|   return load_any<endianness, OutT>(std::span<const uint8_t, out_size>(in + off * out_size, out_size));
  425|  4.27M|}
_ZN5Botan8store_beINS_6detail10AutoDetectEJRKmPhEEEDaDpOT0_:
  711|   116k|inline constexpr auto store_be(ParamTs&&... params) {
  712|   116k|   return detail::store_any<detail::Endianness::Big, ModifierT>(std::forward<ParamTs>(params)...);
  713|   116k|}
_ZN5Botan11copy_out_beITkNS_6ranges14spanable_rangeERNSt3__16vectorImNS_16secure_allocatorImEEEEEEvNS2_4spanIhLm18446744073709551615EEEOT_:
  739|   116k|void copy_out_be(std::span<uint8_t> out, InR&& in) {
  740|   116k|   using T = std::ranges::range_value_t<InR>;
  741|   116k|   std::span<const T> in_s{in};
  742|   116k|   const auto remaining_bytes = detail::copy_out_any_word_aligned_portion<detail::Endianness::Big>(out, in_s);
  743|       |
  744|       |   // copy remaining bytes as a partial word
  745|   116k|   for(size_t i = 0; i < remaining_bytes; ++i) {
  ------------------
  |  Branch (745:22): [True: 0, False: 116k]
  ------------------
  746|      0|      out[i] = get_byte_var(i, in_s.front());
  747|      0|   }
  748|   116k|}
_ZN5Botan6detail33copy_out_any_word_aligned_portionILNS0_10EndiannessE0ETkNS0_20unsigned_integralishEmEEmRNSt3__14spanIhLm18446744073709551615EEERNS4_IKT0_Lm18446744073709551615EEE:
  718|   116k|size_t copy_out_any_word_aligned_portion(std::span<uint8_t>& out, std::span<const T>& in) {
  719|   116k|   const size_t full_words = out.size() / sizeof(T);
  720|   116k|   const size_t full_word_bytes = full_words * sizeof(T);
  721|   116k|   const size_t remaining_bytes = out.size() - full_word_bytes;
  722|   116k|   BOTAN_ASSERT_NOMSG(in.size_bytes() >= full_word_bytes + remaining_bytes);
  ------------------
  |  |   60|   116k|   do {                                                                     \
  |  |   61|   116k|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 116k]
  |  |  ------------------
  |  |   62|   116k|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|   116k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded, False: 116k]
  |  |  ------------------
  ------------------
  723|       |
  724|       |   // copy full words
  725|   116k|   store_any<endianness, T>(out.first(full_word_bytes), in.first(full_words));
  726|   116k|   out = out.subspan(full_word_bytes);
  727|   116k|   in = in.subspan(full_words);
  728|       |
  729|   116k|   return remaining_bytes;
  730|   116k|}
_ZN5Botan6detail9store_anyILNS0_10EndiannessE0EmTkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm18446744073709551615EEETkNS3_14spanable_rangeENS6_IKmLm18446744073709551615EEEQoosr3stdE7same_asINS0_10AutoDetectET0_Esr3stdE7same_asISB_NS5_11conditionalIXsr21__is_primary_templateINS5_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS5_6ranges5__cpo5beginEEclsr3stdE7declvalIRT2_EEEEEEEEE5valueENS5_26indirectly_readable_traitsISJ_EESK_E4type10value_typeEEEEvOT1_OSG_:
  569|   116k|inline constexpr void store_any(OutR&& out, InR&& in) {
  570|   116k|   ranges::assert_equal_byte_lengths(out, in);
  571|       |
  572|   116k|   auto store_elementwise = [&] {
  573|   116k|      using element_type = std::ranges::range_value_t<InR>;
  574|   116k|      constexpr size_t bytes_per_element = sizeof(element_type);
  575|   116k|      std::span<uint8_t> out_s(out);
  576|   116k|      for(auto in_elem : in) {
  577|   116k|         store_any<endianness, element_type>(out_s.template first<bytes_per_element>(), in_elem);
  578|   116k|         out_s = out_s.subspan(bytes_per_element);
  579|   116k|      }
  580|   116k|   };
  581|       |
  582|       |   // At compile time we cannot use `typecast_copy` as it uses `std::memcpy`
  583|       |   // internally to copy ranges on a byte-by-byte basis, which is not allowed
  584|       |   // in a `constexpr` context.
  585|   116k|   if(std::is_constant_evaluated()) /* TODO: C++23: if consteval {} */ {
  ------------------
  |  Branch (585:7): [Folded, False: 116k]
  ------------------
  586|      0|      store_elementwise();
  587|   116k|   } else {
  588|       |      if constexpr(is_native(endianness)) {
  589|       |         typecast_copy(out, in);
  590|   116k|      } else {
  591|   116k|         store_elementwise();
  592|   116k|      }
  593|   116k|   }
  594|   116k|}
_ZZN5Botan6detail9store_anyILNS0_10EndiannessE0EmTkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm18446744073709551615EEETkNS3_14spanable_rangeENS6_IKmLm18446744073709551615EEEQoosr3stdE7same_asINS0_10AutoDetectET0_Esr3stdE7same_asISB_NS5_11conditionalIXsr21__is_primary_templateINS5_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS5_6ranges5__cpo5beginEEclsr3stdE7declvalIRT2_EEEEEEEEE5valueENS5_26indirectly_readable_traitsISJ_EESK_E4type10value_typeEEEEvOT1_OSG_ENKUlvE_clEv:
  572|   116k|   auto store_elementwise = [&] {
  573|   116k|      using element_type = std::ranges::range_value_t<InR>;
  574|   116k|      constexpr size_t bytes_per_element = sizeof(element_type);
  575|   116k|      std::span<uint8_t> out_s(out);
  576|   935k|      for(auto in_elem : in) {
  ------------------
  |  Branch (576:24): [True: 935k, False: 116k]
  ------------------
  577|   935k|         store_any<endianness, element_type>(out_s.template first<bytes_per_element>(), in_elem);
  578|   935k|         out_s = out_s.subspan(bytes_per_element);
  579|   935k|      }
  580|   116k|   };
_ZN5Botan6detail9store_anyILNS0_10EndiannessE0EmTkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm8EEETpTkNS0_20unsigned_integralishEJmEQaagtsZT2_Li0Eooaasr3stdE7same_asINS0_10AutoDetectET0_E10all_same_vIDpT2_Eaa20unsigned_integralishIS9_E10all_same_vIS9_SB_EEEvOT1_SB_:
  548|   935k|inline constexpr void store_any(OutR&& out, Ts... ins) {
  549|   935k|   ranges::assert_exact_byte_length<(sizeof(Ts) + ...)>(out);
  550|   935k|   auto store_one = [off = 0]<typename T>(auto o, T i) mutable {
  551|   935k|      store_any<endianness, T>(i, o.subspan(off).template first<sizeof(T)>());
  552|   935k|      off += sizeof(T);
  553|   935k|   };
  554|       |
  555|   935k|   (store_one(std::span{out}, ins), ...);
  556|   935k|}
_ZZN5Botan6detail9store_anyILNS0_10EndiannessE0EmTkNS_6ranges23contiguous_output_rangeIhEENSt3__14spanIhLm8EEETpTkNS0_20unsigned_integralishEJmEQaagtsZT2_Li0Eooaasr3stdE7same_asINS0_10AutoDetectET0_E10all_same_vIDpT2_Eaa20unsigned_integralishIS9_E10all_same_vIS9_SB_EEEvOT1_SB_ENUlTyS9_T_E_clImS7_EEDaS9_SE_:
  550|   935k|   auto store_one = [off = 0]<typename T>(auto o, T i) mutable {
  551|   935k|      store_any<endianness, T>(i, o.subspan(off).template first<sizeof(T)>());
  552|   935k|      off += sizeof(T);
  553|   935k|   };

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

_ZN5Botan3rhoILm14ELm18ELm41EmEET2_S1_:
   51|  21.3M|inline constexpr T rho(T x) {
   52|  21.3M|   return rotr<R1>(x) ^ rotr<R2>(x) ^ rotr<R3>(x);
   53|  21.3M|}
_ZN5Botan4rotrILm14EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan4rotrILm18EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan4rotrILm41EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan3rhoILm28ELm34ELm39EmEET2_S1_:
   51|  21.3M|inline constexpr T rho(T x) {
   52|  21.3M|   return rotr<R1>(x) ^ rotr<R2>(x) ^ rotr<R3>(x);
   53|  21.3M|}
_ZN5Botan4rotrILm28EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan4rotrILm34EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan4rotrILm39EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan5sigmaILm19ELm61ELm6EmEET2_S1_:
   43|  21.3M|inline constexpr T sigma(T x) {
   44|  21.3M|   return rotr<R1>(x) ^ rotr<R2>(x) ^ (x >> S);
   45|  21.3M|}
_ZN5Botan4rotrILm19EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan4rotrILm61EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan5sigmaILm1ELm8ELm7EmEET2_S1_:
   43|  21.3M|inline constexpr T sigma(T x) {
   44|  21.3M|   return rotr<R1>(x) ^ rotr<R2>(x) ^ (x >> S);
   45|  21.3M|}
_ZN5Botan4rotrILm1EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}
_ZN5Botan4rotrILm8EmEET0_S1_QaagtT_Li0EltT_mlLi8EstS1_:
   35|  21.3M|{
   36|  21.3M|   return static_cast<T>((input >> ROT) | (input << (8 * sizeof(T) - ROT)));
   37|  21.3M|}

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

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

_ZNK5Botan7SHA_51213output_lengthEv:
   74|   125k|      size_t output_length() const override { return output_bytes; }
_ZNK5Botan7SHA_51215hash_block_sizeEv:
   76|  8.35k|      size_t hash_block_size() const override { return block_bytes; }
_ZN5Botan7SHA_5125clearEv:
   84|  33.4k|      void clear() override { m_md.clear(); }

_ZN5Botan9SHA2_64_FEmmmRmmmmS0_S0_mmmm:
   31|  21.3M|                                  uint64_t magic) {
   32|  21.3M|   const uint64_t E_rho = rho<14, 18, 41>(E);
   33|  21.3M|   const uint64_t A_rho = rho<28, 34, 39>(A);
   34|  21.3M|   const uint64_t M2_sigma = sigma<19, 61, 6>(M2);
   35|  21.3M|   const uint64_t M4_sigma = sigma<1, 8, 7>(M4);
   36|  21.3M|   H += magic + E_rho + choose(E, F, G) + M1;
   37|  21.3M|   D += H;
   38|  21.3M|   H += A_rho + majority(A, B, C);
   39|  21.3M|   M1 += M2_sigma + M3 + M4_sigma;
   40|  21.3M|}

_ZN5Botan12BufferSlicerC2ENSt3__14spanIKhLm18446744073709551615EEE:
  144|   584k|      BufferSlicer(std::span<const uint8_t> buffer) : m_remaining(buffer) {}
_ZN5Botan12BufferSlicer4takeEm:
  156|   576k|      std::span<const uint8_t> take(const size_t count) {
  157|   576k|         BOTAN_STATE_CHECK(remaining() >= count);
  ------------------
  |  |   42|   576k|   do {                                                         \
  |  |   43|   576k|      if(!(expr))                                               \
  |  |  ------------------
  |  |  |  Branch (43:10): [True: 0, False: 576k]
  |  |  ------------------
  |  |   44|   576k|         Botan::throw_invalid_state(#expr, __func__, __FILE__); \
  |  |   45|   576k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (45:12): [Folded, False: 576k]
  |  |  ------------------
  ------------------
  158|   576k|         auto result = m_remaining.first(count);
  159|   576k|         m_remaining = m_remaining.subspan(count);
  160|   576k|         return result;
  161|   576k|      }
_ZNK5Botan12BufferSlicer9remainingEv:
  185|  1.15M|      size_t remaining() const { return m_remaining.size(); }
_ZNK5Botan12BufferSlicer5emptyEv:
  187|   626k|      bool empty() const { return m_remaining.empty(); }

_ZN5Botan20Buffered_Computation6updateENSt3__14spanIKhLm18446744073709551615EEE:
   41|   400k|      void update(std::span<const uint8_t> in) { add_data(in); }
_ZN5Botan20Buffered_Computation6updateEh:
   62|  25.0k|      void update(uint8_t in) { add_data({&in, 1}); }
_ZN5Botan20Buffered_Computation5finalENSt3__14spanIhLm18446744073709551615EEE:
   86|   116k|      void final(std::span<uint8_t> out) {
   87|   116k|         BOTAN_ARG_CHECK(out.size() >= output_length(), "provided output buffer has insufficient capacity");
  ------------------
  |  |   30|   116k|   do {                                                          \
  |  |   31|   116k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 116k]
  |  |  ------------------
  |  |   32|   116k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|   116k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded, False: 116k]
  |  |  ------------------
  ------------------
   88|   116k|         final_result(out);
   89|   116k|      }
_ZN5Botan20Buffered_ComputationD2Ev:
  134|  16.7k|      virtual ~Buffered_Computation() = default;
_ZN5Botan20Buffered_Computation5finalITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS_16secure_allocatorIhEEEEEEvRT_:
   92|  58.4k|      void final(T& out) {
   93|  58.4k|         out.resize(output_length());
   94|  58.4k|         final_result(out);
   95|  58.4k|      }

_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeERNSt3__14spanIhLm8EEEEEvOT0_:
   97|  1.98M|inline constexpr void assert_exact_byte_length(R&& r) {
   98|  1.98M|   const std::span s{r};
   99|  1.98M|   if constexpr(statically_spanable_range<R>) {
  100|  1.98M|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
  101|       |   } else {
  102|       |      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
  103|       |   }
  104|  1.98M|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeERNSt3__14spanIhLm8EEETpTkNS0_14spanable_rangeEJRNS3_IKmLm1EEEEEEvOT_DpOT0_QgtsZT0_Li0E:
  118|  1.05M|{
  119|  1.05M|   const std::span s0{r0};
  120|       |
  121|  1.05M|   if constexpr(statically_spanable_range<R0>) {
  122|  1.05M|      constexpr size_t expected_size = s0.size_bytes();
  123|  1.05M|      (assert_exact_byte_length<expected_size>(rs), ...);
  124|       |   } else {
  125|       |      const size_t expected_size = s0.size_bytes();
  126|       |      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  127|       |                      "memory regions don't have equal lengths");
  128|       |   }
  129|  1.05M|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeERNSt3__14spanIKmLm1EEEEEvOT0_:
   97|  1.05M|inline constexpr void assert_exact_byte_length(R&& r) {
   98|  1.05M|   const std::span s{r};
   99|  1.05M|   if constexpr(statically_spanable_range<R>) {
  100|  1.05M|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
  101|       |   } else {
  102|       |      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
  103|       |   }
  104|  1.05M|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeERNSt3__14spanIhLm8EEEEEmOT_:
   84|  1.05M|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   85|  1.05M|   return std::span{r}.size_bytes();
   86|  1.05M|}
_ZN5Botan6ranges24assert_exact_byte_lengthILm8ETkNS0_14spanable_rangeERNSt3__14spanIKhLm8EEEEEvOT0_:
   97|  8.55M|inline constexpr void assert_exact_byte_length(R&& r) {
   98|  8.55M|   const std::span s{r};
   99|  8.55M|   if constexpr(statically_spanable_range<R>) {
  100|  8.55M|      static_assert(s.size_bytes() == expected, "memory region does not have expected byte lengths");
  101|       |   } else {
  102|       |      BOTAN_ASSERT(s.size_bytes() == expected, "memory region does not have expected byte lengths");
  103|       |   }
  104|  8.55M|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeERNSt3__14spanImLm1EEETpTkNS0_14spanable_rangeEJRNS3_IKhLm8EEEEEEvOT_DpOT0_QgtsZT0_Li0E:
  118|  4.27M|{
  119|  4.27M|   const std::span s0{r0};
  120|       |
  121|  4.27M|   if constexpr(statically_spanable_range<R0>) {
  122|  4.27M|      constexpr size_t expected_size = s0.size_bytes();
  123|  4.27M|      (assert_exact_byte_length<expected_size>(rs), ...);
  124|       |   } else {
  125|       |      const size_t expected_size = s0.size_bytes();
  126|       |      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  127|       |                      "memory regions don't have equal lengths");
  128|       |   }
  129|  4.27M|}
_ZN5Botan6ranges10size_bytesITkNS0_14spanable_rangeERNSt3__14spanImLm1EEEEEmOT_:
   84|  4.27M|inline constexpr size_t size_bytes(spanable_range auto&& r) {
   85|  4.27M|   return std::span{r}.size_bytes();
   86|  4.27M|}
_ZN5Botan6ranges25assert_equal_byte_lengthsITkNS0_14spanable_rangeERNSt3__14spanIhLm18446744073709551615EEETpTkNS0_14spanable_rangeEJRNS3_IKmLm18446744073709551615EEEEEEvOT_DpOT0_QgtsZT0_Li0E:
  118|   116k|{
  119|   116k|   const std::span s0{r0};
  120|       |
  121|       |   if constexpr(statically_spanable_range<R0>) {
  122|       |      constexpr size_t expected_size = s0.size_bytes();
  123|       |      (assert_exact_byte_length<expected_size>(rs), ...);
  124|   116k|   } else {
  125|   116k|      const size_t expected_size = s0.size_bytes();
  126|   116k|      BOTAN_ARG_CHECK(((std::span<const std::ranges::range_value_t<Rs>>{rs}.size_bytes() == expected_size) && ...),
  ------------------
  |  |   30|   116k|   do {                                                          \
  |  |   31|   116k|      if(!(expr))                                                \
  |  |  ------------------
  |  |  |  Branch (31:10): [True: 0, False: 116k]
  |  |  ------------------
  |  |   32|   116k|         Botan::throw_invalid_argument(msg, __func__, __FILE__); \
  |  |   33|   116k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (33:12): [Folded, False: 116k]
  |  |  ------------------
  ------------------
  127|   116k|                      "memory regions don't have equal lengths");
  128|   116k|   }
  129|   116k|}

_ZNK5Botan9HMAC_DRBG31max_number_of_bytes_per_requestEv:
  130|  8.35k|      size_t max_number_of_bytes_per_request() const override { return m_max_number_of_bytes_per_request; }

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

_ZN5Botan11clear_bytesEPvm:
  103|   342k|inline constexpr void clear_bytes(void* ptr, size_t bytes) {
  104|   342k|   if(bytes > 0) {
  ------------------
  |  Branch (104:7): [True: 342k, False: 0]
  ------------------
  105|   342k|      std::memset(ptr, 0, bytes);
  106|   342k|   }
  107|   342k|}
_ZN5Botan8copy_memIhQsr3std10is_trivialINSt3__15decayIT_E4typeEEE5valueEEvPS3_PKS3_m:
  146|  8.35k|inline constexpr void copy_mem(T* out, const T* in, size_t n) {
  147|  8.35k|   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
  ------------------
  |  |   78|  8.35k|   do {                                                                                          \
  |  |   79|  16.7k|      if((expr1) && !(expr2))                                                                    \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 8.35k, False: 0]
  |  |  |  Branch (79:23): [True: 8.35k, False: 0]
  |  |  |  Branch (79:23): [True: 8.35k, False: 0]
  |  |  ------------------
  |  |   80|  8.35k|         Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, __LINE__); \
  |  |   81|  8.35k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (81:12): [Folded, False: 8.35k]
  |  |  ------------------
  ------------------
  148|       |
  149|  8.35k|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (149:7): [True: 8.35k, False: 0]
  |  Branch (149:24): [True: 8.35k, False: 0]
  |  Branch (149:42): [True: 8.35k, False: 0]
  ------------------
  150|  8.35k|      std::memmove(out, in, sizeof(T) * n);
  151|  8.35k|   }
  152|  8.35k|}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm8EEEmQaaaasr3stdE23is_trivially_copyable_vIT0_Entsr3std6rangesE5rangeIS6_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEEEvOSB_RKS6_:
  201|  1.05M|inline constexpr void typecast_copy(ToR&& out, const FromT& in) {
  202|  1.05M|   typecast_copy(out, std::span<const FromT, 1>(&in, 1));
  203|  1.05M|}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeERNSt3__14spanIhLm8EEETkNS1_16contiguous_rangeENS3_IKmLm1EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_:
  178|  1.05M|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  179|  1.05M|   ranges::assert_equal_byte_lengths(out, in);
  180|  1.05M|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  181|  1.05M|}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm8EEEQaaaasr3stdE26is_default_constructible_vIT_Esr3stdE23is_trivially_copyable_vIS7_Esr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEEES7_OSC_:
  212|  4.27M|inline constexpr ToT typecast_copy(FromR&& src) noexcept {
  213|  4.27M|   ToT dst;
  214|  4.27M|   typecast_copy(dst, src);
  215|  4.27M|   return dst;
  216|  4.27M|}
_ZN5Botan13typecast_copyImTkNS_6ranges16contiguous_rangeERNSt3__14spanIKhLm8EEEQaaaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISE_EESF_E4type10value_typeEEsr3stdE23is_trivially_copyable_vIT_Entsr3std6rangesE5rangeISL_EEEvRSL_OSB_:
  190|  4.27M|inline constexpr void typecast_copy(ToT& out, FromR&& in) noexcept {
  191|  4.27M|   typecast_copy(std::span<ToT, 1>(&out, 1), in);
  192|  4.27M|}
_ZN5Botan13typecast_copyITkNS_6ranges23contiguous_output_rangeENSt3__14spanImLm1EEETkNS1_16contiguous_rangeERNS3_IKhLm8EEEQaasr3stdE23is_trivially_copyable_vINS2_11conditionalIXsr21__is_primary_templateINS2_15iterator_traitsIu14__remove_cvrefIDTclL_ZNS2_6ranges5__cpo5beginEEclsr3stdE7declvalIRT0_EEEEEEEEE5valueENS2_26indirectly_readable_traitsISF_EESG_E4type10value_typeEEsr3stdE23is_trivially_copyable_vINS8_IXsr21__is_primary_templateINS9_Iu14__remove_cvrefIDTclL_ZNSB_5beginEEclsr3stdE7declvalIRT_EEEEEEEEE5valueENSH_ISP_EESQ_E4type10value_typeEEEEvOSM_OSC_:
  178|  4.27M|inline constexpr void typecast_copy(ToR&& out, FromR&& in) {
  179|  4.27M|   ranges::assert_equal_byte_lengths(out, in);
  180|  4.27M|   std::memcpy(std::ranges::data(out), std::ranges::data(in), ranges::size_bytes(out));
  181|  4.27M|}
_ZN5Botan9clear_memIhEEvPT_m:
  120|   342k|inline constexpr void clear_mem(T* ptr, size_t n) {
  121|   342k|   clear_bytes(ptr, sizeof(T) * n);
  122|   342k|}
_ZN5Botan8copy_memIiQsr3std10is_trivialINSt3__15decayIT_E4typeEEE5valueEEvPS3_PKS3_m:
  146|  1.53k|inline constexpr void copy_mem(T* out, const T* in, size_t n) {
  147|  1.53k|   BOTAN_ASSERT_IMPLICATION(n > 0, in != nullptr && out != nullptr, "If n > 0 then args are not null");
  ------------------
  |  |   78|  1.53k|   do {                                                                                          \
  |  |   79|  3.07k|      if((expr1) && !(expr2))                                                                    \
  |  |  ------------------
  |  |  |  Branch (79:10): [True: 1.53k, False: 0]
  |  |  |  Branch (79:23): [True: 1.53k, False: 0]
  |  |  |  Branch (79:23): [True: 1.53k, False: 0]
  |  |  ------------------
  |  |   80|  1.53k|         Botan::assertion_failure(#expr1 " implies " #expr2, msg, __func__, __FILE__, __LINE__); \
  |  |   81|  1.53k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (81:12): [Folded, False: 1.53k]
  |  |  ------------------
  ------------------
  148|       |
  149|  1.53k|   if(in != nullptr && out != nullptr && n > 0) {
  ------------------
  |  Branch (149:7): [True: 1.53k, False: 0]
  |  Branch (149:24): [True: 1.53k, False: 0]
  |  Branch (149:42): [True: 1.53k, False: 0]
  ------------------
  150|  1.53k|      std::memmove(out, in, sizeof(T) * n);
  151|  1.53k|   }
  152|  1.53k|}

_ZN5Botan21RandomNumberGenerator10random_vecITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS_16secure_allocatorIhEEEEEEvRT_m:
  190|  8.35k|      void random_vec(T& v, size_t bytes) {
  191|  8.35k|         v.resize(bytes);
  192|  8.35k|         random_vec(v);
  193|  8.35k|      }
_ZN5Botan21RandomNumberGenerator10random_vecENSt3__14spanIhLm18446744073709551615EEE:
  179|  8.35k|      void random_vec(std::span<uint8_t> v) { this->randomize(v); }
_ZN5Botan21RandomNumberGenerator9randomizeENSt3__14spanIhLm18446744073709551615EEE:
   52|  8.35k|      void randomize(std::span<uint8_t> output) { this->fill_bytes_with_input(output, {}); }
_ZN5Botan21RandomNumberGenerator11add_entropyENSt3__14spanIKhLm18446744073709551615EEE:
   75|  8.35k|      void add_entropy(std::span<const uint8_t> input) { this->fill_bytes_with_input({}, input); }
_ZN5Botan21RandomNumberGenerator9next_byteEv:
  217|  8.35k|      uint8_t next_byte() {
  218|  8.35k|         uint8_t b;
  219|  8.35k|         this->fill_bytes_with_input(std::span(&b, 1), {});
  220|  8.35k|         return b;
  221|  8.35k|      }
_ZN5Botan21RandomNumberGeneratorC2Ev:
   34|  16.7k|      RandomNumberGenerator() = default;
_ZN5Botan21RandomNumberGeneratorD2Ev:
   32|  16.7k|      virtual ~RandomNumberGenerator() = default;
_ZN5Botan21RandomNumberGenerator10random_vecITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS_16secure_allocatorIhEEEEQsr3stdE21default_initializableIT_EEES8_m:
  205|  8.35k|      T random_vec(size_t bytes) {
  206|  8.35k|         T result;
  207|  8.35k|         random_vec(result, bytes);
  208|  8.35k|         return result;
  209|  8.35k|      }

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

_ZN5Botan12Stateful_RNGC2ERNS_21RandomNumberGeneratorEm:
   45|  8.35k|            m_underlying_rng(&rng), m_reseed_interval(reseed_interval) {}
_ZNK5Botan12Stateful_RNG13accepts_inputEv:
   71|  8.35k|      bool accepts_input() const final { return true; }

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

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

_ZN9Botan_FFI15ffi_guard_thunkEPKcRKNSt3__18functionIFivEEE:
  116|  8.35k|int ffi_guard_thunk(const char* func_name, const std::function<int()>& thunk) {
  117|  8.35k|   g_last_exception_what.clear();
  118|       |
  119|  8.35k|   try {
  120|  8.35k|      return thunk();
  121|  8.35k|   } catch(std::bad_alloc&) {
  122|      0|      return ffi_error_exception_thrown(func_name, "bad_alloc", BOTAN_FFI_ERROR_OUT_OF_MEMORY);
  123|      0|   } catch(Botan_FFI::FFI_Error& e) {
  124|      0|      return ffi_error_exception_thrown(func_name, e.what(), e.error_code());
  125|      0|   } catch(Botan::Exception& e) {
  126|      0|      return ffi_error_exception_thrown(func_name, e.what(), ffi_map_error_type(e.error_type()));
  127|      0|   } catch(std::exception& e) {
  128|      0|      return ffi_error_exception_thrown(func_name, e.what());
  129|      0|   } catch(...) {
  130|      0|      return ffi_error_exception_thrown(func_name, "unknown exception");
  131|      0|   }
  132|       |
  133|      0|   return BOTAN_FFI_ERROR_UNKNOWN_ERROR;
  134|  8.35k|}
botan_scrub_mem:
  308|  14.3k|int botan_scrub_mem(void* mem, size_t bytes) {
  309|  14.3k|   Botan::secure_scrub_memory(mem, bytes);
  310|  14.3k|   return BOTAN_FFI_SUCCESS;
  311|  14.3k|}

botan_rng_init:
   26|  4.17k|int botan_rng_init(botan_rng_t* rng_out, const char* rng_type) {
   27|  4.17k|   return ffi_guard_thunk(__func__, [=]() -> int {
   28|  4.17k|      if(rng_out == nullptr) {
   29|  4.17k|         return BOTAN_FFI_ERROR_NULL_POINTER;
   30|  4.17k|      }
   31|       |
   32|  4.17k|      const std::string rng_type_s(rng_type ? rng_type : "system");
   33|       |
   34|  4.17k|      std::unique_ptr<Botan::RandomNumberGenerator> rng;
   35|       |
   36|  4.17k|      if(rng_type_s == "system") {
   37|  4.17k|         rng = std::make_unique<Botan::System_RNG>();
   38|  4.17k|      } else if(rng_type_s == "user" || rng_type_s == "user-threadsafe") {
   39|  4.17k|         rng = std::make_unique<Botan::AutoSeeded_RNG>();
   40|  4.17k|      } else if(rng_type_s == "null") {
   41|  4.17k|         rng = std::make_unique<Botan::Null_RNG>();
   42|  4.17k|      }
   43|       |#if defined(BOTAN_HAS_PROCESSOR_RNG)
   44|       |      else if((rng_type_s == "rdrand" || rng_type_s == "hwrng") && Botan::Processor_RNG::available()) {
   45|       |         rng = std::make_unique<Botan::Processor_RNG>();
   46|       |      }
   47|       |#endif
   48|       |
   49|  4.17k|      if(!rng) {
   50|  4.17k|         return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
   51|  4.17k|      }
   52|       |
   53|  4.17k|      *rng_out = new botan_rng_struct(std::move(rng));
   54|  4.17k|      return BOTAN_FFI_SUCCESS;
   55|  4.17k|   });
   56|  4.17k|}
botan_rng_destroy:
  143|  4.17k|int botan_rng_destroy(botan_rng_t rng) {
  144|  4.17k|   return BOTAN_FFI_CHECKED_DELETE(rng);
  ------------------
  |  |  143|  4.17k|#define BOTAN_FFI_CHECKED_DELETE(o) ffi_delete_object(o, __func__)
  ------------------
  145|  4.17k|}
ffi_rng.cpp:_ZZ14botan_rng_initENK3$_0clEv:
   27|  4.17k|   return ffi_guard_thunk(__func__, [=]() -> int {
   28|  4.17k|      if(rng_out == nullptr) {
  ------------------
  |  Branch (28:10): [True: 0, False: 4.17k]
  ------------------
   29|      0|         return BOTAN_FFI_ERROR_NULL_POINTER;
   30|      0|      }
   31|       |
   32|  4.17k|      const std::string rng_type_s(rng_type ? rng_type : "system");
  ------------------
  |  Branch (32:36): [True: 4.17k, False: 0]
  ------------------
   33|       |
   34|  4.17k|      std::unique_ptr<Botan::RandomNumberGenerator> rng;
   35|       |
   36|  4.17k|      if(rng_type_s == "system") {
  ------------------
  |  Branch (36:10): [True: 0, False: 4.17k]
  ------------------
   37|      0|         rng = std::make_unique<Botan::System_RNG>();
   38|  4.17k|      } else if(rng_type_s == "user" || rng_type_s == "user-threadsafe") {
  ------------------
  |  Branch (38:17): [True: 4.17k, False: 0]
  |  Branch (38:41): [True: 0, False: 0]
  ------------------
   39|  4.17k|         rng = std::make_unique<Botan::AutoSeeded_RNG>();
   40|  4.17k|      } else if(rng_type_s == "null") {
  ------------------
  |  Branch (40:17): [True: 0, False: 0]
  ------------------
   41|      0|         rng = std::make_unique<Botan::Null_RNG>();
   42|      0|      }
   43|       |#if defined(BOTAN_HAS_PROCESSOR_RNG)
   44|       |      else if((rng_type_s == "rdrand" || rng_type_s == "hwrng") && Botan::Processor_RNG::available()) {
   45|       |         rng = std::make_unique<Botan::Processor_RNG>();
   46|       |      }
   47|       |#endif
   48|       |
   49|  4.17k|      if(!rng) {
  ------------------
  |  Branch (49:10): [True: 0, False: 4.17k]
  ------------------
   50|      0|         return BOTAN_FFI_ERROR_NOT_IMPLEMENTED;
   51|      0|      }
   52|       |
   53|  4.17k|      *rng_out = new botan_rng_struct(std::move(rng));
   54|  4.17k|      return BOTAN_FFI_SUCCESS;
   55|  4.17k|   });

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

_ZN5Botan7SHA_51215compress_digestERNSt3__16vectorImNS_16secure_allocatorImEEEENS1_4spanIKhLm18446744073709551615EEEm:
   43|   267k|void SHA_512::compress_digest(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
   44|       |#if defined(BOTAN_HAS_SHA2_64_BMI2)
   45|       |   if(CPUID::has_bmi2()) {
   46|       |      return compress_digest_bmi2(digest, input, blocks);
   47|       |   }
   48|       |#endif
   49|       |
   50|       |#if defined(BOTAN_HAS_SHA2_64_ARMV8)
   51|       |   if(CPUID::has_arm_sha2_512()) {
   52|       |      return compress_digest_armv8(digest, input, blocks);
   53|       |   }
   54|       |#endif
   55|       |
   56|   267k|   uint64_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], G = digest[6],
   57|   267k|            H = digest[7];
   58|       |
   59|   267k|   BufferSlicer in(input);
   60|       |
   61|   534k|   for(size_t i = 0; i != blocks; ++i) {
  ------------------
  |  Branch (61:22): [True: 267k, False: 267k]
  ------------------
   62|   267k|      const auto block = in.take(block_bytes);
   63|       |
   64|   267k|      uint64_t W00 = load_be<uint64_t>(block.data(), 0);
   65|   267k|      uint64_t W01 = load_be<uint64_t>(block.data(), 1);
   66|   267k|      uint64_t W02 = load_be<uint64_t>(block.data(), 2);
   67|   267k|      uint64_t W03 = load_be<uint64_t>(block.data(), 3);
   68|   267k|      uint64_t W04 = load_be<uint64_t>(block.data(), 4);
   69|   267k|      uint64_t W05 = load_be<uint64_t>(block.data(), 5);
   70|   267k|      uint64_t W06 = load_be<uint64_t>(block.data(), 6);
   71|   267k|      uint64_t W07 = load_be<uint64_t>(block.data(), 7);
   72|   267k|      uint64_t W08 = load_be<uint64_t>(block.data(), 8);
   73|   267k|      uint64_t W09 = load_be<uint64_t>(block.data(), 9);
   74|   267k|      uint64_t W10 = load_be<uint64_t>(block.data(), 10);
   75|   267k|      uint64_t W11 = load_be<uint64_t>(block.data(), 11);
   76|   267k|      uint64_t W12 = load_be<uint64_t>(block.data(), 12);
   77|   267k|      uint64_t W13 = load_be<uint64_t>(block.data(), 13);
   78|   267k|      uint64_t W14 = load_be<uint64_t>(block.data(), 14);
   79|   267k|      uint64_t W15 = load_be<uint64_t>(block.data(), 15);
   80|       |
   81|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98D728AE22);
   82|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x7137449123EF65CD);
   83|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCFEC4D3B2F);
   84|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA58189DBBC);
   85|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25BF348B538);
   86|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1B605D019);
   87|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4AF194F9B);
   88|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5DA6D8118);
   89|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98A3030242);
   90|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B0145706FBE);
   91|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE4EE4B28C);
   92|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3D5FFB4E2);
   93|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74F27B896F);
   94|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE3B1696B1);
   95|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A725C71235);
   96|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174CF692694);
   97|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C19EF14AD2);
   98|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786384F25E3);
   99|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC68B8CD5B5);
  100|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC77AC9C65);
  101|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F592B0275);
  102|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA6EA6E483);
  103|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DCBD41FBD4);
  104|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA831153B5);
  105|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152EE66DFAB);
  106|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D2DB43210);
  107|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C898FB213F);
  108|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7BEEF0EE4);
  109|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF33DA88FC2);
  110|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147930AA725);
  111|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351E003826F);
  112|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x142929670A0E6E70);
  113|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A8546D22FFC);
  114|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B21385C26C926);
  115|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC5AC42AED);
  116|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D139D95B3DF);
  117|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A73548BAF63DE);
  118|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB3C77B2A8);
  119|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E47EDAEE6);
  120|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C851482353B);
  121|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A14CF10364);
  122|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664BBC423001);
  123|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70D0F89791);
  124|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A30654BE30);
  125|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819D6EF5218);
  126|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD69906245565A910);
  127|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E35855771202A);
  128|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA07032BBD1B8);
  129|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116B8D2D0C8);
  130|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C085141AB53);
  131|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774CDF8EEB99);
  132|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5E19B48A8);
  133|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3C5C95A63);
  134|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4AE3418ACB);
  135|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F7763E373);
  136|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3D6B2B8A3);
  137|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE5DEFB2FC);
  138|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F43172F60);
  139|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814A1F0AB72);
  140|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC702081A6439EC);
  141|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA23631E28);
  142|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEBDE82BDE9);
  143|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7B2C67915);
  144|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2E372532B);
  145|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xCA273ECEEA26619C);
  146|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xD186B8C721C0C207);
  147|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xEADA7DD6CDE0EB1E);
  148|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xF57D4F7FEE6ED178);
  149|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x06F067AA72176FBA);
  150|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x0A637DC5A2C898A6);
  151|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x113F9804BEF90DAE);
  152|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x1B710B35131C471B);
  153|   267k|      SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x28DB77F523047D84);
  154|   267k|      SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x32CAAB7B40C72493);
  155|   267k|      SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x3C9EBE0A15C9BEBC);
  156|   267k|      SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x431D67C49C100D4C);
  157|   267k|      SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x4CC5D4BECB3E42B6);
  158|   267k|      SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x597F299CFC657E2A);
  159|   267k|      SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x5FCB6FAB3AD6FAEC);
  160|   267k|      SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x6C44198C4A475817);
  161|       |
  162|   267k|      A = (digest[0] += A);
  163|   267k|      B = (digest[1] += B);
  164|   267k|      C = (digest[2] += C);
  165|   267k|      D = (digest[3] += D);
  166|   267k|      E = (digest[4] += E);
  167|   267k|      F = (digest[5] += F);
  168|   267k|      G = (digest[6] += G);
  169|   267k|      H = (digest[7] += H);
  170|   267k|   }
  171|   267k|}
_ZN5Botan7SHA_51210compress_nERNSt3__16vectorImNS_16secure_allocatorImEEEENS1_4spanIKhLm18446744073709551615EEEm:
  193|   267k|void SHA_512::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
  194|   267k|   SHA_512::compress_digest(digest, input, blocks);
  195|   267k|}
_ZN5Botan7SHA_5124initERNSt3__16vectorImNS_16secure_allocatorImEEEE:
  219|   158k|void SHA_512::init(digest_type& digest) {
  220|   158k|   digest.assign({0x6A09E667F3BCC908,
  221|   158k|                  0xBB67AE8584CAA73B,
  222|   158k|                  0x3C6EF372FE94F82B,
  223|   158k|                  0xA54FF53A5F1D36F1,
  224|   158k|                  0x510E527FADE682D1,
  225|   158k|                  0x9B05688C2B3E6C1F,
  226|   158k|                  0x1F83D9ABFB41BD6B,
  227|   158k|                  0x5BE0CD19137E2179});
  228|   158k|}
_ZN5Botan7SHA_5128add_dataENSt3__14spanIKhLm18446744073709551615EEE:
  258|   317k|void SHA_512::add_data(std::span<const uint8_t> input) {
  259|   317k|   m_md.update(input);
  260|   317k|}
_ZN5Botan7SHA_51212final_resultENSt3__14spanIhLm18446744073709551615EEE:
  270|   116k|void SHA_512::final_result(std::span<uint8_t> output) {
  271|   116k|   m_md.final(output);
  272|   116k|}

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

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

_ZN5Botan14AutoSeeded_RNGD2Ev:
   42|  8.35k|AutoSeeded_RNG::~AutoSeeded_RNG() = default;
_ZN5Botan14AutoSeeded_RNGC2ERNS_21RandomNumberGeneratorEm:
   44|  8.35k|AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng, size_t reseed_interval) {
   45|  8.35k|   m_rng = std::make_unique<HMAC_DRBG>(auto_rng_hmac(), underlying_rng, reseed_interval);
   46|       |
   47|  8.35k|   force_reseed();
   48|  8.35k|}
_ZN5Botan14AutoSeeded_RNGC2Em:
   66|  8.35k|      AutoSeeded_RNG(system_rng(), reseed_interval)
   67|       |#else
   68|       |      AutoSeeded_RNG(Entropy_Sources::global_sources(), reseed_interval)
   69|       |#endif
   70|  8.35k|{
   71|  8.35k|}
_ZN5Botan14AutoSeeded_RNG12force_reseedEv:
   73|  8.35k|void AutoSeeded_RNG::force_reseed() {
   74|  8.35k|   m_rng->force_reseed();
   75|  8.35k|   m_rng->next_byte();
   76|       |
   77|  8.35k|   if(!m_rng->is_seeded()) {
  ------------------
  |  Branch (77:7): [True: 0, False: 8.35k]
  ------------------
   78|      0|      throw Internal_Error("AutoSeeded_RNG reseeding failed");
   79|      0|   }
   80|  8.35k|}
auto_rng.cpp:_ZN5Botan12_GLOBAL__N_113auto_rng_hmacEv:
   24|  8.35k|std::unique_ptr<MessageAuthenticationCode> auto_rng_hmac() {
   25|  8.35k|   const std::string possible_auto_rng_hmacs[] = {
   26|  8.35k|      "HMAC(SHA-512)",
   27|  8.35k|      "HMAC(SHA-256)",
   28|  8.35k|   };
   29|       |
   30|  8.35k|   for(const auto& hmac : possible_auto_rng_hmacs) {
  ------------------
  |  Branch (30:25): [True: 8.35k, False: 0]
  ------------------
   31|  8.35k|      if(auto mac = MessageAuthenticationCode::create_or_throw(hmac)) {
  ------------------
  |  Branch (31:15): [True: 8.35k, False: 0]
  ------------------
   32|  8.35k|         return mac;
   33|  8.35k|      }
   34|  8.35k|   }
   35|       |
   36|       |   // This shouldn't happen since this module has a dependency on sha2_32
   37|      0|   throw Internal_Error("AutoSeeded_RNG: No usable HMAC hash found");
   38|  8.35k|}

_ZN5Botan9HMAC_DRBGC2ENSt3__110unique_ptrINS_25MessageAuthenticationCodeENS1_14default_deleteIS3_EEEERNS_21RandomNumberGeneratorEmm:
   50|  8.35k|      Stateful_RNG(underlying_rng, reseed_interval),
   51|  8.35k|      m_mac(std::move(prf)),
   52|  8.35k|      m_max_number_of_bytes_per_request(max_number_of_bytes_per_request),
   53|  8.35k|      m_security_level(hmac_drbg_security_level(m_mac->output_length())) {
   54|  8.35k|   BOTAN_ASSERT_NONNULL(m_mac);
  ------------------
  |  |   87|  8.35k|   do {                                                                                   \
  |  |   88|  8.35k|      if((ptr) == nullptr)                                                                \
  |  |  ------------------
  |  |  |  Branch (88:10): [True: 0, False: 8.35k]
  |  |  ------------------
  |  |   89|  8.35k|         Botan::assertion_failure(#ptr " is not null", "", __func__, __FILE__, __LINE__); \
  |  |   90|  8.35k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (90:12): [Folded, False: 8.35k]
  |  |  ------------------
  ------------------
   55|       |
   56|  8.35k|   check_limits(reseed_interval, max_number_of_bytes_per_request);
   57|       |
   58|  8.35k|   clear();
   59|  8.35k|}
_ZN5Botan9HMAC_DRBG11clear_stateEv:
  109|  8.35k|void HMAC_DRBG::clear_state() {
  110|  8.35k|   if(m_V.empty()) {
  ------------------
  |  Branch (110:7): [True: 8.35k, False: 0]
  ------------------
  111|  8.35k|      const size_t output_length = m_mac->output_length();
  112|  8.35k|      m_V.resize(output_length);
  113|  8.35k|   }
  114|       |
  115|   543k|   for(size_t i = 0; i != m_V.size(); ++i) {
  ------------------
  |  Branch (115:22): [True: 534k, False: 8.35k]
  ------------------
  116|   534k|      m_V[i] = 0x01;
  117|   534k|   }
  118|  8.35k|   m_mac->set_key(std::vector<uint8_t>(m_V.size(), 0x00));
  119|  8.35k|}
_ZN5Botan9HMAC_DRBG15generate_outputENSt3__14spanIhLm18446744073709551615EEENS2_IKhLm18446744073709551615EEE:
  129|  8.35k|void HMAC_DRBG::generate_output(std::span<uint8_t> output, std::span<const uint8_t> input) {
  130|  8.35k|   BOTAN_ASSERT_NOMSG(!output.empty());
  ------------------
  |  |   60|  8.35k|   do {                                                                     \
  |  |   61|  8.35k|      if(!(expr))                                                           \
  |  |  ------------------
  |  |  |  Branch (61:10): [True: 0, False: 8.35k]
  |  |  ------------------
  |  |   62|  8.35k|         Botan::assertion_failure(#expr, "", __func__, __FILE__, __LINE__); \
  |  |   63|  8.35k|   } while(0)
  |  |  ------------------
  |  |  |  Branch (63:12): [Folded, False: 8.35k]
  |  |  ------------------
  ------------------
  131|       |
  132|  8.35k|   if(!input.empty()) {
  ------------------
  |  Branch (132:7): [True: 0, False: 8.35k]
  ------------------
  133|      0|      update(input);
  134|      0|   }
  135|       |
  136|  16.7k|   while(!output.empty()) {
  ------------------
  |  Branch (136:10): [True: 8.35k, False: 8.35k]
  ------------------
  137|  8.35k|      const size_t to_copy = std::min(output.size(), m_V.size());
  138|  8.35k|      m_mac->update(m_V);
  139|  8.35k|      m_mac->final(m_V);
  140|  8.35k|      copy_mem(output.data(), m_V.data(), to_copy);
  141|       |
  142|  8.35k|      output = output.subspan(to_copy);
  143|  8.35k|   }
  144|       |
  145|  8.35k|   update(input);
  146|  8.35k|}
_ZN5Botan9HMAC_DRBG6updateENSt3__14spanIKhLm18446744073709551615EEE:
  152|  16.7k|void HMAC_DRBG::update(std::span<const uint8_t> input) {
  153|  16.7k|   secure_vector<uint8_t> T(m_V.size());
  154|  16.7k|   m_mac->update(m_V);
  155|  16.7k|   m_mac->update(0x00);
  156|  16.7k|   m_mac->update(input);
  157|  16.7k|   m_mac->final(T);
  158|  16.7k|   m_mac->set_key(T);
  159|       |
  160|  16.7k|   m_mac->update(m_V);
  161|  16.7k|   m_mac->final(m_V);
  162|       |
  163|  16.7k|   if(!input.empty()) {
  ------------------
  |  Branch (163:7): [True: 8.35k, False: 8.35k]
  ------------------
  164|  8.35k|      m_mac->update(m_V);
  165|  8.35k|      m_mac->update(0x01);
  166|  8.35k|      m_mac->update(input);
  167|  8.35k|      m_mac->final(T);
  168|  8.35k|      m_mac->set_key(T);
  169|       |
  170|  8.35k|      m_mac->update(m_V);
  171|  8.35k|      m_mac->final(m_V);
  172|  8.35k|   }
  173|  16.7k|}
_ZNK5Botan9HMAC_DRBG14security_levelEv:
  175|  25.0k|size_t HMAC_DRBG::security_level() const {
  176|  25.0k|   return m_security_level;
  177|  25.0k|}
hmac_drbg.cpp:_ZN5Botan12_GLOBAL__N_124hmac_drbg_security_levelEm:
   17|  8.35k|size_t hmac_drbg_security_level(size_t mac_output_length) {
   18|       |   // security strength of the hash function
   19|       |   // for pre-image resistance (see NIST SP 800-57)
   20|       |   // SHA-1: 128 bits
   21|       |   // SHA-224, SHA-512/224: 192 bits,
   22|       |   // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits
   23|       |   // NIST SP 800-90A only supports up to 256 bits though
   24|       |
   25|  8.35k|   if(mac_output_length < 32) {
  ------------------
  |  Branch (25:7): [True: 0, False: 8.35k]
  ------------------
   26|      0|      return (mac_output_length - 4) * 8;
   27|  8.35k|   } else {
   28|  8.35k|      return 32 * 8;
   29|  8.35k|   }
   30|  8.35k|}
hmac_drbg.cpp:_ZN5Botan12_GLOBAL__N_112check_limitsEmm:
   32|  8.35k|void check_limits(size_t reseed_interval, size_t max_number_of_bytes_per_request) {
   33|       |   // SP800-90A permits up to 2^48, but it is not usable on 32 bit
   34|       |   // platforms, so we only allow up to 2^24, which is still reasonably high
   35|  8.35k|   if(reseed_interval == 0 || reseed_interval > static_cast<size_t>(1) << 24) {
  ------------------
  |  Branch (35:7): [True: 0, False: 8.35k]
  |  Branch (35:31): [True: 0, False: 8.35k]
  ------------------
   36|      0|      throw Invalid_Argument("Invalid value for reseed_interval");
   37|      0|   }
   38|       |
   39|  8.35k|   if(max_number_of_bytes_per_request == 0 || max_number_of_bytes_per_request > 64 * 1024) {
  ------------------
  |  Branch (39:7): [True: 0, False: 8.35k]
  |  Branch (39:47): [True: 0, False: 8.35k]
  ------------------
   40|      0|      throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
   41|      0|   }
   42|  8.35k|}

_ZN5Botan21RandomNumberGenerator15reseed_from_rngERS0_m:
   57|  8.35k|void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits) {
   58|  8.35k|   if(this->accepts_input()) {
  ------------------
  |  Branch (58:7): [True: 8.35k, False: 0]
  ------------------
   59|  8.35k|      this->add_entropy(rng.random_vec(poll_bits / 8));
   60|  8.35k|   }
   61|  8.35k|}

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

_ZN5Botan10system_rngEv:
  368|  8.35k|RandomNumberGenerator& system_rng() {
  369|  8.35k|   static System_RNG_Impl g_system_rng;
  370|  8.35k|   return g_system_rng;
  371|  8.35k|}
system_rng.cpp:_ZN5Botan12_GLOBAL__N_115System_RNG_Impl21fill_bytes_with_inputENSt3__14spanIhLm18446744073709551615EEENS3_IKhLm18446744073709551615EEE:
  210|  8.35k|      void fill_bytes_with_input(std::span<uint8_t> output, std::span<const uint8_t> /* ignored */) override {
  211|  8.35k|         const unsigned int flags = 0;
  212|       |
  213|  8.35k|         uint8_t* buf = output.data();
  214|  8.35k|         size_t len = output.size();
  215|  16.7k|         while(len > 0) {
  ------------------
  |  Branch (215:16): [True: 8.35k, False: 8.35k]
  ------------------
  216|       |   #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 25
  217|       |            const ssize_t got = ::syscall(SYS_getrandom, buf, len, flags);
  218|       |   #else
  219|  8.35k|            const ssize_t got = ::getrandom(buf, len, flags);
  220|  8.35k|   #endif
  221|       |
  222|  8.35k|            if(got < 0) {
  ------------------
  |  Branch (222:16): [True: 0, False: 8.35k]
  ------------------
  223|      0|               if(errno == EINTR) {
  ------------------
  |  Branch (223:19): [True: 0, False: 0]
  ------------------
  224|      0|                  continue;
  225|      0|               }
  226|      0|               throw System_Error("System_RNG getrandom failed", errno);
  227|      0|            }
  228|       |
  229|  8.35k|            buf += got;
  230|  8.35k|            len -= got;
  231|  8.35k|         }
  232|  8.35k|      }

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

_ZN5Botan19secure_scrub_memoryEPvm:
   87|  81.1k|void secure_scrub_memory(void* ptr, size_t n) {
   88|       |#if defined(BOTAN_TARGET_OS_HAS_RTLSECUREZEROMEMORY)
   89|       |   ::RtlSecureZeroMemory(ptr, n);
   90|       |
   91|       |#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO)
   92|       |   ::explicit_bzero(ptr, n);
   93|       |
   94|       |#elif defined(BOTAN_TARGET_OS_HAS_EXPLICIT_MEMSET)
   95|       |   (void)::explicit_memset(ptr, 0, n);
   96|       |
   97|       |#elif defined(BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO) && (BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO == 1)
   98|       |   /*
   99|       |   Call memset through a static volatile pointer, which the compiler
  100|       |   should not elide. This construct should be safe in conforming
  101|       |   compilers, but who knows. I did confirm that on x86-64 GCC 6.1 and
  102|       |   Clang 3.8 both create code that saves the memset address in the
  103|       |   data segment and unconditionally loads and jumps to that address.
  104|       |   */
  105|       |   static void* (*const volatile memset_ptr)(void*, int, size_t) = std::memset;
  106|       |   (memset_ptr)(ptr, 0, n);
  107|       |#else
  108|       |
  109|       |   volatile uint8_t* p = reinterpret_cast<volatile uint8_t*>(ptr);
  110|       |
  111|       |   for(size_t i = 0; i != n; ++i)
  112|       |      p[i] = 0;
  113|       |#endif
  114|  81.1k|}
_ZN5Botan2OS14get_process_idEv:
  116|  8.35k|uint32_t OS::get_process_id() {
  117|  8.35k|#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
  118|  8.35k|   return ::getpid();
  119|       |#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
  120|       |   return ::GetCurrentProcessId();
  121|       |#elif defined(BOTAN_TARGET_OS_IS_LLVM) || defined(BOTAN_TARGET_OS_IS_NONE)
  122|       |   return 0;  // truly no meaningful value
  123|       |#else
  124|       |   #error "Missing get_process_id"
  125|       |#endif
  126|  8.35k|}

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

_ZN3rnp8KeyStoreC2ERNS_15SecurityContextE:
   80|  4.17k|    KeyStore(SecurityContext &ctx) : path(""), format(KeyFormat::Unknown), secctx(ctx){};

_ZN3rnp11str_case_eqEPKcS1_:
   83|  3.84k|{
   84|  8.02k|    while (*s1 && *s2) {
  ------------------
  |  Branch (84:12): [True: 6.81k, False: 1.21k]
  |  Branch (84:19): [True: 6.81k, False: 4]
  ------------------
   85|  6.81k|        if (std::tolower(*s1) != std::tolower(*s2)) {
  ------------------
  |  Branch (85:13): [True: 2.63k, False: 4.17k]
  ------------------
   86|  2.63k|            return false;
   87|  2.63k|        }
   88|  4.17k|        s1++;
   89|  4.17k|        s2++;
   90|  4.17k|    }
   91|  1.21k|    return !*s1 && !*s2;
  ------------------
  |  Branch (91:12): [True: 1.21k, False: 4]
  |  Branch (91:20): [True: 1.10k, False: 109]
  ------------------
   92|  3.84k|}

LLVMFuzzerTestOneInput:
   42|  4.17k|{
   43|  4.17k|    rnp::SecurityContext ctx;
   44|  4.17k|    rnp::KeyStore        ks(ctx);
   45|  4.17k|    pgp_source_t         memsrc = {};
   46|       |
   47|  4.17k|    init_mem_src(&memsrc, data, size, false);
   48|  4.17k|    ks.load_g10(memsrc);
   49|  4.17k|    memsrc.close();
   50|       |
   51|  4.17k|    return 0;
   52|  4.17k|}

_ZN3rnp12backend_initEPPv:
  179|  4.17k|{
  180|  4.17k|    return true;
  181|  4.17k|}
_ZN3rnp14backend_finishEPv:
  185|  4.17k|{
  186|       |    // Do nothing
  187|  4.17k|}

_ZN3pgp3dsa3Key12clear_secretEv:
   56|    148|    {
   57|    148|        x.forget();
   58|    148|    }
_ZN3pgp3dsa3KeyD2Ev:
   61|    144|    {
   62|    144|        clear_secret();
   63|    144|    }

_ZN3pgp2ec3Key12clear_secretEv:
  125|    152|    {
  126|    152|        x.forget();
  127|    152|    }
_ZN3pgp2ec3KeyD2Ev:
  130|    149|    {
  131|    149|        clear_secret();
  132|    149|    }

_ZN3pgp2eg3Key12clear_secretEv:
   62|    312|    {
   63|    312|        x.forget();
   64|    312|    }
_ZN3pgp2eg3KeyD2Ev:
   67|    311|    {
   68|    311|        clear_secret();
   69|    311|    }

_Z12secure_clearPvm:
   35|  14.3k|{
   36|  14.3k|    botan_scrub_mem(vp, size);
   37|  14.3k|}

_ZN3pgp3mpi6assignEPKhm:
  107|  2.28k|{
  108|  2.28k|    data_.assign(val, val + size);
  109|  2.28k|}
_ZN3pgp3mpi6forgetEv:
  125|  7.44k|{
  126|  7.44k|    secure_clear(data_.data(), data_.size());
  127|  7.44k|    data_.resize(0);
  128|  7.44k|}

_ZN3rnp3RNGC2ENS0_4TypeE:
   34|  4.17k|{
   35|  4.17k|    if (botan_rng_init(&botan_rng, type == Type::DRBG ? "user" : NULL)) {
  ------------------
  |  Branch (35:9): [True: 0, False: 4.17k]
  |  Branch (35:36): [True: 4.17k, False: 0]
  ------------------
   36|      0|        throw rnp::rnp_exception(RNP_ERROR_RNG);
   37|      0|    }
   38|  4.17k|#if defined(ENABLE_CRYPTO_REFRESH) || defined(ENABLE_PQC)
   39|  4.17k|    if (type == Type::DRBG) {
  ------------------
  |  Branch (39:9): [True: 4.17k, False: 0]
  ------------------
   40|  4.17k|        botan_rng_obj.reset(new Botan::AutoSeeded_RNG);
   41|  4.17k|    } else {
   42|      0|        botan_rng_obj.reset(new Botan::System_RNG);
   43|      0|    }
   44|  4.17k|#endif
   45|  4.17k|}
_ZN3rnp3RNGD2Ev:
   48|  4.17k|{
   49|  4.17k|    (void) botan_rng_destroy(botan_rng);
   50|  4.17k|}

_ZN3pgp3rsa3Key12clear_secretEv:
   61|  1.64k|    {
   62|  1.64k|        d.forget();
   63|  1.64k|        p.forget();
   64|  1.64k|        q.forget();
   65|  1.64k|        u.forget();
   66|  1.64k|    }
_ZN3pgp3rsa3KeyD2Ev:
   69|  1.63k|    {
   70|  1.63k|        clear_secret();
   71|  1.63k|    }

_ZN3pgp11FingerprintC2Ev:
   38|    912|Fingerprint::Fingerprint() : keyid_({})
   39|    912|{
   40|    912|}
_ZNK3pgp11Fingerprint4dataEv:
  127|    152|{
  128|    152|    return fp_.data();
  129|    152|}
_ZNK3pgp11Fingerprint4sizeEv:
  133|    152|{
  134|    152|    return fp_.size();
  135|    152|}

_ZNKSt3__14hashIN3pgp11FingerprintEEclERKS2_:
   88|    152|    {
   89|       |        /* since fingerprint value is hash itself, we may use its low bytes */
   90|    152|        size_t res = 0;
   91|    152|        size_t copy = std::min(sizeof(res), fp.size());
   92|    152|        std::memcpy(&res, fp.data(), copy);
   93|    152|        return res;
   94|    152|    }

_ZN14pgp_validity_t5resetEv:
   59|    304|{
   60|    304|    validated = false;
   61|    304|    valid = false;
   62|    304|    expired = false;
   63|    304|}
_ZN3rnp3KeyC2ERKS0_b:
  445|    152|{
  446|       |    /* Do some checks for g10 keys */
  447|    152|    if (src.format == KeyFormat::G10) {
  ------------------
  |  Branch (447:9): [True: 152, False: 0]
  ------------------
  448|    152|        if (pubonly) {
  ------------------
  |  Branch (448:13): [True: 0, False: 152]
  ------------------
  449|      0|            RNP_LOG("attempt to copy public part from g10 key");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  450|      0|            throw std::invalid_argument("pubonly");
  451|      0|        }
  452|    152|    }
  453|       |
  454|    152|    if (pubonly) {
  ------------------
  |  Branch (454:9): [True: 0, False: 152]
  ------------------
  455|      0|        pkt_ = pgp_key_pkt_t(src.pkt_, true);
  456|      0|        rawpkt_ = RawPacket(pkt_);
  457|    152|    } else {
  458|    152|        pkt_ = src.pkt_;
  459|    152|        rawpkt_ = src.rawpkt_;
  460|    152|    }
  461|       |
  462|    152|    uids_ = src.uids_;
  463|    152|    sigs_ = src.sigs_;
  464|    152|    sigs_map_ = src.sigs_map_;
  465|    152|    keysigs_ = src.keysigs_;
  466|    152|    subkey_fps_ = src.subkey_fps_;
  467|    152|    primary_fp_set_ = src.primary_fp_set_;
  468|    152|    primary_fp_ = src.primary_fp_;
  469|    152|    expiration_ = src.expiration_;
  470|    152|    flags_ = src.flags_;
  471|    152|    fingerprint_ = src.fingerprint_;
  472|    152|    grip_ = src.grip_;
  473|    152|    uid0_ = src.uid0_;
  474|    152|    uid0_set_ = src.uid0_set_;
  475|    152|    revoked_ = src.revoked_;
  476|    152|    revocation_ = src.revocation_;
  477|    152|    revokers_ = src.revokers_;
  478|    152|    format = src.format;
  479|    152|    validity_ = src.validity_;
  480|    152|    valid_till_ = src.valid_till_;
  481|    152|}
_ZN3rnp3Key7set_pktERK13pgp_key_pkt_t:
  839|    152|{
  840|    152|    pkt_ = pkt;
  841|    152|}
_ZNK3rnp3Key10is_primaryEv:
 1032|    152|{
 1033|    152|    return is_primary_key_pkt(pkt_.tag);
 1034|    152|}
_ZNK3rnp3Key9is_subkeyEv:
 1038|    760|{
 1039|    760|    return is_subkey_pkt(pkt_.tag);
 1040|    760|}
_ZNK3rnp3Key9validatedEv:
 1070|    152|{
 1071|    152|    return validity_.validated;
 1072|    152|}
_ZNK3rnp3Key2fpEv:
 1122|    304|{
 1123|    304|    return fingerprint_;
 1124|    304|}
_ZNK3rnp3Key12subkey_countEv:
 1175|    152|{
 1176|    152|    return subkey_fps_.size();
 1177|    152|}
_ZN3rnp3Key10set_rawpktERKNS_9RawPacketE:
 1223|    152|{
 1224|    152|    rawpkt_ = src;
 1225|    152|}
_ZN3rnp3Key14latest_selfsigEjb:
 1463|    456|{
 1464|    456|    uint32_t   latest = 0;
 1465|    456|    Signature *res = nullptr;
 1466|       |
 1467|    456|    for (auto &sigid : sigs_) {
  ------------------
  |  Branch (1467:22): [True: 0, False: 456]
  ------------------
 1468|      0|        auto &sig = get_sig(sigid);
 1469|      0|        if (validated && !sig.validity.valid()) {
  ------------------
  |  Branch (1469:13): [True: 0, False: 0]
  |  Branch (1469:26): [True: 0, False: 0]
  ------------------
 1470|      0|            continue;
 1471|      0|        }
 1472|      0|        bool skip = false;
 1473|      0|        switch (uid) {
 1474|      0|        case UserID::None:
  ------------------
  |  Branch (1474:9): [True: 0, False: 0]
  ------------------
 1475|      0|            skip = (sig.uid != UserID::None) || !is_direct_self(sig);
  ------------------
  |  Branch (1475:20): [True: 0, False: 0]
  |  Branch (1475:49): [True: 0, False: 0]
  ------------------
 1476|      0|            break;
 1477|      0|        case UserID::Primary: {
  ------------------
  |  Branch (1477:9): [True: 0, False: 0]
  ------------------
 1478|      0|            skip = !is_self_cert(sig) ||
  ------------------
  |  Branch (1478:20): [True: 0, False: 0]
  ------------------
 1479|      0|                   !sig.sig.get_subpkt(pgp::pkt::sigsub::Type::PrimaryUserID) ||
  ------------------
  |  Branch (1479:20): [True: 0, False: 0]
  ------------------
 1480|      0|                   !sig.sig.primary_uid() || (sig.uid == UserID::None);
  ------------------
  |  Branch (1480:20): [True: 0, False: 0]
  |  Branch (1480:46): [True: 0, False: 0]
  ------------------
 1481|      0|            break;
 1482|      0|        }
 1483|      0|        case UserID::Any:
  ------------------
  |  Branch (1483:9): [True: 0, False: 0]
  ------------------
 1484|      0|            skip = !is_self_cert(sig) || (sig.uid == UserID::None);
  ------------------
  |  Branch (1484:20): [True: 0, False: 0]
  |  Branch (1484:42): [True: 0, False: 0]
  ------------------
 1485|      0|            break;
 1486|      0|        default:
  ------------------
  |  Branch (1486:9): [True: 0, False: 0]
  ------------------
 1487|      0|            skip = (sig.uid != uid) || !is_self_cert(sig);
  ------------------
  |  Branch (1487:20): [True: 0, False: 0]
  |  Branch (1487:40): [True: 0, False: 0]
  ------------------
 1488|      0|            break;
 1489|      0|        }
 1490|      0|        if (skip) {
  ------------------
  |  Branch (1490:13): [True: 0, False: 0]
  ------------------
 1491|      0|            continue;
 1492|      0|        }
 1493|       |
 1494|      0|        uint32_t creation = sig.sig.creation();
 1495|      0|        if (creation >= latest) {
  ------------------
  |  Branch (1495:13): [True: 0, False: 0]
  ------------------
 1496|      0|            latest = creation;
 1497|      0|            res = &sig;
 1498|      0|        }
 1499|      0|    }
 1500|       |
 1501|       |    /* if there is later self-sig for the same uid without primary flag, then drop res */
 1502|    456|    if ((uid == UserID::Primary) && res) {
  ------------------
  |  Branch (1502:9): [True: 152, False: 304]
  |  Branch (1502:37): [True: 0, False: 152]
  ------------------
 1503|      0|        auto overres = latest_selfsig(res->uid, validated);
 1504|      0|        if (overres && (overres->sig.creation() > res->sig.creation())) {
  ------------------
  |  Branch (1504:13): [True: 0, False: 0]
  |  Branch (1504:24): [True: 0, False: 0]
  ------------------
 1505|      0|            res = nullptr;
 1506|      0|        }
 1507|      0|    }
 1508|    456|    return res;
 1509|    456|}
_ZN3rnp3Key24validate_self_signaturesERKNS_15SecurityContextE:
 1857|    152|{
 1858|    152|    for (auto &sigid : sigs_) {
  ------------------
  |  Branch (1858:22): [True: 0, False: 152]
  ------------------
 1859|      0|        auto &sig = get_sig(sigid);
 1860|      0|        if (sig.validity.validated()) {
  ------------------
  |  Branch (1860:13): [True: 0, False: 0]
  ------------------
 1861|      0|            continue;
 1862|      0|        }
 1863|      0|        if (!is_signer(sig)) {
  ------------------
  |  Branch (1863:13): [True: 0, False: 0]
  ------------------
 1864|      0|            continue;
 1865|      0|        }
 1866|       |
 1867|      0|        if (is_direct_self(sig) || is_self_cert(sig) || is_uid_revocation(sig) ||
  ------------------
  |  Branch (1867:13): [True: 0, False: 0]
  |  Branch (1867:36): [True: 0, False: 0]
  |  Branch (1867:57): [True: 0, False: 0]
  ------------------
 1868|      0|            is_revocation(sig)) {
  ------------------
  |  Branch (1868:13): [True: 0, False: 0]
  ------------------
 1869|      0|            validate_sig(*this, sig, ctx);
 1870|      0|        }
 1871|      0|    }
 1872|    152|}
_ZN3rnp3Key22validate_desig_revokesERNS_8KeyStoreE:
 1891|    152|{
 1892|    152|    if (revokers_.empty()) {
  ------------------
  |  Branch (1892:9): [True: 152, False: 0]
  ------------------
 1893|    152|        return false;
 1894|    152|    }
 1895|      0|    bool refresh = false;
 1896|      0|    for (auto &sigid : sigs_) {
  ------------------
  |  Branch (1896:22): [True: 0, False: 0]
  ------------------
 1897|      0|        auto &sig = get_sig(sigid);
 1898|      0|        if (!is_revocation(sig) || is_signer(sig)) {
  ------------------
  |  Branch (1898:13): [True: 0, False: 0]
  |  Branch (1898:36): [True: 0, False: 0]
  ------------------
 1899|      0|            continue;
 1900|      0|        }
 1901|       |        /* Don't think we should deal with sigs without issuer's fingerprint */
 1902|      0|        if (!sig.sig.has_keyfp() || !has_revoker(sig.sig.keyfp())) {
  ------------------
  |  Branch (1902:13): [True: 0, False: 0]
  |  Branch (1902:13): [True: 0, False: 0]
  |  Branch (1902:37): [True: 0, False: 0]
  ------------------
 1903|      0|            continue;
 1904|      0|        }
 1905|       |        /* If signature was validated and valid, do not re-validate it */
 1906|      0|        if (sig.validity.valid()) {
  ------------------
  |  Branch (1906:13): [True: 0, False: 0]
  ------------------
 1907|      0|            continue;
 1908|      0|        }
 1909|       |
 1910|      0|        auto revoker = keyring.get_signer(sig.sig);
 1911|      0|        if (!revoker) {
  ------------------
  |  Branch (1911:13): [True: 0, False: 0]
  ------------------
 1912|      0|            continue;
 1913|      0|        }
 1914|       |
 1915|      0|        revoker->validate_sig(*this, sig, keyring.secctx);
 1916|      0|        if (sig.validity.valid()) {
  ------------------
  |  Branch (1916:13): [True: 0, False: 0]
  ------------------
 1917|       |            /* return true only if new valid revocation was added */
 1918|      0|            refresh = true;
 1919|      0|        }
 1920|      0|    }
 1921|       |
 1922|      0|    return refresh;
 1923|    152|}
_ZN3rnp3Key16validate_primaryERNS_8KeyStoreE:
 1927|    152|{
 1928|       |    /* validate signatures if needed */
 1929|    152|    validate_self_signatures(keyring.secctx);
 1930|       |
 1931|       |    /* consider public key as valid on this level if it is not expired and has at least one
 1932|       |     * valid self-signature, and is not revoked */
 1933|    152|    validity_.reset();
 1934|    152|    validity_.validated = true;
 1935|    152|    bool has_cert = false;
 1936|    152|    bool has_expired = false;
 1937|       |    /* check whether key is revoked */
 1938|    152|    for (auto &sigid : sigs_) {
  ------------------
  |  Branch (1938:22): [True: 0, False: 152]
  ------------------
 1939|      0|        auto &sig = get_sig(sigid);
 1940|      0|        if (!sig.validity.valid()) {
  ------------------
  |  Branch (1940:13): [True: 0, False: 0]
  ------------------
 1941|      0|            continue;
 1942|      0|        }
 1943|      0|        if (is_revocation(sig)) {
  ------------------
  |  Branch (1943:13): [True: 0, False: 0]
  ------------------
 1944|      0|            return;
 1945|      0|        }
 1946|      0|    }
 1947|       |    /* if we have direct-key signature, then it has higher priority for expiration check */
 1948|    152|    uint64_t now = keyring.secctx.time();
 1949|    152|    auto     dirsig = latest_selfsig(UserID::None);
 1950|    152|    if (dirsig) {
  ------------------
  |  Branch (1950:9): [True: 0, False: 152]
  ------------------
 1951|      0|        has_expired = expired_with(*dirsig, now);
 1952|      0|        has_cert = !has_expired;
 1953|      0|    }
 1954|       |    /* if we have primary uid and it is more restrictive, then use it as well */
 1955|    152|    Signature *prisig = nullptr;
 1956|    152|    if (!has_expired && (prisig = latest_selfsig(UserID::Primary))) {
  ------------------
  |  Branch (1956:9): [True: 152, False: 0]
  |  Branch (1956:25): [True: 0, False: 152]
  ------------------
 1957|      0|        has_expired = expired_with(*prisig, now);
 1958|      0|        has_cert = !has_expired;
 1959|      0|    }
 1960|       |    /* if we don't have direct-key sig and primary uid, use the latest self-cert */
 1961|    152|    Signature *latest = nullptr;
 1962|    152|    if (!dirsig && !prisig && (latest = latest_selfsig(UserID::Any))) {
  ------------------
  |  Branch (1962:9): [True: 152, False: 0]
  |  Branch (1962:20): [True: 152, False: 0]
  |  Branch (1962:31): [True: 0, False: 152]
  ------------------
 1963|      0|        has_expired = expired_with(*latest, now);
 1964|      0|        has_cert = !has_expired;
 1965|      0|    }
 1966|       |
 1967|       |    /* we have at least one non-expiring key self-signature */
 1968|    152|    if (has_cert) {
  ------------------
  |  Branch (1968:9): [True: 0, False: 152]
  ------------------
 1969|      0|        validity_.valid = true;
 1970|      0|        return;
 1971|      0|    }
 1972|       |    /* we have valid self-signature which expires key */
 1973|    152|    if (has_expired) {
  ------------------
  |  Branch (1973:9): [True: 0, False: 152]
  ------------------
 1974|      0|        validity_.expired = true;
 1975|      0|        return;
 1976|      0|    }
 1977|       |
 1978|       |    /* let's check whether key has at least one valid subkey binding */
 1979|    152|    for (size_t i = 0; i < subkey_count(); i++) {
  ------------------
  |  Branch (1979:24): [True: 0, False: 152]
  ------------------
 1980|      0|        Key *sub = keyring.get_subkey(*this, i);
 1981|      0|        if (!sub) {
  ------------------
  |  Branch (1981:13): [True: 0, False: 0]
  ------------------
 1982|      0|            continue;
 1983|      0|        }
 1984|      0|        sub->validate_self_signatures(*this, keyring.secctx);
 1985|      0|        auto sig = sub->latest_binding();
 1986|      0|        if (!sig) {
  ------------------
  |  Branch (1986:13): [True: 0, False: 0]
  ------------------
 1987|      0|            continue;
 1988|      0|        }
 1989|       |        /* check whether subkey is expired - then do not mark key as valid */
 1990|      0|        if (sub->expired_with(*sig, now)) {
  ------------------
  |  Branch (1990:13): [True: 0, False: 0]
  ------------------
 1991|      0|            continue;
 1992|      0|        }
 1993|      0|        validity_.valid = true;
 1994|      0|        return;
 1995|      0|    }
 1996|    152|}
_ZN3rnp3Key8validateERNS_8KeyStoreE:
 2038|    152|{
 2039|    152|    validity_.reset();
 2040|    152|    if (!is_subkey()) {
  ------------------
  |  Branch (2040:9): [True: 152, False: 0]
  ------------------
 2041|    152|        validate_primary(keyring);
 2042|    152|        return;
 2043|    152|    }
 2044|      0|    Key *primary = nullptr;
 2045|      0|    if (has_primary_fp()) {
  ------------------
  |  Branch (2045:9): [True: 0, False: 0]
  ------------------
 2046|      0|        primary = keyring.get_key(primary_fp());
 2047|      0|    }
 2048|      0|    validate_subkey(primary, keyring.secctx);
 2049|      0|}
_ZN3rnp3Key10revalidateERNS_8KeyStoreE:
 2053|    152|{
 2054|    152|    if (is_subkey()) {
  ------------------
  |  Branch (2054:9): [True: 0, False: 152]
  ------------------
 2055|      0|        Key *primary = keyring.primary_key(*this);
 2056|      0|        if (primary) {
  ------------------
  |  Branch (2056:13): [True: 0, False: 0]
  ------------------
 2057|      0|            primary->revalidate(keyring);
 2058|      0|        } else {
 2059|      0|            validate_subkey(NULL, keyring.secctx);
 2060|      0|        }
 2061|      0|        return;
 2062|      0|    }
 2063|       |
 2064|    152|    validate_desig_revokes(keyring);
 2065|    152|    validate(keyring);
 2066|    152|    if (!refresh_data(keyring.secctx)) {
  ------------------
  |  Branch (2066:9): [True: 152, False: 0]
  ------------------
 2067|    152|        RNP_LOG("Failed to refresh key data");
  ------------------
  |  |   76|    152|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|    152|    do {                                                                                 \
  |  |  |  |   69|    152|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 152, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|    152|            break;                                                                       \
  |  |  |  |   71|    152|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2068|    152|    }
 2069|       |    /* validate/re-validate all subkeys as well */
 2070|    152|    for (auto &fp : subkey_fps_) {
  ------------------
  |  Branch (2070:19): [True: 0, False: 152]
  ------------------
 2071|      0|        Key *subkey = keyring.get_key(fp);
 2072|      0|        if (subkey) {
  ------------------
  |  Branch (2072:13): [True: 0, False: 0]
  ------------------
 2073|      0|            subkey->validate_subkey(this, keyring.secctx);
 2074|      0|            if (!subkey->refresh_data(this, keyring.secctx)) {
  ------------------
  |  Branch (2074:17): [True: 0, False: 0]
  ------------------
 2075|      0|                RNP_LOG("Failed to refresh subkey data");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2076|      0|            }
 2077|      0|        }
 2078|      0|    }
 2079|    152|}
_ZN3rnp3Key12refresh_dataERKNS_15SecurityContextE:
 2330|    152|{
 2331|    152|    if (!is_primary()) {
  ------------------
  |  Branch (2331:9): [True: 152, False: 0]
  ------------------
 2332|    152|        RNP_LOG("key must be primary");
  ------------------
  |  |   76|    152|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|    152|    do {                                                                                 \
  |  |  |  |   69|    152|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 152, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|    152|            break;                                                                       \
  |  |  |  |   71|    152|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2333|    152|        return false;
 2334|    152|    }
 2335|       |    /* validate self-signatures if not done yet */
 2336|      0|    validate_self_signatures(ctx);
 2337|       |    /* key expiration */
 2338|      0|    expiration_ = 0;
 2339|       |    /* if we have direct-key signature, then it has higher priority */
 2340|      0|    auto dirsig = latest_selfsig(UserID::None);
 2341|      0|    if (dirsig) {
  ------------------
  |  Branch (2341:9): [True: 0, False: 0]
  ------------------
 2342|      0|        expiration_ = dirsig->sig.key_expiration();
 2343|      0|    }
 2344|       |    /* if we have primary uid and it is more restrictive, then use it as well */
 2345|      0|    auto prisig = latest_selfsig(UserID::Primary);
 2346|      0|    if (prisig && prisig->sig.key_expiration() &&
  ------------------
  |  Branch (2346:9): [True: 0, False: 0]
  |  Branch (2346:19): [True: 0, False: 0]
  ------------------
 2347|      0|        (!expiration_ || (prisig->sig.key_expiration() < expiration_))) {
  ------------------
  |  Branch (2347:10): [True: 0, False: 0]
  |  Branch (2347:26): [True: 0, False: 0]
  ------------------
 2348|      0|        expiration_ = prisig->sig.key_expiration();
 2349|      0|    }
 2350|       |    /* if we don't have direct-key sig and primary uid, use the latest self-cert */
 2351|      0|    auto latest = latest_selfsig(UserID::Any);
 2352|      0|    if (!dirsig && !prisig && latest) {
  ------------------
  |  Branch (2352:9): [True: 0, False: 0]
  |  Branch (2352:20): [True: 0, False: 0]
  |  Branch (2352:31): [True: 0, False: 0]
  ------------------
 2353|      0|        expiration_ = latest->sig.key_expiration();
 2354|      0|    }
 2355|       |    /* key flags: check in direct-key sig first, then primary uid, and then latest */
 2356|      0|    if (dirsig && dirsig->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
  ------------------
  |  Branch (2356:9): [True: 0, False: 0]
  |  Branch (2356:19): [True: 0, False: 0]
  ------------------
 2357|      0|        flags_ = dirsig->sig.key_flags();
 2358|      0|    } else if (prisig && prisig->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
  ------------------
  |  Branch (2358:16): [True: 0, False: 0]
  |  Branch (2358:26): [True: 0, False: 0]
  ------------------
 2359|      0|        flags_ = prisig->sig.key_flags();
 2360|      0|    } else if (latest && latest->sig.has_subpkt(PGP_SIG_SUBPKT_KEY_FLAGS)) {
  ------------------
  |  Branch (2360:16): [True: 0, False: 0]
  |  Branch (2360:26): [True: 0, False: 0]
  ------------------
 2361|      0|        flags_ = latest->sig.key_flags();
 2362|      0|    } else {
 2363|      0|        flags_ = pgp_pk_alg_capabilities(alg());
 2364|      0|    }
 2365|       |    /* designated revokers */
 2366|      0|    revokers_.clear();
 2367|      0|    for (auto &sigid : sigs_) {
  ------------------
  |  Branch (2367:22): [True: 0, False: 0]
  ------------------
 2368|      0|        auto &sig = get_sig(sigid);
 2369|       |        /* pick designated revokers only from direct-key signatures */
 2370|      0|        if (!sig.validity.valid() || !is_direct_self(sig)) {
  ------------------
  |  Branch (2370:13): [True: 0, False: 0]
  |  Branch (2370:38): [True: 0, False: 0]
  ------------------
 2371|      0|            continue;
 2372|      0|        }
 2373|      0|        if (!sig.sig.has_revoker()) {
  ------------------
  |  Branch (2373:13): [True: 0, False: 0]
  ------------------
 2374|      0|            continue;
 2375|      0|        }
 2376|      0|        add_revoker(sig.sig.revoker());
 2377|      0|    }
 2378|       |    /* revocation(s) */
 2379|      0|    refresh_revocations();
 2380|       |    /* valid till */
 2381|      0|    valid_till_ = valid_till_common(expired());
 2382|       |    /* userid validities */
 2383|      0|    for (auto &uid : uids_) {
  ------------------
  |  Branch (2383:20): [True: 0, False: 0]
  ------------------
 2384|      0|        uid.valid = false;
 2385|      0|    }
 2386|      0|    for (auto &sigid : sigs_) {
  ------------------
  |  Branch (2386:22): [True: 0, False: 0]
  ------------------
 2387|      0|        auto &sig = get_sig(sigid);
 2388|       |        /* consider userid as valid if it has at least one non-expired self-sig */
 2389|      0|        if (!sig.validity.valid() || !sig.is_cert() || !is_signer(sig) ||
  ------------------
  |  Branch (2389:13): [True: 0, False: 0]
  |  Branch (2389:38): [True: 0, False: 0]
  |  Branch (2389:56): [True: 0, False: 0]
  ------------------
 2390|      0|            sig.expired(ctx.time())) {
  ------------------
  |  Branch (2390:13): [True: 0, False: 0]
  ------------------
 2391|      0|            continue;
 2392|      0|        }
 2393|      0|        if (sig.uid >= uid_count()) {
  ------------------
  |  Branch (2393:13): [True: 0, False: 0]
  ------------------
 2394|      0|            continue;
 2395|      0|        }
 2396|      0|        get_uid(sig.uid).valid = true;
 2397|      0|    }
 2398|       |    /* check whether uid is revoked */
 2399|      0|    for (auto &uid : uids_) {
  ------------------
  |  Branch (2399:20): [True: 0, False: 0]
  ------------------
 2400|      0|        if (uid.revoked) {
  ------------------
  |  Branch (2400:13): [True: 0, False: 0]
  ------------------
 2401|      0|            uid.valid = false;
 2402|      0|        }
 2403|      0|    }
 2404|       |    /* primary userid: use latest one which is not overridden by later non-primary selfsig */
 2405|      0|    uid0_set_ = false;
 2406|      0|    if (prisig && get_uid(prisig->uid).valid) {
  ------------------
  |  Branch (2406:9): [True: 0, False: 0]
  |  Branch (2406:19): [True: 0, False: 0]
  ------------------
 2407|      0|        uid0_ = prisig->uid;
 2408|      0|        uid0_set_ = true;
 2409|      0|    }
 2410|      0|    return true;
 2411|    152|}

_ZN3rnp3KeyC2Ev:
   88|    304|    Key() = default;
_ZN3rnp3KeyaSEOS0_:
   95|    152|    Key &operator=(Key &&) = default;

_ZN3pgp11KeyMaterialD2Ev:
  238|  1.17k|{
  239|  1.17k|}
_ZN3pgp11KeyMaterial12clear_secretEv:
  295|     15|{
  296|     15|    secret_ = false;
  297|     15|}
_ZN3pgp11KeyMaterial6createE16pgp_pubkey_alg_tRKNS_3rsa3KeyE:
  436|    739|{
  437|    739|    return std::unique_ptr<KeyMaterial>(new RSAKeyMaterial(alg, key));
  438|    739|}
_ZN3pgp11KeyMaterial6createERKNS_3dsa3KeyE:
  442|     29|{
  443|     29|    return std::unique_ptr<KeyMaterial>(new DSAKeyMaterial(key));
  444|     29|}
_ZN3pgp11KeyMaterial6createE16pgp_pubkey_alg_tRKNS_2eg3KeyE:
  448|     70|{
  449|     70|    return std::unique_ptr<KeyMaterial>(new EGKeyMaterial(alg, key));
  450|     70|}
_ZN3pgp11KeyMaterial6createE16pgp_pubkey_alg_tRKNS_2ec3KeyE:
  454|     36|{
  455|     36|    switch (alg) {
  456|      5|    case PGP_PKA_ECDSA:
  ------------------
  |  Branch (456:5): [True: 5, False: 31]
  ------------------
  457|      5|        return std::unique_ptr<KeyMaterial>(new ECDSAKeyMaterial(key));
  458|     24|    case PGP_PKA_ECDH:
  ------------------
  |  Branch (458:5): [True: 24, False: 12]
  ------------------
  459|     24|        return std::unique_ptr<KeyMaterial>(new ECDHKeyMaterial(key));
  460|      7|    case PGP_PKA_EDDSA:
  ------------------
  |  Branch (460:5): [True: 7, False: 29]
  ------------------
  461|      7|        return std::unique_ptr<KeyMaterial>(new EDDSAKeyMaterial(key));
  462|      0|    case PGP_PKA_SM2:
  ------------------
  |  Branch (462:5): [True: 0, False: 36]
  ------------------
  463|      0|        return std::unique_ptr<KeyMaterial>(new SM2KeyMaterial(key));
  464|      0|    default:
  ------------------
  |  Branch (464:5): [True: 0, False: 36]
  ------------------
  465|      0|        throw std::invalid_argument("Invalid EC algorithm.");
  466|     36|    }
  467|     36|}
_ZN3pgp14RSAKeyMaterial5cloneEv:
  471|     88|{
  472|     88|    return std::unique_ptr<KeyMaterial>(new RSAKeyMaterial(*this));
  473|     88|}
_ZN3pgp14RSAKeyMaterial12clear_secretEv:
  490|      7|{
  491|      7|    key_.clear_secret();
  492|      7|    KeyMaterial::clear_secret();
  493|      7|}
_ZN3pgp14RSAKeyMaterial10set_secretERKNS_3mpiES3_S3_S3_:
  598|     37|{
  599|     37|    key_.d = d;
  600|     37|    key_.p = p;
  601|     37|    key_.q = q;
  602|     37|    key_.u = u;
  603|     37|    secret_ = true;
  604|     37|}
_ZN3pgp14DSAKeyMaterial5cloneEv:
  650|     50|{
  651|     50|    return std::unique_ptr<KeyMaterial>(new DSAKeyMaterial(*this));
  652|     50|}
_ZN3pgp14DSAKeyMaterial12clear_secretEv:
  671|      4|{
  672|      4|    key_.clear_secret();
  673|      4|    KeyMaterial::clear_secret();
  674|      4|}
_ZN3pgp14DSAKeyMaterial10set_secretERKNS_3mpiE:
  756|     21|{
  757|     21|    key_.x = x;
  758|     21|    secret_ = true;
  759|     21|}
_ZN3pgp13EGKeyMaterial5cloneEv:
  805|    110|{
  806|    110|    return std::unique_ptr<KeyMaterial>(new EGKeyMaterial(*this));
  807|    110|}
_ZN3pgp13EGKeyMaterial12clear_secretEv:
  825|      1|{
  826|      1|    key_.clear_secret();
  827|      1|    KeyMaterial::clear_secret();
  828|      1|}
_ZN3pgp13EGKeyMaterial10set_secretERKNS_3mpiE:
  912|     54|{
  913|     54|    key_.x = x;
  914|     54|    secret_ = true;
  915|     54|}
_ZN3pgp13ECKeyMaterial12clear_secretEv:
  955|      3|{
  956|      3|    key_.clear_secret();
  957|      3|    KeyMaterial::clear_secret();
  958|      3|}
_ZN3pgp13ECKeyMaterial10set_secretERKNS_3mpiE:
 1032|     25|{
 1033|     25|    key_.x = x;
 1034|     25|    secret_ = true;
 1035|     25|}
_ZN3pgp16ECDSAKeyMaterial5cloneEv:
 1075|      6|{
 1076|      6|    return std::unique_ptr<KeyMaterial>(new ECDSAKeyMaterial(*this));
 1077|      6|}
_ZN3pgp15ECDHKeyMaterial5cloneEv:
 1134|     44|{
 1135|     44|    return std::unique_ptr<KeyMaterial>(new ECDHKeyMaterial(*this));
 1136|     44|}
_ZN3pgp16EDDSAKeyMaterial5cloneEv:
 1259|      6|{
 1260|      6|    return std::unique_ptr<KeyMaterial>(new EDDSAKeyMaterial(*this));
 1261|      6|}

_ZN3pgp11KeyMaterialC2E16pgp_pubkey_alg_tb:
  193|    874|        : validity_({}), alg_(kalg), secret_(secret){};
_ZN3pgp14RSAKeyMaterialC2E16pgp_pubkey_alg_tRKNS_3rsa3KeyEb:
  247|    739|        : KeyMaterial(kalg, secret), key_(key){};
_ZN3pgp14DSAKeyMaterialC2ERKNS_3dsa3KeyEb:
  290|     29|        : KeyMaterial(PGP_PKA_DSA, secret), key_(key){};
_ZN3pgp13EGKeyMaterialC2E16pgp_pubkey_alg_tRKNS_2eg3KeyEb:
  327|     70|        : KeyMaterial(kalg, secret), key_(key){};
_ZN3pgp13ECKeyMaterialC2E16pgp_pubkey_alg_tRKNS_2ec3KeyEb:
  365|     36|        : KeyMaterial(kalg, secret), key_(key){};
_ZN3pgp16ECDSAKeyMaterialC2ERKNS_2ec3KeyEb:
  388|      5|        : ECKeyMaterial(PGP_PKA_ECDSA, key, secret){};
_ZN3pgp15ECDHKeyMaterialC2ERKNS_2ec3KeyEb:
  407|     24|        : ECKeyMaterial(PGP_PKA_ECDH, key, secret){};
_ZN3pgp16EDDSAKeyMaterialC2ERKNS_2ec3KeyEb:
  433|      7|        : ECKeyMaterial(PGP_PKA_EDDSA, key, secret){};

_Z14rnp_log_switchv:
   53|  7.45k|{
   54|  7.45k|    if (_rnp_log_switch < 0) {
  ------------------
  |  Branch (54:9): [True: 1, False: 7.45k]
  ------------------
   55|      1|        const char *var = getenv(RNP_LOG_CONSOLE);
   56|      1|        _rnp_log_switch = (var && strcmp(var, "0")) ? 1 : 0;
  ------------------
  |  Branch (56:28): [True: 0, False: 1]
  |  Branch (56:35): [True: 0, False: 0]
  ------------------
   57|      1|    }
   58|  7.45k|    return !_rnp_log_disable && !!_rnp_log_switch;
  ------------------
  |  Branch (58:12): [True: 7.45k, False: 0]
  |  Branch (58:33): [True: 0, False: 7.45k]
  ------------------
   59|  7.45k|}

_ZN3rnp9RawPacketC2EPKhm14pgp_pkt_type_t:
   33|    152|RawPacket::RawPacket(const uint8_t *data, size_t len, pgp_pkt_type_t atag) : tag_(atag)
   34|    152|{
   35|    152|    if (data && len) {
  ------------------
  |  Branch (35:9): [True: 152, False: 0]
  |  Branch (35:17): [True: 152, False: 0]
  ------------------
   36|    152|        data_.assign(data, data + len);
   37|    152|    }
   38|    152|}

_ZN3rnp9RawPacketC2Ev:
   42|    456|    RawPacket() : tag_(PGP_PKT_RESERVED){};

_ZN3rnp15SecurityProfile8add_ruleEONS_12SecurityRuleE:
   75|  29.2k|{
   76|  29.2k|    rules_.emplace_back(rule);
   77|  29.2k|    return rules_.back();
   78|  29.2k|}
_ZN3rnp15SecurityContextC2Ev:
  179|  4.17k|SecurityContext::SecurityContext() : time_(0), prov_state_(NULL), rng(RNG::Type::DRBG)
  180|  4.17k|{
  181|       |    /* Initialize crypto provider if needed (currently only for OpenSSL 3.0) */
  182|  4.17k|    if (!rnp::backend_init(&prov_state_)) {
  ------------------
  |  Branch (182:9): [True: 0, False: 4.17k]
  ------------------
  183|      0|        throw rnp::rnp_exception(RNP_ERROR_BAD_STATE);
  184|      0|    }
  185|       |    /* Mark SHA-1 data signature insecure since 2019-01-19, as GnuPG does */
  186|  4.17k|    profile.add_rule({FeatureType::Hash,
  187|  4.17k|                      PGP_HASH_SHA1,
  188|  4.17k|                      SecurityLevel::Insecure,
  189|  4.17k|                      1547856000,
  190|  4.17k|                      SecurityAction::VerifyData});
  191|       |    /* Mark SHA-1 key signature insecure since 2024-01-19 by default */
  192|  4.17k|    profile.add_rule({FeatureType::Hash,
  193|  4.17k|                      PGP_HASH_SHA1,
  194|  4.17k|                      SecurityLevel::Insecure,
  195|  4.17k|                      1705629600,
  196|  4.17k|                      SecurityAction::VerifyKey});
  197|       |    /* Mark MD5 insecure since 2012-01-01 */
  198|  4.17k|    profile.add_rule({FeatureType::Hash, PGP_HASH_MD5, SecurityLevel::Insecure, 1325376000});
  199|       |    /* Mark CAST5, 3DES, IDEA, BLOWFISH insecure since 2024-10-01*/
  200|  4.17k|    profile.add_rule({FeatureType::Cipher, PGP_SA_CAST5, SecurityLevel::Insecure, 1727730000});
  201|  4.17k|    profile.add_rule(
  202|  4.17k|      {FeatureType::Cipher, PGP_SA_TRIPLEDES, SecurityLevel::Insecure, 1727730000});
  203|  4.17k|    profile.add_rule({FeatureType::Cipher, PGP_SA_IDEA, SecurityLevel::Insecure, 1727730000});
  204|  4.17k|    profile.add_rule(
  205|  4.17k|      {FeatureType::Cipher, PGP_SA_BLOWFISH, SecurityLevel::Insecure, 1727730000});
  206|  4.17k|}
_ZN3rnp15SecurityContextD2Ev:
  209|  4.17k|{
  210|  4.17k|    rnp::backend_finish(prov_state_);
  211|  4.17k|}
_ZNK3rnp15SecurityContext4timeEv:
  231|    152|{
  232|    152|    return time_ ? time_ : ::time(NULL);
  ------------------
  |  Branch (232:12): [True: 0, False: 152]
  ------------------
  233|    152|}

_ZN3rnp12SecurityRuleC2ENS_11FeatureTypeEiNS_13SecurityLevelEmNS_14SecurityActionE:
   54|  29.2k|        : type(ftype), feature(fval), level(flevel), from(ffrom), override(false),
   55|  29.2k|          action(faction){};

_ZN3rnp10RevocationC2Ev:
  145|    456|    Revocation() : uid(0), code(PGP_REVOCATION_NO_REASON), sigid(){};

_ZN11id_str_pair6lookupEPKS_PKci:
   44|  1.15k|{
   45|  3.90k|    while (pair && pair->str) {
  ------------------
  |  Branch (45:12): [True: 3.90k, False: 0]
  |  Branch (45:20): [True: 3.84k, False: 54]
  ------------------
   46|  3.84k|        if (rnp::str_case_eq(str, pair->str)) {
  ------------------
  |  Branch (46:13): [True: 1.10k, False: 2.74k]
  ------------------
   47|  1.10k|            return pair->id;
   48|  1.10k|        }
   49|  2.74k|        pair++;
   50|  2.74k|    }
   51|     54|    return notfound;
   52|  1.15k|}

_ZN28gnupg_extended_private_key_t5parseEPKcmm:
  232|  4.17k|{
  233|  4.17k|    bool               res = false;
  234|  4.17k|    std::istringstream iss(std::string(r_bytes, r_length));
  235|  4.17k|    try {
  236|  4.17k|        ext_key_input_stream_t g23_is(&iss, depth);
  237|  4.17k|        g23_is.scan(*this);
  238|  4.17k|        res = true;
  239|  4.17k|    } catch (sexp_exception_t &e) {
  240|  2.84k|        RNP_LOG("%s", e.what());
  ------------------
  |  |   76|  2.84k|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|  2.84k|    do {                                                                                 \
  |  |  |  |   69|  2.84k|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 2.84k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|  2.84k|            break;                                                                       \
  |  |  |  |   71|  2.84k|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  241|  2.84k|    }
  242|  4.17k|    return res;
  243|  4.17k|}
_ZN3rnp8KeyStore8load_g10ER12pgp_source_tPKNS_11KeyProviderE:
  935|  4.17k|{
  936|  4.17k|    try {
  937|       |        /* read src to the memory */
  938|  4.17k|        MemorySource memsrc(src);
  939|       |        /* parse secret key: fills material and sec_protection only */
  940|  4.17k|        pgp_key_pkt_t seckey;
  941|  4.17k|        if (!g23_parse_seckey(seckey, (uint8_t *) memsrc.memory(), memsrc.size(), NULL)) {
  ------------------
  |  Branch (941:13): [True: 4.02k, False: 152]
  ------------------
  942|  4.02k|            return false;
  943|  4.02k|        }
  944|       |        /* copy public key fields if any */
  945|    152|        Key key;
  946|    152|        if (key_provider) {
  ------------------
  |  Branch (946:13): [True: 0, False: 152]
  ------------------
  947|      0|            pgp::KeyGrip grip = seckey.material->grip();
  948|      0|            auto         pubkey =
  949|      0|              key_provider->request_key(*KeySearch::create(grip), PGP_OP_MERGE_INFO);
  950|      0|            if (!pubkey) {
  ------------------
  |  Branch (950:17): [True: 0, False: 0]
  ------------------
  951|      0|                return false;
  952|      0|            }
  953|       |
  954|       |            /* public key packet has some more info then the secret part */
  955|      0|            key = Key(*pubkey, true);
  956|      0|            if (!copy_secret_fields(key.pkt(), seckey)) {
  ------------------
  |  Branch (956:17): [True: 0, False: 0]
  ------------------
  957|      0|                return false;
  958|      0|            }
  959|    152|        } else {
  960|    152|            key.set_pkt(std::move(seckey));
  961|    152|        }
  962|       |        /* set rawpkt */
  963|    152|        key.set_rawpkt(
  964|    152|          RawPacket((uint8_t *) memsrc.memory(), memsrc.size(), PGP_PKT_RESERVED));
  965|    152|        key.format = KeyFormat::G10;
  966|    152|        if (!add_key(key)) {
  ------------------
  |  Branch (966:13): [True: 0, False: 152]
  ------------------
  967|      0|            return false;
  968|      0|        }
  969|    152|        return true;
  970|    152|    } catch (const std::exception &e) {
  971|       |        /* LCOV_EXCL_START */
  972|      0|        RNP_LOG("%s", e.what());
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  973|      0|        return false;
  974|       |        /* LCOV_EXCL_END */
  975|      0|    }
  976|  4.17k|}
key_store_g10.cpp:_ZL16g23_parse_seckeyR13pgp_key_pkt_tPKhmPKc16pgp_pubkey_alg_t:
  779|  4.17k|{
  780|  4.17k|    gnupg_extended_private_key_t g23_extended_key;
  781|       |
  782|  4.17k|    if (!g23_extended_key.parse((const char *) data, data_len, SXP_MAX_DEPTH)) {
  ------------------
  |  |   33|  4.17k|#define SXP_MAX_DEPTH 30
  ------------------
  |  Branch (782:9): [True: 2.84k, False: 1.33k]
  ------------------
  783|  2.84k|        RNP_LOG("Failed to parse s-exp.");
  ------------------
  |  |   76|  2.84k|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|  2.84k|    do {                                                                                 \
  |  |  |  |   69|  2.84k|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 2.84k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|  2.84k|            break;                                                                       \
  |  |  |  |   71|  2.84k|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  784|  2.84k|        return false;
  785|  2.84k|    }
  786|       |    // Although the library parses full g23 extended key
  787|       |    // we extract and use g10 part only
  788|  1.33k|    const sexp_list_t &g10_key = g23_extended_key.key;
  789|       |
  790|       |    /* expected format:
  791|       |     *  (<type>
  792|       |     *    (<algo>
  793|       |     *	   (x <mpi>)
  794|       |     *	   (y <mpi>)
  795|       |     *    )
  796|       |     *  )
  797|       |     */
  798|       |
  799|  1.33k|    if (g10_key.size() != 2 || !g10_key.at(0)->is_sexp_string() ||
  ------------------
  |  Branch (799:9): [True: 36, False: 1.30k]
  |  Branch (799:32): [True: 6, False: 1.29k]
  ------------------
  800|  1.29k|        !g10_key.at(1)->is_sexp_list()) {
  ------------------
  |  Branch (800:9): [True: 3, False: 1.29k]
  ------------------
  801|     45|        RNP_LOG("Wrong format, expected: (<type> (...))");
  ------------------
  |  |   76|     45|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     45|    do {                                                                                 \
  |  |  |  |   69|     45|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 45, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     45|            break;                                                                       \
  |  |  |  |   71|     45|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  802|     45|        return false;
  803|     45|    }
  804|       |
  805|  1.29k|    bool is_protected = false;
  806|       |
  807|  1.29k|    auto &name = g10_key.sexp_string_at(0)->get_string();
  808|  1.29k|    if (name == "private-key") {
  ------------------
  |  Branch (808:9): [True: 465, False: 827]
  ------------------
  809|    465|        is_protected = false;
  810|    827|    } else if (name == "protected-private-key") {
  ------------------
  |  Branch (810:16): [True: 651, False: 176]
  ------------------
  811|    651|        is_protected = true;
  812|    651|    } else {
  813|    176|        RNP_LOG("Unsupported top-level block: '%.*s'",
  ------------------
  |  |   76|    176|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|    176|    do {                                                                                 \
  |  |  |  |   69|    176|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 176, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|    176|            break;                                                                       \
  |  |  |  |   71|    176|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  814|    176|                (int) name.size(),
  815|    176|                (const char *) name.data());
  816|    176|        return false;
  817|    176|    }
  818|       |
  819|  1.11k|    auto alg_s_exp = g10_key.sexp_list_at(1);
  820|  1.11k|    if (alg_s_exp->size() < 2) {
  ------------------
  |  Branch (820:9): [True: 3, False: 1.11k]
  ------------------
  821|      3|        RNP_LOG("Wrong count of algorithm-level elements: %zu", alg_s_exp->size());
  ------------------
  |  |   76|      3|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      3|    do {                                                                                 \
  |  |  |  |   69|      3|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 3, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      3|            break;                                                                       \
  |  |  |  |   71|      3|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  822|      3|        return false;
  823|      3|    }
  824|       |
  825|  1.11k|    if (!alg_s_exp->at(0)->is_sexp_string()) {
  ------------------
  |  Branch (825:9): [True: 1, False: 1.11k]
  ------------------
  826|      1|        RNP_LOG("Expected block with algorithm name, but has s-exp");
  ------------------
  |  |   76|      1|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      1|    do {                                                                                 \
  |  |  |  |   69|      1|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 1, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      1|            break;                                                                       \
  |  |  |  |   71|      1|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  827|      1|        return false;
  828|      1|    }
  829|       |
  830|  1.11k|    bool ret = false;
  831|  1.11k|    auto alg = pubalg;
  832|  1.11k|    if (alg == PGP_PKA_NOTHING) {
  ------------------
  |  Branch (832:9): [True: 1.11k, False: 0]
  ------------------
  833|  1.11k|        auto &alg_bt = alg_s_exp->sexp_string_at(0)->get_string();
  834|  1.11k|        auto  alg_st = (const char *) alg_bt.data();
  835|  1.11k|        alg = static_cast<pgp_pubkey_alg_t>(
  836|  1.11k|          id_str_pair::lookup(g10_alg_aliases, alg_st, PGP_PKA_NOTHING));
  837|  1.11k|        if (alg == PGP_PKA_NOTHING) {
  ------------------
  |  Branch (837:13): [True: 48, False: 1.06k]
  ------------------
  838|     48|            RNP_LOG("Unsupported algorithm: '%.*s'", (int) alg_bt.size(), alg_st);
  ------------------
  |  |   76|     48|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     48|    do {                                                                                 \
  |  |  |  |   69|     48|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 48, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     48|            break;                                                                       \
  |  |  |  |   71|     48|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  839|     48|            return false;
  840|     48|        }
  841|       |        /* Parse pubkey only if it was not parsed before */
  842|  1.06k|        if (!parse_pubkey(seckey, alg_s_exp, alg)) {
  ------------------
  |  Branch (842:13): [True: 190, False: 874]
  ------------------
  843|    190|            RNP_LOG("failed to parse pubkey");
  ------------------
  |  |   76|    190|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|    190|    do {                                                                                 \
  |  |  |  |   69|    190|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 190, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|    190|            break;                                                                       \
  |  |  |  |   71|    190|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  844|    190|            goto done;
  845|    190|        }
  846|  1.06k|    }
  847|       |
  848|    874|    if (is_protected) {
  ------------------
  |  Branch (848:9): [True: 646, False: 228]
  ------------------
  849|    646|        if (!parse_protected_seckey(seckey, alg_s_exp, password)) {
  ------------------
  |  Branch (849:13): [True: 631, False: 15]
  ------------------
  850|    631|            goto done;
  851|    631|        }
  852|    646|    } else {
  853|    228|        seckey.sec_protection.s2k.usage = PGP_S2KU_NONE;
  854|    228|        seckey.sec_protection.symm_alg = PGP_SA_PLAINTEXT;
  855|    228|        seckey.sec_protection.s2k.hash_alg = PGP_HASH_UNKNOWN;
  856|    228|        if (!parse_seckey(seckey, alg_s_exp)) {
  ------------------
  |  Branch (856:13): [True: 91, False: 137]
  ------------------
  857|     91|            RNP_LOG("failed to parse seckey");
  ------------------
  |  |   76|     91|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     91|    do {                                                                                 \
  |  |  |  |   69|     91|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 91, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     91|            break;                                                                       \
  |  |  |  |   71|     91|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  858|     91|            goto done;
  859|     91|        }
  860|    228|    }
  861|    152|    ret = true;
  862|  1.06k|done:
  863|  1.06k|    if (!ret) {
  ------------------
  |  Branch (863:9): [True: 912, False: 152]
  ------------------
  864|    912|        seckey = pgp_key_pkt_t();
  865|    912|    }
  866|  1.06k|    return ret;
  867|    152|}
key_store_g10.cpp:_ZL12parse_pubkeyR13pgp_key_pkt_tPKN4sexp11sexp_list_tE16pgp_pubkey_alg_t:
  375|  1.06k|{
  376|  1.06k|    pubkey.version = PGP_V4;
  377|  1.06k|    pubkey.alg = alg;
  378|  1.06k|    switch (alg) {
  379|     65|    case PGP_PKA_DSA: {
  ------------------
  |  Branch (379:5): [True: 65, False: 999]
  ------------------
  380|     65|        pgp::dsa::Key dsa;
  381|     65|        if (!read_mpi(s_exp, "p", dsa.p) || !read_mpi(s_exp, "q", dsa.q) ||
  ------------------
  |  Branch (381:13): [True: 5, False: 60]
  |  Branch (381:13): [True: 36, False: 29]
  |  Branch (381:45): [True: 26, False: 34]
  ------------------
  382|     36|            !read_mpi(s_exp, "g", dsa.g) || !read_mpi(s_exp, "y", dsa.y)) {
  ------------------
  |  Branch (382:13): [True: 4, False: 30]
  |  Branch (382:45): [True: 1, False: 29]
  ------------------
  383|     36|            return false;
  384|     36|        }
  385|     29|        pubkey.material = pgp::KeyMaterial::create(dsa);
  386|     29|        break;
  387|     65|    }
  388|    811|    case PGP_PKA_RSA:
  ------------------
  |  Branch (388:5): [True: 811, False: 253]
  ------------------
  389|    811|    case PGP_PKA_RSA_ENCRYPT_ONLY:
  ------------------
  |  Branch (389:5): [True: 0, False: 1.06k]
  ------------------
  390|    811|    case PGP_PKA_RSA_SIGN_ONLY: {
  ------------------
  |  Branch (390:5): [True: 0, False: 1.06k]
  ------------------
  391|    811|        pgp::rsa::Key rsa;
  392|    811|        if (!read_mpi(s_exp, "n", rsa.n) || !read_mpi(s_exp, "e", rsa.e)) {
  ------------------
  |  Branch (392:13): [True: 34, False: 777]
  |  Branch (392:13): [True: 72, False: 739]
  |  Branch (392:45): [True: 38, False: 739]
  ------------------
  393|     72|            return false;
  394|     72|        }
  395|    739|        pubkey.material = pgp::KeyMaterial::create(alg, rsa);
  396|    739|        break;
  397|    811|    }
  398|    131|    case PGP_PKA_ELGAMAL:
  ------------------
  |  Branch (398:5): [True: 131, False: 933]
  ------------------
  399|    131|    case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: {
  ------------------
  |  Branch (399:5): [True: 0, False: 1.06k]
  ------------------
  400|    131|        pgp::eg::Key eg;
  401|    131|        if (!read_mpi(s_exp, "p", eg.p) || !read_mpi(s_exp, "g", eg.g) ||
  ------------------
  |  Branch (401:13): [True: 23, False: 108]
  |  Branch (401:13): [True: 61, False: 70]
  |  Branch (401:44): [True: 33, False: 75]
  ------------------
  402|     75|            !read_mpi(s_exp, "y", eg.y)) {
  ------------------
  |  Branch (402:13): [True: 5, False: 70]
  ------------------
  403|     61|            return false;
  404|     61|        }
  405|     70|        pubkey.material = pgp::KeyMaterial::create(alg, eg);
  406|     70|        break;
  407|    131|    }
  408|     31|    case PGP_PKA_ECDSA:
  ------------------
  |  Branch (408:5): [True: 31, False: 1.03k]
  ------------------
  409|     56|    case PGP_PKA_ECDH:
  ------------------
  |  Branch (409:5): [True: 25, False: 1.03k]
  ------------------
  410|     57|    case PGP_PKA_EDDSA: {
  ------------------
  |  Branch (410:5): [True: 1, False: 1.06k]
  ------------------
  411|     57|        pgp::ec::Key ec{};
  412|     57|        if (!read_curve(s_exp, "curve", ec) || !read_mpi(s_exp, "q", ec.p)) {
  ------------------
  |  Branch (412:13): [True: 20, False: 37]
  |  Branch (412:13): [True: 21, False: 36]
  |  Branch (412:48): [True: 1, False: 36]
  ------------------
  413|     21|            return false;
  414|     21|        }
  415|     36|        if (ec.curve == PGP_CURVE_ED25519) {
  ------------------
  |  Branch (415:13): [True: 7, False: 29]
  ------------------
  416|       |            /* need to adjust it here since 'ecc' key type defaults to ECDSA */
  417|      7|            pubkey.alg = PGP_PKA_EDDSA;
  418|      7|        }
  419|     36|        pubkey.material = pgp::KeyMaterial::create(pubkey.alg, ec);
  420|     36|        break;
  421|     57|    }
  422|      0|    default:
  ------------------
  |  Branch (422:5): [True: 0, False: 1.06k]
  ------------------
  423|      0|        RNP_LOG("Unsupported public key algorithm: %d", (int) alg);
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  424|      0|        return false;
  425|  1.06k|    }
  426|       |
  427|    874|    return true;
  428|  1.06k|}
key_store_g10.cpp:_ZL8read_mpiPKN4sexp11sexp_list_tERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERN3pgp3mpiE:
  290|  2.54k|{
  291|  2.54k|    const sexp_string_t *data = lookup_var_data(list, name);
  292|  2.54k|    if (!data) {
  ------------------
  |  Branch (292:9): [True: 261, False: 2.28k]
  ------------------
  293|    261|        return false;
  294|    261|    }
  295|       |
  296|       |    /* strip leading zero */
  297|  2.28k|    const auto &bytes = data->get_string();
  298|  2.28k|    if ((bytes.size() > 1) && !bytes[0] && (bytes[1] & 0x80)) {
  ------------------
  |  Branch (298:9): [True: 502, False: 1.78k]
  |  Branch (298:31): [True: 221, False: 281]
  |  Branch (298:44): [True: 139, False: 82]
  ------------------
  299|    139|        val.assign(bytes.data() + 1, bytes.size() - 1);
  300|  2.14k|    } else {
  301|  2.14k|        val.assign(bytes.data(), bytes.size());
  302|  2.14k|    }
  303|  2.28k|    return true;
  304|  2.54k|}
key_store_g10.cpp:_ZL15lookup_var_dataPKN4sexp11sexp_list_tERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  274|  2.60k|{
  275|  2.60k|    const sexp_list_t *var = lookup_var(list, name);
  276|  2.60k|    if (!var) {
  ------------------
  |  Branch (276:9): [True: 273, False: 2.33k]
  ------------------
  277|    273|        return NULL;
  278|    273|    }
  279|       |
  280|  2.33k|    if (!var->at(1)->is_sexp_string()) {
  ------------------
  |  Branch (280:9): [True: 2, False: 2.32k]
  ------------------
  281|      2|        RNP_LOG("Expected block value");
  ------------------
  |  |   76|      2|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      2|    do {                                                                                 \
  |  |  |  |   69|      2|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 2, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      2|            break;                                                                       \
  |  |  |  |   71|      2|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  282|      2|        return NULL;
  283|      2|    }
  284|       |
  285|  2.32k|    return var->sexp_string_at(1);
  286|  2.33k|}
key_store_g10.cpp:_ZL10lookup_varPKN4sexp11sexp_list_tERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  247|  3.25k|{
  248|  3.25k|    const sexp_list_t *res = nullptr;
  249|       |    // We are looking for a list element  (condition 1)
  250|       |    // that:
  251|       |    //  -- has at least two SEXP elements (condition 2)
  252|       |    //  -- has a SEXP string at 0 position (condition 3)
  253|       |    //     matching given name            (condition 4)
  254|  3.25k|    auto match = [name](const std::shared_ptr<sexp_object_t> &ptr) {
  255|  3.25k|        bool r = false;
  256|  3.25k|        auto r1 = ptr->sexp_list_view();
  257|  3.25k|        if (r1 && r1->size() >= 2) { // conditions (1) and (2)
  258|  3.25k|            auto r2 = r1->sexp_string_at(0);
  259|  3.25k|            if (r2 && r2 == name) // conditions (3) and (4)
  260|  3.25k|                r = true;
  261|  3.25k|        }
  262|  3.25k|        return r;
  263|  3.25k|    };
  264|  3.25k|    auto r3 = std::find_if(list->begin(), list->end(), std::move(match));
  265|  3.25k|    if (r3 == list->end())
  ------------------
  |  Branch (265:9): [True: 278, False: 2.97k]
  ------------------
  266|  3.25k|        RNP_LOG("Haven't got variable '%s'", name.c_str());
  ------------------
  |  |   76|    278|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|    278|    do {                                                                                 \
  |  |  |  |   69|    278|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 278, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|    278|            break;                                                                       \
  |  |  |  |   71|    278|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  267|  2.97k|    else
  268|  2.97k|        res = (*r3)->sexp_list_view();
  269|  3.25k|    return res;
  270|  3.25k|}
key_store_g10.cpp:_ZZL10lookup_varPKN4sexp11sexp_list_tERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEENK3$_0clERKNS3_10shared_ptrINS_13sexp_object_tEEE:
  254|  28.5k|    auto match = [name](const std::shared_ptr<sexp_object_t> &ptr) {
  255|  28.5k|        bool r = false;
  256|  28.5k|        auto r1 = ptr->sexp_list_view();
  257|  28.5k|        if (r1 && r1->size() >= 2) { // conditions (1) and (2)
  ------------------
  |  Branch (257:13): [True: 16.9k, False: 11.5k]
  |  Branch (257:19): [True: 8.39k, False: 8.59k]
  ------------------
  258|  8.39k|            auto r2 = r1->sexp_string_at(0);
  259|  8.39k|            if (r2 && r2 == name) // conditions (3) and (4)
  ------------------
  |  Branch (259:17): [True: 8.09k, False: 302]
  |  Branch (259:23): [True: 2.97k, False: 5.12k]
  ------------------
  260|  2.97k|                r = true;
  261|  8.39k|        }
  262|  28.5k|        return r;
  263|  28.5k|    };
key_store_g10.cpp:_ZL10read_curvePKN4sexp11sexp_list_tERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERN3pgp2ec3KeyE:
  308|     57|{
  309|     57|    const sexp_string_t *data = lookup_var_data(list, name);
  310|     57|    if (!data) {
  ------------------
  |  Branch (310:9): [True: 14, False: 43]
  ------------------
  311|     14|        return false;
  312|     14|    }
  313|       |
  314|     43|    const auto &bytes = data->get_string();
  315|     43|    pgp_curve_t curve = static_cast<pgp_curve_t>(
  316|     43|      id_str_pair::lookup(g10_curve_aliases, (const char *) bytes.data(), PGP_CURVE_UNKNOWN));
  317|     43|    if (curve != PGP_CURVE_UNKNOWN) {
  ------------------
  |  Branch (317:9): [True: 37, False: 6]
  ------------------
  318|     37|        key.curve = curve;
  319|     37|        return true;
  320|     37|    }
  321|      6|    RNP_LOG("Unknown curve: %.*s", (int) bytes.size(), (const char *) bytes.data());
  ------------------
  |  |   76|      6|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      6|    do {                                                                                 \
  |  |  |  |   69|      6|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 6, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      6|            break;                                                                       \
  |  |  |  |   71|      6|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  322|      6|    return false;
  323|     43|}
key_store_g10.cpp:_ZL22parse_protected_seckeyR13pgp_key_pkt_tPKN4sexp11sexp_list_tEPKc:
  593|    646|{
  594|       |    // find and validate the protected section
  595|    646|    const sexp_list_t *protected_key = lookup_var(list, "protected");
  596|    646|    if (!protected_key) {
  ------------------
  |  Branch (596:9): [True: 5, False: 641]
  ------------------
  597|      5|        RNP_LOG("missing protected section");
  ------------------
  |  |   76|      5|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      5|    do {                                                                                 \
  |  |  |  |   69|      5|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 5, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      5|            break;                                                                       \
  |  |  |  |   71|      5|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  598|      5|        return false;
  599|      5|    }
  600|    641|    if (protected_key->size() != 4 || !protected_key->at(1)->is_sexp_string() ||
  ------------------
  |  Branch (600:9): [True: 15, False: 626]
  |  Branch (600:39): [True: 1, False: 625]
  ------------------
  601|    625|        protected_key->at(2)->is_sexp_string() || !protected_key->at(3)->is_sexp_string()) {
  ------------------
  |  Branch (601:9): [True: 1, False: 624]
  |  Branch (601:51): [True: 1, False: 623]
  ------------------
  602|     18|        RNP_LOG("Wrong protected format, expected: (protected mode (params) "
  ------------------
  |  |   76|     18|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     18|    do {                                                                                 \
  |  |  |  |   69|     18|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 18, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     18|            break;                                                                       \
  |  |  |  |   71|     18|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  603|     18|                "encrypted_octet_string)\n");
  604|     18|        return false;
  605|     18|    }
  606|       |
  607|       |    // lookup the protection format
  608|    623|    auto &             fmt_bt = protected_key->sexp_string_at(1)->get_string();
  609|    623|    const format_info *format = parse_format((const char *) fmt_bt.data(), fmt_bt.size());
  610|    623|    if (!format) {
  ------------------
  |  Branch (610:9): [True: 452, False: 171]
  ------------------
  611|    452|        RNP_LOG("Unsupported protected mode: '%.*s'\n",
  ------------------
  |  |   76|    452|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|    452|    do {                                                                                 \
  |  |  |  |   69|    452|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 452, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|    452|            break;                                                                       \
  |  |  |  |   71|    452|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  612|    452|                (int) fmt_bt.size(),
  613|    452|                (const char *) fmt_bt.data());
  614|    452|        return false;
  615|    452|    }
  616|       |
  617|       |    // fill in some fields based on the lookup above
  618|    171|    pgp_key_protection_t &prot = seckey.sec_protection;
  619|    171|    prot.symm_alg = format->cipher;
  620|    171|    prot.cipher_mode = format->cipher_mode;
  621|    171|    prot.s2k.hash_alg = format->hash_alg;
  622|       |
  623|       |    // locate and validate the protection parameters
  624|    171|    auto params = protected_key->sexp_list_at(2);
  625|    171|    if (params->size() != 2 || params->at(0)->is_sexp_string() ||
  ------------------
  |  Branch (625:9): [True: 14, False: 157]
  |  Branch (625:32): [True: 1, False: 156]
  ------------------
  626|    156|        !params->at(1)->is_sexp_string()) {
  ------------------
  |  Branch (626:9): [True: 1, False: 155]
  ------------------
  627|     16|        RNP_LOG("Wrong params format, expected: ((hash salt no_of_iterations) iv)\n");
  ------------------
  |  |   76|     16|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     16|    do {                                                                                 \
  |  |  |  |   69|     16|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 16, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     16|            break;                                                                       \
  |  |  |  |   71|     16|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  628|     16|        return false;
  629|     16|    }
  630|       |
  631|       |    // locate and validate the (hash salt no_of_iterations) exp
  632|    155|    auto alg = params->sexp_list_at(0);
  633|    155|    if (alg->size() != 3 || !alg->at(0)->is_sexp_string() || !alg->at(1)->is_sexp_string() ||
  ------------------
  |  Branch (633:9): [True: 2, False: 153]
  |  Branch (633:29): [True: 1, False: 152]
  |  Branch (633:62): [True: 1, False: 151]
  ------------------
  634|    151|        !alg->at(2)->is_sexp_string()) {
  ------------------
  |  Branch (634:9): [True: 1, False: 150]
  ------------------
  635|      5|        RNP_LOG("Wrong params sub-level format, expected: (hash salt no_of_iterations)\n");
  ------------------
  |  |   76|      5|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      5|    do {                                                                                 \
  |  |  |  |   69|      5|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 5, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      5|            break;                                                                       \
  |  |  |  |   71|      5|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  636|      5|        return false;
  637|      5|    }
  638|    150|    auto &hash_bt = alg->sexp_string_at(0)->get_string();
  639|    150|    if (hash_bt != "sha1") {
  ------------------
  |  Branch (639:9): [True: 40, False: 110]
  ------------------
  640|     40|        RNP_LOG("Wrong hashing algorithm, should be sha1 but %.*s\n",
  ------------------
  |  |   76|     40|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     40|    do {                                                                                 \
  |  |  |  |   69|     40|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 40, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     40|            break;                                                                       \
  |  |  |  |   71|     40|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  641|     40|                (int) hash_bt.size(),
  642|     40|                (const char *) hash_bt.data());
  643|     40|        return false;
  644|     40|    }
  645|       |
  646|       |    // fill in some constant values
  647|    110|    prot.s2k.hash_alg = PGP_HASH_SHA1;
  648|    110|    prot.s2k.usage = PGP_S2KU_ENCRYPTED_AND_HASHED;
  649|    110|    prot.s2k.specifier = PGP_S2KS_ITERATED_AND_SALTED;
  650|       |
  651|       |    // check salt size
  652|    110|    auto &salt_bt = alg->sexp_string_at(1)->get_string();
  653|    110|    if (salt_bt.size() != PGP_SALT_SIZE) {
  ------------------
  |  |   92|    110|#define PGP_SALT_SIZE 8
  ------------------
  |  Branch (653:9): [True: 23, False: 87]
  ------------------
  654|     23|        RNP_LOG("Wrong salt size, should be %d but %d\n", PGP_SALT_SIZE, (int) salt_bt.size());
  ------------------
  |  |   76|     23|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     23|    do {                                                                                 \
  |  |  |  |   69|     23|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 23, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     23|            break;                                                                       \
  |  |  |  |   71|     23|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  655|     23|        return false;
  656|     23|    }
  657|       |
  658|       |    // salt
  659|     87|    memcpy(prot.s2k.salt, salt_bt.data(), salt_bt.size());
  660|       |    // s2k iterations
  661|     87|    auto iter = alg->sexp_string_at(2);
  662|     87|    prot.s2k.iterations = iter->as_unsigned();
  663|     87|    if (prot.s2k.iterations == UINT_MAX) {
  ------------------
  |  Branch (663:9): [True: 1, False: 86]
  ------------------
  664|      1|        RNP_LOG("Wrong numbers of iteration, %.*s\n",
  ------------------
  |  |   76|      1|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      1|    do {                                                                                 \
  |  |  |  |   69|      1|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 1, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      1|            break;                                                                       \
  |  |  |  |   71|      1|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  665|      1|                (int) iter->get_string().size(),
  666|      1|                (const char *) iter->get_string().data());
  667|      1|        return false;
  668|      1|    }
  669|       |
  670|       |    // iv
  671|     86|    auto &iv_bt = params->sexp_string_at(1)->get_string();
  672|     86|    if (iv_bt.size() != format->iv_size) {
  ------------------
  |  Branch (672:9): [True: 71, False: 15]
  ------------------
  673|     71|        RNP_LOG("Wrong nonce size, should be %zu but %zu\n", format->iv_size, iv_bt.size());
  ------------------
  |  |   76|     71|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|     71|    do {                                                                                 \
  |  |  |  |   69|     71|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 71, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|     71|            break;                                                                       \
  |  |  |  |   71|     71|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  674|     71|        return false;
  675|     71|    }
  676|     15|    memcpy(prot.iv, iv_bt.data(), iv_bt.size());
  677|       |
  678|       |    // we're all done if no password was provided (decryption not requested)
  679|     15|    if (!password) {
  ------------------
  |  Branch (679:9): [True: 15, False: 0]
  ------------------
  680|     15|        seckey.material->clear_secret();
  681|     15|        return true;
  682|     15|    }
  683|       |
  684|       |    // password was provided, so decrypt
  685|      0|    auto &       enc_bt = protected_key->sexp_string_at(3)->get_string();
  686|      0|    gnupg_sexp_t decrypted_s_exp;
  687|       |
  688|       |    // Build associated data (AD) that is not included in the ciphertext but that should be
  689|       |    // authenticated. gnupg builds AD as follows  (file 'protect.c' do_encryption/do_decryption
  690|       |    // functions)
  691|       |    //  -- "protected-private-key" section content
  692|       |    //  -- less "protected" subsection
  693|       |    //  -- serialized in canonical format
  694|      0|    std::string associated_data;
  695|      0|    if (format->with_associated_data) {
  ------------------
  |  Branch (695:9): [True: 0, False: 0]
  ------------------
  696|      0|        std::ostringstream   oss(std::ios_base::binary);
  697|      0|        sexp_output_stream_t os(&oss);
  698|      0|        os.var_put_char('(');
  699|      0|        for_each(list->begin(), list->end(), [&](const std::shared_ptr<sexp_object_t> &obj) {
  700|      0|            if (obj->sexp_list_view() != protected_key)
  701|      0|                obj->print_canonical(&os);
  702|      0|        });
  703|      0|        os.var_put_char(')');
  704|      0|        associated_data = oss.str();
  705|      0|    }
  706|       |
  707|      0|    if (!decrypt_protected_section(
  ------------------
  |  Branch (707:9): [True: 0, False: 0]
  ------------------
  708|      0|          enc_bt,
  709|      0|          seckey,
  710|      0|          password,
  711|      0|          decrypted_s_exp,
  712|      0|          format->with_associated_data ? (uint8_t *) associated_data.data() : nullptr,
  ------------------
  |  Branch (712:11): [True: 0, False: 0]
  ------------------
  713|      0|          format->with_associated_data ? associated_data.length() : 0)) {
  ------------------
  |  Branch (713:11): [True: 0, False: 0]
  ------------------
  714|      0|        return false;
  715|      0|    }
  716|       |    // see if we have a protected-at section
  717|      0|    char protected_at[G10_PROTECTED_AT_SIZE] = {0};
  718|      0|    auto protected_at_data = lookup_var_data(list, "protected-at");
  719|      0|    if (protected_at_data) {
  ------------------
  |  Branch (719:9): [True: 0, False: 0]
  ------------------
  720|      0|        if (protected_at_data->get_string().size() != G10_PROTECTED_AT_SIZE) {
  ------------------
  |  |   54|      0|#define G10_PROTECTED_AT_SIZE 15
  ------------------
  |  Branch (720:13): [True: 0, False: 0]
  ------------------
  721|      0|            RNP_LOG("protected-at has wrong length: %zu, expected, %d\n",
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  722|      0|                    protected_at_data->get_string().size(),
  723|      0|                    G10_PROTECTED_AT_SIZE);
  724|      0|            return false;
  725|      0|        }
  726|      0|        memcpy(protected_at,
  727|      0|               protected_at_data->get_string().data(),
  728|      0|               protected_at_data->get_string().size());
  729|      0|    }
  730|       |    // parse MPIs
  731|      0|    if (!parse_seckey(seckey, decrypted_s_exp.sexp_list_at(0))) {
  ------------------
  |  Branch (731:9): [True: 0, False: 0]
  ------------------
  732|      0|        RNP_LOG("failed to parse seckey");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  733|      0|        return false;
  734|      0|    }
  735|       |    // check hash, if present
  736|      0|    if (decrypted_s_exp.size() > 1) {
  ------------------
  |  Branch (736:9): [True: 0, False: 0]
  ------------------
  737|      0|        if (decrypted_s_exp.at(1)->is_sexp_string()) {
  ------------------
  |  Branch (737:13): [True: 0, False: 0]
  ------------------
  738|      0|            RNP_LOG("Wrong hash block type.");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  739|      0|            return false;
  740|      0|        }
  741|      0|        auto sub_el = decrypted_s_exp.sexp_list_at(1);
  742|      0|        if (sub_el->size() < 3 || !sub_el->at(0)->is_sexp_string() ||
  ------------------
  |  Branch (742:13): [True: 0, False: 0]
  |  Branch (742:35): [True: 0, False: 0]
  ------------------
  743|      0|            !sub_el->at(1)->is_sexp_string() || !sub_el->at(2)->is_sexp_string()) {
  ------------------
  |  Branch (743:13): [True: 0, False: 0]
  |  Branch (743:49): [True: 0, False: 0]
  ------------------
  744|      0|            RNP_LOG("Wrong hash block structure.");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  745|      0|            return false;
  746|      0|        }
  747|       |
  748|      0|        auto &hkey = sub_el->sexp_string_at(0)->get_string();
  749|      0|        if (hkey != "hash") {
  ------------------
  |  Branch (749:13): [True: 0, False: 0]
  ------------------
  750|      0|            RNP_LOG("Has got wrong hash block at encrypted key data.");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  751|      0|            return false;
  752|      0|        }
  753|      0|        auto &halg = sub_el->sexp_string_at(1)->get_string();
  754|      0|        if (halg != "sha1") {
  ------------------
  |  Branch (754:13): [True: 0, False: 0]
  ------------------
  755|      0|            RNP_LOG("Supported only sha1 hash at encrypted private key.");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  756|      0|            return false;
  757|      0|        }
  758|      0|        uint8_t checkhash[G10_SHA1_HASH_SIZE];
  759|      0|        if (!g10_calculated_hash(seckey, protected_at, checkhash)) {
  ------------------
  |  Branch (759:13): [True: 0, False: 0]
  ------------------
  760|      0|            RNP_LOG("failed to calculate hash");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  761|      0|            return false;
  762|      0|        }
  763|      0|        auto &hval = sub_el->sexp_string_at(2)->get_string();
  764|      0|        if (hval.size() != G10_SHA1_HASH_SIZE ||
  ------------------
  |  |   52|      0|#define G10_SHA1_HASH_SIZE 20
  ------------------
  |  Branch (764:13): [True: 0, False: 0]
  ------------------
  765|      0|            memcmp(checkhash, hval.data(), G10_SHA1_HASH_SIZE)) {
  ------------------
  |  |   52|      0|#define G10_SHA1_HASH_SIZE 20
  ------------------
  |  Branch (765:13): [True: 0, False: 0]
  ------------------
  766|      0|            RNP_LOG("Incorrect hash at encrypted private key.");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  767|      0|            return false;
  768|      0|        }
  769|      0|    }
  770|      0|    return true;
  771|      0|}
key_store_g10.cpp:_ZL12parse_formatPKcm:
  174|    623|{
  175|  2.31k|    for (size_t i = 0; i < ARRAY_SIZE(formats); i++) {
  ------------------
  |  |   34|  2.31k|#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
  ------------------
  |  Branch (175:24): [True: 1.86k, False: 452]
  ------------------
  176|  1.86k|        if (strlen(formats[i].g10_type) == format_len &&
  ------------------
  |  Branch (176:13): [True: 590, False: 1.27k]
  ------------------
  177|    590|            !strncmp(formats[i].g10_type, format, format_len)) {
  ------------------
  |  Branch (177:13): [True: 171, False: 419]
  ------------------
  178|    171|            return &formats[i];
  179|    171|        }
  180|  1.86k|    }
  181|    452|    return NULL;
  182|    623|}
key_store_g10.cpp:_ZL12parse_seckeyR13pgp_key_pkt_tPKN4sexp11sexp_list_tE:
  432|    228|{
  433|    228|    switch (seckey.alg) {
  434|     25|    case PGP_PKA_DSA: {
  ------------------
  |  Branch (434:5): [True: 25, False: 203]
  ------------------
  435|     25|        pgp::mpi x;
  436|     25|        auto     key = dynamic_cast<pgp::DSAKeyMaterial *>(seckey.material.get());
  437|     25|        if (!key || !read_mpi(s_exp, "x", x)) {
  ------------------
  |  Branch (437:13): [True: 0, False: 25]
  |  Branch (437:13): [True: 4, False: 21]
  |  Branch (437:21): [True: 4, False: 21]
  ------------------
  438|      4|            return false;
  439|      4|        }
  440|     21|        key->set_secret(x);
  441|     21|        x.forget();
  442|     21|        return true;
  443|     25|    }
  444|    103|    case PGP_PKA_RSA:
  ------------------
  |  Branch (444:5): [True: 103, False: 125]
  ------------------
  445|    103|    case PGP_PKA_RSA_ENCRYPT_ONLY:
  ------------------
  |  Branch (445:5): [True: 0, False: 228]
  ------------------
  446|    103|    case PGP_PKA_RSA_SIGN_ONLY: {
  ------------------
  |  Branch (446:5): [True: 0, False: 228]
  ------------------
  447|    103|        pgp::mpi d, p, q, u;
  448|    103|        auto     key = dynamic_cast<pgp::RSAKeyMaterial *>(seckey.material.get());
  449|    103|        if (!key || !read_mpi(s_exp, "d", d) || !read_mpi(s_exp, "p", p) ||
  ------------------
  |  Branch (449:13): [True: 0, False: 103]
  |  Branch (449:13): [True: 66, False: 37]
  |  Branch (449:21): [True: 27, False: 76]
  |  Branch (449:49): [True: 14, False: 62]
  ------------------
  450|     66|            !read_mpi(s_exp, "q", q) || !read_mpi(s_exp, "u", u)) {
  ------------------
  |  Branch (450:13): [True: 9, False: 53]
  |  Branch (450:41): [True: 16, False: 37]
  ------------------
  451|     66|            return false;
  452|     66|        }
  453|     37|        key->set_secret(d, p, q, u);
  454|     37|        d.forget();
  455|     37|        p.forget();
  456|     37|        q.forget();
  457|     37|        u.forget();
  458|     37|        return true;
  459|    103|    }
  460|     69|    case PGP_PKA_ELGAMAL:
  ------------------
  |  Branch (460:5): [True: 69, False: 159]
  ------------------
  461|     69|    case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN: {
  ------------------
  |  Branch (461:5): [True: 0, False: 228]
  ------------------
  462|     69|        pgp::mpi x;
  463|     69|        auto     key = dynamic_cast<pgp::EGKeyMaterial *>(seckey.material.get());
  464|     69|        if (!key || !read_mpi(s_exp, "x", x)) {
  ------------------
  |  Branch (464:13): [True: 0, False: 69]
  |  Branch (464:13): [True: 15, False: 54]
  |  Branch (464:21): [True: 15, False: 54]
  ------------------
  465|     15|            return false;
  466|     15|        }
  467|     54|        key->set_secret(x);
  468|     54|        x.forget();
  469|     54|        return true;
  470|     69|    }
  471|      5|    case PGP_PKA_ECDSA:
  ------------------
  |  Branch (471:5): [True: 5, False: 223]
  ------------------
  472|     28|    case PGP_PKA_ECDH:
  ------------------
  |  Branch (472:5): [True: 23, False: 205]
  ------------------
  473|     31|    case PGP_PKA_EDDSA: {
  ------------------
  |  Branch (473:5): [True: 3, False: 225]
  ------------------
  474|     31|        pgp::mpi x;
  475|     31|        auto     key = dynamic_cast<pgp::ECKeyMaterial *>(seckey.material.get());
  476|     31|        if (!key || !read_mpi(s_exp, "d", x)) {
  ------------------
  |  Branch (476:13): [True: 0, False: 31]
  |  Branch (476:13): [True: 6, False: 25]
  |  Branch (476:21): [True: 6, False: 25]
  ------------------
  477|      6|            return false;
  478|      6|        }
  479|     25|        key->set_secret(x);
  480|     25|        x.forget();
  481|     25|        return true;
  482|     31|    }
  483|      0|    default:
  ------------------
  |  Branch (483:5): [True: 0, False: 228]
  ------------------
  484|      0|        RNP_LOG("Unsupported public key algorithm: %d", (int) seckey.alg);
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  485|      0|        return false;
  486|    228|    }
  487|    228|}

_ZN3rnp8KeyStore5clearEv:
  209|  4.17k|{
  210|  4.17k|    keybyfp.clear();
  211|  4.17k|    keys.clear();
  212|  4.17k|    blobs.clear();
  213|  4.17k|}
_ZN3rnp8KeyStore20refresh_subkey_gripsERNS_3KeyE:
  223|    152|{
  224|    152|    if (key.is_subkey()) {
  ------------------
  |  Branch (224:9): [True: 0, False: 152]
  ------------------
  225|      0|        RNP_LOG("wrong argument");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  226|      0|        return false;
  227|      0|    }
  228|       |
  229|    152|    for (auto &skey : keys) {
  ------------------
  |  Branch (229:21): [True: 152, False: 152]
  ------------------
  230|    152|        bool found = false;
  231|       |
  232|       |        /* if we have primary_grip then we also added to subkey_grips */
  233|    152|        if (!skey.is_subkey() || skey.has_primary_fp()) {
  ------------------
  |  Branch (233:13): [True: 152, False: 0]
  |  Branch (233:34): [True: 0, False: 0]
  ------------------
  234|    152|            continue;
  235|    152|        }
  236|       |
  237|      0|        for (size_t i = 0; i < skey.sig_count(); i++) {
  ------------------
  |  Branch (237:28): [True: 0, False: 0]
  ------------------
  238|      0|            auto &subsig = skey.get_sig(i);
  239|       |
  240|      0|            if (subsig.sig.type() != PGP_SIG_SUBKEY) {
  ------------------
  |  Branch (240:17): [True: 0, False: 0]
  ------------------
  241|      0|                continue;
  242|      0|            }
  243|      0|            if (subsig.sig.has_keyfp() && (key.fp() == subsig.sig.keyfp())) {
  ------------------
  |  Branch (243:17): [True: 0, False: 0]
  |  Branch (243:17): [True: 0, False: 0]
  |  Branch (243:43): [True: 0, False: 0]
  ------------------
  244|      0|                found = true;
  245|      0|                break;
  246|      0|            }
  247|      0|            if (subsig.sig.has_keyid() && (key.keyid() == subsig.sig.keyid())) {
  ------------------
  |  Branch (247:17): [True: 0, False: 0]
  |  Branch (247:17): [True: 0, False: 0]
  |  Branch (247:43): [True: 0, False: 0]
  ------------------
  248|      0|                found = true;
  249|      0|                break;
  250|      0|            }
  251|      0|        }
  252|       |
  253|      0|        if (found) {
  ------------------
  |  Branch (253:13): [True: 0, False: 0]
  ------------------
  254|      0|            try {
  255|      0|                key.link_subkey_fp(skey);
  256|      0|            } catch (const std::exception &e) {
  257|       |                /* LCOV_EXCL_START */
  258|      0|                RNP_LOG("%s", e.what());
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  259|      0|                return false;
  260|       |                /* LCOV_EXCL_END */
  261|      0|            }
  262|      0|        }
  263|      0|    }
  264|       |
  265|    152|    return true;
  266|    152|}
_ZN3rnp8KeyStore7add_keyERNS_3KeyE:
  332|    152|{
  333|    152|    assert(srckey.type() && srckey.version());
  334|    152|    auto *added_key = get_key(srckey.fp());
  335|       |    /* we cannot merge G10 keys - so just return it */
  336|    152|    if (added_key && (srckey.format == KeyFormat::G10)) {
  ------------------
  |  Branch (336:9): [True: 0, False: 152]
  |  Branch (336:22): [True: 0, False: 0]
  ------------------
  337|      0|        return added_key;
  338|      0|    }
  339|       |    /* different processing for subkeys */
  340|    152|    if (srckey.is_subkey()) {
  ------------------
  |  Branch (340:9): [True: 0, False: 152]
  ------------------
  341|      0|        return add_subkey(srckey, added_key);
  342|      0|    }
  343|       |
  344|    152|    if (added_key) {
  ------------------
  |  Branch (344:9): [True: 0, False: 152]
  ------------------
  345|      0|        if (!added_key->merge(srckey)) {
  ------------------
  |  Branch (345:13): [True: 0, False: 0]
  ------------------
  346|      0|            RNP_LOG_KEY("failed to merge key %s", &srckey);
  ------------------
  |  |   79|      0|    do {                                                                                \
  |  |   80|      0|        if (!(key)) {                                                                   \
  |  |  ------------------
  |  |  |  Branch (80:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   81|      0|            RNP_LOG(msg, "(null)");                                                     \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|            break;                                                                      \
  |  |   83|      0|        }                                                                               \
  |  |   84|      0|        auto keyid = (key)->keyid();                                                    \
  |  |   85|      0|        auto idhex = bin_to_hex(keyid.data(), keyid.size(), rnp::HexFormat::Lowercase); \
  |  |   86|      0|        RNP_LOG(msg, idhex.c_str());                                                    \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   87|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (87:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  347|      0|            return NULL;
  348|      0|        }
  349|    152|    } else {
  350|    152|        try {
  351|    152|            keys.emplace_back();
  352|    152|            added_key = &keys.back();
  353|    152|            keybyfp[srckey.fp()] = std::prev(keys.end());
  354|    152|            *added_key = Key(srckey);
  355|       |            /* primary key may be added after subkeys, so let's handle this case correctly */
  356|    152|            if (!refresh_subkey_grips(*added_key)) {
  ------------------
  |  Branch (356:17): [True: 0, False: 152]
  ------------------
  357|      0|                RNP_LOG_KEY("failed to refresh subkey grips for %s", added_key);
  ------------------
  |  |   79|      0|    do {                                                                                \
  |  |   80|      0|        if (!(key)) {                                                                   \
  |  |  ------------------
  |  |  |  Branch (80:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   81|      0|            RNP_LOG(msg, "(null)");                                                     \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|            break;                                                                      \
  |  |   83|      0|        }                                                                               \
  |  |   84|      0|        auto keyid = (key)->keyid();                                                    \
  |  |   85|      0|        auto idhex = bin_to_hex(keyid.data(), keyid.size(), rnp::HexFormat::Lowercase); \
  |  |   86|      0|        RNP_LOG(msg, idhex.c_str());                                                    \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   87|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (87:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  358|      0|            }
  359|    152|        } catch (const std::exception &e) {
  360|       |            /* LCOV_EXCL_START */
  361|      0|            RNP_LOG_KEY("key %s copying failed", &srckey);
  ------------------
  |  |   79|      0|    do {                                                                                \
  |  |   80|      0|        if (!(key)) {                                                                   \
  |  |  ------------------
  |  |  |  Branch (80:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   81|      0|            RNP_LOG(msg, "(null)");                                                     \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|            break;                                                                      \
  |  |   83|      0|        }                                                                               \
  |  |   84|      0|        auto keyid = (key)->keyid();                                                    \
  |  |   85|      0|        auto idhex = bin_to_hex(keyid.data(), keyid.size(), rnp::HexFormat::Lowercase); \
  |  |   86|      0|        RNP_LOG(msg, idhex.c_str());                                                    \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   87|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (87:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  362|      0|            RNP_LOG("%s", e.what());
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  363|      0|            if (added_key) {
  ------------------
  |  Branch (363:17): [True: 0, False: 0]
  ------------------
  364|      0|                keys.pop_back();
  365|      0|                keybyfp.erase(srckey.fp());
  366|      0|            }
  367|      0|            return NULL;
  368|       |            /* LCOV_EXCL_END */
  369|      0|        }
  370|    152|    }
  371|       |
  372|       |    /* validate all added keys if not disabled or already validated */
  373|    152|    if (!disable_validation && !added_key->validated()) {
  ------------------
  |  Branch (373:9): [True: 152, False: 0]
  |  Branch (373:32): [True: 152, False: 0]
  ------------------
  374|    152|        added_key->revalidate(*this);
  375|    152|    } else if (!added_key->refresh_data(secctx)) {
  ------------------
  |  Branch (375:16): [True: 0, False: 0]
  ------------------
  376|      0|        RNP_LOG_KEY("Failed to refresh key %s data", &srckey);
  ------------------
  |  |   79|      0|    do {                                                                                \
  |  |   80|      0|        if (!(key)) {                                                                   \
  |  |  ------------------
  |  |  |  Branch (80:13): [True: 0, False: 0]
  |  |  ------------------
  |  |   81|      0|            RNP_LOG(msg, "(null)");                                                     \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   82|      0|            break;                                                                      \
  |  |   83|      0|        }                                                                               \
  |  |   84|      0|        auto keyid = (key)->keyid();                                                    \
  |  |   85|      0|        auto idhex = bin_to_hex(keyid.data(), keyid.size(), rnp::HexFormat::Lowercase); \
  |  |   86|      0|        RNP_LOG(msg, idhex.c_str());                                                    \
  |  |  ------------------
  |  |  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  |  |  ------------------
  |  |  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  |  |  ------------------
  |  |  |  |  ------------------
  |  |  ------------------
  |  |   87|      0|    } while (0)
  |  |  ------------------
  |  |  |  Branch (87:14): [Folded, False: 0]
  |  |  ------------------
  ------------------
  377|      0|    }
  378|       |    /* Revalidate non-self revocations for all keys in keyring, as added_key key could be a
  379|       |     * revoker. Should not be time-consuming as `validate_desig_revokes()` has early exit. */
  380|    152|    for (auto &key : keys) {
  ------------------
  |  Branch (380:20): [True: 152, False: 152]
  ------------------
  381|    152|        if (&key == added_key) {
  ------------------
  |  Branch (381:13): [True: 152, False: 0]
  ------------------
  382|    152|            continue;
  383|    152|        }
  384|      0|        if (key.validate_desig_revokes(*this)) {
  ------------------
  |  Branch (384:13): [True: 0, False: 0]
  ------------------
  385|      0|            key.revalidate(*this);
  386|      0|        }
  387|      0|    }
  388|    152|    return added_key;
  389|    152|}
_ZN3rnp8KeyStore7get_keyERKN3pgp11FingerprintE:
  616|    152|{
  617|    152|    auto it = keybyfp.find(fpr);
  618|    152|    if (it == keybyfp.end()) {
  ------------------
  |  Branch (618:9): [True: 152, False: 0]
  ------------------
  619|    152|        return nullptr;
  620|    152|    }
  621|      0|    return &*it->second;
  622|    152|}
_ZN3rnp8KeyStoreD2Ev:
  723|  4.17k|{
  724|  4.17k|    clear();
  725|  4.17k|}

_ZN12pgp_source_t4readEPvmPm:
   57|  7.56k|{
   58|  7.56k|    size_t left = len;
   59|  7.56k|    size_t read;
   60|  7.56k|    bool   readahead = cache ? cache->readahead : false;
  ------------------
  |  Branch (60:24): [True: 7.56k, False: 0]
  ------------------
   61|       |
   62|  7.56k|    if (error_) {
  ------------------
  |  Branch (62:9): [True: 0, False: 7.56k]
  ------------------
   63|      0|        return false;
   64|      0|    }
   65|       |
   66|  7.56k|    if (eof_ || (len == 0)) {
  ------------------
  |  Branch (66:9): [True: 0, False: 7.56k]
  |  Branch (66:17): [True: 0, False: 7.56k]
  ------------------
   67|      0|        *readres = 0;
   68|      0|        return true;
   69|      0|    }
   70|       |
   71|       |    // Do not read more then available if source size is known
   72|  7.56k|    if (knownsize && (readb + len > size)) {
  ------------------
  |  Branch (72:9): [True: 7.56k, False: 0]
  |  Branch (72:22): [True: 4.13k, False: 3.42k]
  ------------------
   73|  4.13k|        len = size - readb;
   74|  4.13k|        left = len;
   75|  4.13k|        readahead = false;
   76|  4.13k|    }
   77|       |
   78|       |    // Check whether we have cache and there is data inside
   79|  7.56k|    if (cache && (cache->len > cache->pos)) {
  ------------------
  |  Branch (79:9): [True: 7.56k, False: 0]
  |  Branch (79:18): [True: 0, False: 7.56k]
  ------------------
   80|      0|        read = cache->len - cache->pos;
   81|      0|        if (read >= len) {
  ------------------
  |  Branch (81:13): [True: 0, False: 0]
  ------------------
   82|      0|            memcpy(buf, &cache->buf[cache->pos], len);
   83|      0|            cache->pos += len;
   84|      0|            goto finish;
   85|      0|        } else {
   86|      0|            memcpy(buf, &cache->buf[cache->pos], read);
   87|      0|            cache->pos += read;
   88|      0|            buf = (uint8_t *) buf + read;
   89|      0|            left = len - read;
   90|      0|        }
   91|      0|    }
   92|       |
   93|       |    // If we got here then we have empty cache or no cache at all
   94|  11.7k|    while (left > 0) {
  ------------------
  |  Branch (94:12): [True: 7.56k, False: 4.13k]
  ------------------
   95|  7.56k|        if (left > sizeof(cache->buf) || !readahead || !cache) {
  ------------------
  |  Branch (95:13): [True: 0, False: 7.56k]
  |  Branch (95:42): [True: 4.13k, False: 3.42k]
  |  Branch (95:56): [True: 0, False: 3.42k]
  ------------------
   96|       |            // If there is no cache or chunk is larger then read directly
   97|  4.13k|            if (!raw_read(this, buf, left, &read)) {
  ------------------
  |  Branch (97:17): [True: 0, False: 4.13k]
  ------------------
   98|      0|                error_ = 1;
   99|      0|                return false;
  100|      0|            }
  101|  4.13k|            if (!read) {
  ------------------
  |  Branch (101:17): [True: 0, False: 4.13k]
  ------------------
  102|      0|                eof_ = true;
  103|      0|                len = len - left;
  104|      0|                goto finish;
  105|      0|            }
  106|  4.13k|            left -= read;
  107|  4.13k|            buf = (uint8_t *) buf + read;
  108|  4.13k|        } else {
  109|       |            // Try to fill the cache to avoid small reads
  110|  3.42k|            if (!raw_read(this, &cache->buf[0], sizeof(cache->buf), &read)) {
  ------------------
  |  Branch (110:17): [True: 0, False: 3.42k]
  ------------------
  111|      0|                error_ = true;
  112|      0|                return false;
  113|      0|            }
  114|  3.42k|            if (!read) {
  ------------------
  |  Branch (114:17): [True: 0, False: 3.42k]
  ------------------
  115|      0|                eof_ = true;
  116|      0|                len = len - left;
  117|      0|                goto finish;
  118|  3.42k|            } else if (read < left) {
  ------------------
  |  Branch (118:24): [True: 0, False: 3.42k]
  ------------------
  119|      0|                memcpy(buf, &cache->buf[0], read);
  120|      0|                left -= read;
  121|      0|                buf = (uint8_t *) buf + read;
  122|  3.42k|            } else {
  123|  3.42k|                memcpy(buf, &cache->buf[0], left);
  124|  3.42k|                cache->pos = left;
  125|  3.42k|                cache->len = read;
  126|  3.42k|                goto finish;
  127|  3.42k|            }
  128|  3.42k|        }
  129|  7.56k|    }
  130|       |
  131|  7.56k|finish:
  132|  7.56k|    readb += len;
  133|  7.56k|    if (knownsize && (readb == size)) {
  ------------------
  |  Branch (133:9): [True: 7.56k, False: 0]
  |  Branch (133:22): [True: 4.17k, False: 3.38k]
  ------------------
  134|  4.17k|        eof_ = true;
  135|  4.17k|    }
  136|  7.56k|    *readres = len;
  137|  7.56k|    return true;
  138|  7.56k|}
_ZN12pgp_source_t5closeEv:
  281|  8.35k|{
  282|  8.35k|    if (raw_close) {
  ------------------
  |  Branch (282:9): [True: 8.35k, False: 0]
  ------------------
  283|  8.35k|        raw_close(this);
  284|  8.35k|    }
  285|       |
  286|  8.35k|    if (cache) {
  ------------------
  |  Branch (286:9): [True: 8.35k, False: 0]
  ------------------
  287|  8.35k|        free(cache);
  288|       |        cache = NULL;
  289|  8.35k|    }
  290|  8.35k|}
_Z15init_src_commonP12pgp_source_tm:
  369|  8.35k|{
  370|  8.35k|    memset(src, 0, sizeof(*src));
  371|  8.35k|    src->cache = (pgp_source_cache_t *) calloc(1, sizeof(*src->cache));
  372|  8.35k|    if (!src->cache) {
  ------------------
  |  Branch (372:9): [True: 0, False: 8.35k]
  ------------------
  373|      0|        RNP_LOG("cache allocation failed");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  374|      0|        return false;
  375|      0|    }
  376|  8.35k|    src->cache->readahead = true;
  377|  8.35k|    if (!paramsize) {
  ------------------
  |  Branch (377:9): [True: 0, False: 8.35k]
  ------------------
  378|      0|        return true;
  379|      0|    }
  380|  8.35k|    src->param = calloc(1, paramsize);
  381|  8.35k|    if (!src->param) {
  ------------------
  |  Branch (381:9): [True: 0, False: 8.35k]
  ------------------
  382|      0|        RNP_LOG("param allocation failed");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  383|      0|        free(src->cache);
  384|      0|        src->cache = NULL;
  385|      0|        return false;
  386|      0|    }
  387|  8.35k|    return true;
  388|  8.35k|}
_Z12init_mem_srcP12pgp_source_tPKvmb:
  546|  8.35k|{
  547|  8.35k|    if (!mem && len) {
  ------------------
  |  Branch (547:9): [True: 0, False: 8.35k]
  |  Branch (547:17): [True: 0, False: 0]
  ------------------
  548|      0|        return RNP_ERROR_NULL_POINTER;
  549|      0|    }
  550|       |    /* this is actually double buffering, but then src_peek will fail */
  551|  8.35k|    if (!init_src_common(src, sizeof(pgp_source_mem_param_t))) {
  ------------------
  |  Branch (551:9): [True: 0, False: 8.35k]
  ------------------
  552|      0|        return RNP_ERROR_OUT_OF_MEMORY;
  553|      0|    }
  554|       |
  555|  8.35k|    pgp_source_mem_param_t *param = (pgp_source_mem_param_t *) src->param;
  556|  8.35k|    param->memory = mem;
  557|  8.35k|    param->len = len;
  558|  8.35k|    param->pos = 0;
  559|  8.35k|    param->free = free;
  560|  8.35k|    src->raw_read = mem_src_read;
  561|  8.35k|    src->raw_close = mem_src_close;
  562|  8.35k|    src->raw_finish = NULL;
  563|  8.35k|    src->size = len;
  564|  8.35k|    src->knownsize = 1;
  565|  8.35k|    src->type = PGP_STREAM_MEMORY;
  566|       |
  567|  8.35k|    return RNP_SUCCESS;
  568|  8.35k|}
_Z12read_mem_srcP12pgp_source_tS0_:
  588|  4.17k|{
  589|  4.17k|    pgp_dest_t   dst;
  590|  4.17k|    rnp_result_t ret = RNP_ERROR_GENERIC;
  591|  4.17k|    size_t       sz = 0;
  592|       |
  593|  4.17k|    if ((ret = init_mem_dest(&dst, NULL, 0))) {
  ------------------
  |  Branch (593:9): [True: 0, False: 4.17k]
  ------------------
  594|      0|        return ret;
  595|      0|    }
  596|       |
  597|  4.17k|    if ((ret = dst_write_src(readsrc, &dst))) {
  ------------------
  |  Branch (597:9): [True: 0, False: 4.17k]
  ------------------
  598|      0|        goto done;
  599|      0|    }
  600|       |
  601|  4.17k|    sz = dst.writeb;
  602|  4.17k|    ret = init_mem_src(src, mem_dest_own_memory(&dst), sz, true);
  603|  4.17k|done:
  604|  4.17k|    dst_close(&dst, true);
  605|  4.17k|    return ret;
  606|  4.17k|}
_Z18mem_src_get_memoryP12pgp_source_tb:
  610|  4.32k|{
  611|  4.32k|    if (src->type != PGP_STREAM_MEMORY) {
  ------------------
  |  Branch (611:9): [True: 0, False: 4.32k]
  ------------------
  612|      0|        RNP_LOG("wrong function call");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  613|      0|        return NULL;
  614|      0|    }
  615|       |
  616|  4.32k|    if (!src->param) {
  ------------------
  |  Branch (616:9): [True: 0, False: 4.32k]
  ------------------
  617|      0|        return NULL;
  618|      0|    }
  619|       |
  620|  4.32k|    pgp_source_mem_param_t *param = (pgp_source_mem_param_t *) src->param;
  621|  4.32k|    if (own) {
  ------------------
  |  Branch (621:9): [True: 0, False: 4.32k]
  ------------------
  622|      0|        param->free = false;
  623|      0|    }
  624|  4.32k|    return param->memory;
  625|  4.32k|}
_Z15init_dst_commonP10pgp_dest_tm:
  629|  4.17k|{
  630|  4.17k|    memset(dst, 0, sizeof(*dst));
  631|  4.17k|    dst->werr = RNP_SUCCESS;
  632|  4.17k|    if (!paramsize) {
  ------------------
  |  Branch (632:9): [True: 0, False: 4.17k]
  ------------------
  633|      0|        return true;
  634|      0|    }
  635|       |    /* allocate param */
  636|  4.17k|    dst->param = calloc(1, paramsize);
  637|  4.17k|    if (!dst->param) {
  ------------------
  |  Branch (637:9): [True: 0, False: 4.17k]
  ------------------
  638|      0|        RNP_LOG("allocation failed");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  639|      0|    }
  640|  4.17k|    return dst->param;
  641|  4.17k|}
_Z9dst_writeP10pgp_dest_tPKvm:
  645|  7.56k|{
  646|       |    /* we call write function only if all previous calls succeeded */
  647|  7.56k|    if ((len > 0) && (dst->write) && (dst->werr == RNP_SUCCESS)) {
  ------------------
  |  Branch (647:9): [True: 7.56k, False: 0]
  |  Branch (647:22): [True: 7.56k, False: 0]
  |  Branch (647:38): [True: 7.56k, False: 0]
  ------------------
  648|       |        /* if cache non-empty and len will overflow it then fill it and write out */
  649|  7.56k|        if ((dst->clen > 0) && (dst->clen + len > sizeof(dst->cache))) {
  ------------------
  |  Branch (649:13): [True: 0, False: 7.56k]
  |  Branch (649:32): [True: 0, False: 0]
  ------------------
  650|      0|            memcpy(dst->cache + dst->clen, buf, sizeof(dst->cache) - dst->clen);
  651|      0|            buf = (uint8_t *) buf + sizeof(dst->cache) - dst->clen;
  652|      0|            len -= sizeof(dst->cache) - dst->clen;
  653|      0|            dst->werr = dst->write(dst, dst->cache, sizeof(dst->cache));
  654|      0|            dst->writeb += sizeof(dst->cache);
  655|      0|            dst->clen = 0;
  656|      0|            if (dst->werr != RNP_SUCCESS) {
  ------------------
  |  Branch (656:17): [True: 0, False: 0]
  ------------------
  657|      0|                return;
  658|      0|            }
  659|      0|        }
  660|       |
  661|       |        /* here everything will fit into the cache or cache is empty */
  662|  7.56k|        if (dst->no_cache || (len > sizeof(dst->cache))) {
  ------------------
  |  Branch (662:13): [True: 7.56k, False: 0]
  |  Branch (662:30): [True: 0, False: 0]
  ------------------
  663|  7.56k|            dst->werr = dst->write(dst, buf, len);
  664|  7.56k|            if (!dst->werr) {
  ------------------
  |  Branch (664:17): [True: 7.56k, False: 0]
  ------------------
  665|  7.56k|                dst->writeb += len;
  666|  7.56k|            }
  667|  7.56k|        } else {
  668|      0|            memcpy(dst->cache + dst->clen, buf, len);
  669|      0|            dst->clen += len;
  670|      0|        }
  671|  7.56k|    }
  672|  7.56k|}
_Z9dst_flushP10pgp_dest_t:
  700|  8.35k|{
  701|  8.35k|    if ((dst->clen > 0) && (dst->write) && (dst->werr == RNP_SUCCESS)) {
  ------------------
  |  Branch (701:9): [True: 0, False: 8.35k]
  |  Branch (701:28): [True: 0, False: 0]
  |  Branch (701:44): [True: 0, False: 0]
  ------------------
  702|      0|        dst->werr = dst->write(dst, dst->cache, dst->clen);
  703|      0|        dst->writeb += dst->clen;
  704|      0|        dst->clen = 0;
  705|      0|    }
  706|  8.35k|}
_Z10dst_finishP10pgp_dest_t:
  710|  4.17k|{
  711|  4.17k|    rnp_result_t res = RNP_SUCCESS;
  712|       |
  713|  4.17k|    if (!dst->finished) {
  ------------------
  |  Branch (713:9): [True: 4.17k, False: 0]
  ------------------
  714|       |        /* flush write cache in the dst */
  715|  4.17k|        dst_flush(dst);
  716|  4.17k|        if (dst->finish) {
  ------------------
  |  Branch (716:13): [True: 0, False: 4.17k]
  ------------------
  717|      0|            res = dst->finish(dst);
  718|      0|        }
  719|  4.17k|        dst->finished = true;
  720|  4.17k|    }
  721|       |
  722|  4.17k|    return res;
  723|  4.17k|}
_Z9dst_closeP10pgp_dest_tb:
  727|  4.17k|{
  728|  4.17k|    if (!discard && !dst->finished) {
  ------------------
  |  Branch (728:9): [True: 0, False: 4.17k]
  |  Branch (728:21): [True: 0, False: 0]
  ------------------
  729|      0|        dst_finish(dst);
  730|      0|    }
  731|       |
  732|  4.17k|    if (dst->close) {
  ------------------
  |  Branch (732:9): [True: 4.17k, False: 0]
  ------------------
  733|  4.17k|        dst->close(dst, discard);
  734|  4.17k|    }
  735|  4.17k|}
_Z13init_mem_destP10pgp_dest_tPvj:
 1035|  4.17k|{
 1036|  4.17k|    pgp_dest_mem_param_t *param;
 1037|       |
 1038|  4.17k|    if (!init_dst_common(dst, sizeof(*param))) {
  ------------------
  |  Branch (1038:9): [True: 0, False: 4.17k]
  ------------------
 1039|      0|        return RNP_ERROR_OUT_OF_MEMORY;
 1040|      0|    }
 1041|       |
 1042|  4.17k|    param = (pgp_dest_mem_param_t *) dst->param;
 1043|       |
 1044|  4.17k|    param->maxalloc = len;
 1045|  4.17k|    param->allocated = mem ? len : 0;
  ------------------
  |  Branch (1045:24): [True: 0, False: 4.17k]
  ------------------
 1046|  4.17k|    param->memory = mem;
 1047|  4.17k|    param->free = !mem;
 1048|  4.17k|    param->secure = false;
 1049|       |
 1050|  4.17k|    dst->write = mem_dst_write;
 1051|  4.17k|    dst->close = mem_dst_close;
 1052|  4.17k|    dst->type = PGP_STREAM_MEMORY;
 1053|  4.17k|    dst->werr = RNP_SUCCESS;
 1054|  4.17k|    dst->no_cache = true;
 1055|       |
 1056|  4.17k|    return RNP_SUCCESS;
 1057|  4.17k|}
_Z19mem_dest_own_memoryP10pgp_dest_t:
 1092|  4.17k|{
 1093|  4.17k|    if (dst->type != PGP_STREAM_MEMORY) {
  ------------------
  |  Branch (1093:9): [True: 0, False: 4.17k]
  ------------------
 1094|      0|        RNP_LOG("wrong function call");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1095|      0|        return NULL;
 1096|      0|    }
 1097|       |
 1098|  4.17k|    pgp_dest_mem_param_t *param = (pgp_dest_mem_param_t *) dst->param;
 1099|       |
 1100|  4.17k|    if (!param) {
  ------------------
  |  Branch (1100:9): [True: 0, False: 4.17k]
  ------------------
 1101|      0|        RNP_LOG("null param");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1102|      0|        return NULL;
 1103|      0|    }
 1104|       |
 1105|  4.17k|    dst_finish(dst);
 1106|       |
 1107|  4.17k|    if (param->free) {
  ------------------
  |  Branch (1107:9): [True: 4.17k, False: 0]
  ------------------
 1108|  4.17k|        if (!dst->writeb) {
  ------------------
  |  Branch (1108:13): [True: 0, False: 4.17k]
  ------------------
 1109|      0|            free(param->memory);
 1110|      0|            param->memory = NULL;
 1111|      0|            return param->memory;
 1112|      0|        }
 1113|       |        /* it may be larger then required - let's truncate */
 1114|  4.17k|        void *newalloc = realloc(param->memory, dst->writeb);
 1115|  4.17k|        if (!newalloc) {
  ------------------
  |  Branch (1115:13): [True: 0, False: 4.17k]
  ------------------
 1116|      0|            return NULL;
 1117|      0|        }
 1118|  4.17k|        param->memory = newalloc;
 1119|  4.17k|        param->allocated = dst->writeb;
 1120|  4.17k|        param->free = false;
 1121|  4.17k|        return param->memory;
 1122|  4.17k|    }
 1123|       |
 1124|       |    /* in this case we should copy the memory */
 1125|      0|    void *res = malloc(dst->writeb);
 1126|      0|    if (res) {
  ------------------
  |  Branch (1126:9): [True: 0, False: 0]
  ------------------
 1127|      0|        memcpy(res, param->memory, dst->writeb);
 1128|      0|    }
 1129|      0|    return res;
 1130|  4.17k|}
_Z13dst_write_srcP12pgp_source_tP10pgp_dest_tm:
 1174|  4.17k|{
 1175|  4.17k|    const size_t bufsize = PGP_INPUT_CACHE_SIZE;
  ------------------
  |  |   35|  4.17k|#define PGP_INPUT_CACHE_SIZE 32768
  ------------------
 1176|  4.17k|    uint8_t *    readbuf = (uint8_t *) malloc(bufsize);
 1177|  4.17k|    if (!readbuf) {
  ------------------
  |  Branch (1177:9): [True: 0, False: 4.17k]
  ------------------
 1178|      0|        return RNP_ERROR_OUT_OF_MEMORY;
 1179|      0|    }
 1180|  4.17k|    rnp_result_t res = RNP_SUCCESS;
 1181|  4.17k|    try {
 1182|  4.17k|        size_t   read;
 1183|  4.17k|        uint64_t totalread = 0;
 1184|       |
 1185|  11.7k|        while (!src->eof_) {
  ------------------
  |  Branch (1185:16): [True: 7.56k, False: 4.17k]
  ------------------
 1186|  7.56k|            if (!src->read(readbuf, bufsize, &read)) {
  ------------------
  |  Branch (1186:17): [True: 0, False: 7.56k]
  ------------------
 1187|      0|                res = RNP_ERROR_GENERIC;
 1188|      0|                break;
 1189|      0|            }
 1190|  7.56k|            if (!read) {
  ------------------
  |  Branch (1190:17): [True: 0, False: 7.56k]
  ------------------
 1191|      0|                continue;
 1192|      0|            }
 1193|  7.56k|            totalread += read;
 1194|  7.56k|            if (limit && totalread > limit) {
  ------------------
  |  Branch (1194:17): [True: 0, False: 7.56k]
  |  Branch (1194:26): [True: 0, False: 0]
  ------------------
 1195|      0|                res = RNP_ERROR_GENERIC;
 1196|      0|                break;
 1197|      0|            }
 1198|  7.56k|            if (dst) {
  ------------------
  |  Branch (1198:17): [True: 7.56k, False: 0]
  ------------------
 1199|  7.56k|                dst_write(dst, readbuf, read);
 1200|  7.56k|                if (dst->werr) {
  ------------------
  |  Branch (1200:21): [True: 0, False: 7.56k]
  ------------------
 1201|      0|                    RNP_LOG("failed to output data");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1202|      0|                    res = RNP_ERROR_WRITE;
 1203|      0|                    break;
 1204|      0|                }
 1205|  7.56k|            }
 1206|  7.56k|        }
 1207|  4.17k|    } catch (...) {
 1208|      0|        free(readbuf);
 1209|      0|        throw;
 1210|      0|    }
 1211|  4.17k|    free(readbuf);
 1212|  4.17k|    if (res || !dst) {
  ------------------
  |  Branch (1212:9): [True: 0, False: 4.17k]
  |  Branch (1212:16): [True: 0, False: 4.17k]
  ------------------
 1213|      0|        return res;
 1214|      0|    }
 1215|  4.17k|    dst_flush(dst);
 1216|  4.17k|    return dst->werr;
 1217|  4.17k|}
stream-common.cpp:_ZL12mem_src_readP12pgp_source_tPvmPm:
  516|  7.56k|{
  517|  7.56k|    pgp_source_mem_param_t *param = (pgp_source_mem_param_t *) src->param;
  518|  7.56k|    if (!param) {
  ------------------
  |  Branch (518:9): [True: 0, False: 7.56k]
  ------------------
  519|      0|        return false;
  520|      0|    }
  521|       |
  522|  7.56k|    if (len > param->len - param->pos) {
  ------------------
  |  Branch (522:9): [True: 0, False: 7.56k]
  ------------------
  523|      0|        len = param->len - param->pos;
  524|      0|    }
  525|  7.56k|    memcpy(buf, (uint8_t *) param->memory + param->pos, len);
  526|  7.56k|    param->pos += len;
  527|  7.56k|    *read = len;
  528|  7.56k|    return true;
  529|  7.56k|}
stream-common.cpp:_ZL13mem_src_closeP12pgp_source_t:
  533|  8.35k|{
  534|  8.35k|    pgp_source_mem_param_t *param = (pgp_source_mem_param_t *) src->param;
  535|  8.35k|    if (param) {
  ------------------
  |  Branch (535:9): [True: 8.35k, False: 0]
  ------------------
  536|  8.35k|        if (param->free) {
  ------------------
  |  Branch (536:13): [True: 4.17k, False: 4.17k]
  ------------------
  537|  4.17k|            free((void *) param->memory);
  538|  4.17k|        }
  539|  8.35k|        free(src->param);
  540|       |        src->param = NULL;
  541|  8.35k|    }
  542|  8.35k|}
stream-common.cpp:_ZL13mem_dst_writeP10pgp_dest_tPKvm:
  972|  7.56k|{
  973|  7.56k|    pgp_dest_mem_param_t *param = (pgp_dest_mem_param_t *) dst->param;
  974|  7.56k|    if (!param) {
  ------------------
  |  Branch (974:9): [True: 0, False: 7.56k]
  ------------------
  975|      0|        return RNP_ERROR_BAD_PARAMETERS;
  976|      0|    }
  977|       |
  978|       |    /* checking whether we need to realloc or discard extra bytes */
  979|  7.56k|    if (param->discard_overflow && (dst->writeb >= param->allocated)) {
  ------------------
  |  Branch (979:9): [True: 0, False: 7.56k]
  |  Branch (979:36): [True: 0, False: 0]
  ------------------
  980|      0|        return RNP_SUCCESS;
  981|      0|    }
  982|  7.56k|    if (param->discard_overflow && (dst->writeb + len > param->allocated)) {
  ------------------
  |  Branch (982:9): [True: 0, False: 7.56k]
  |  Branch (982:36): [True: 0, False: 0]
  ------------------
  983|      0|        len = param->allocated - dst->writeb;
  984|      0|    }
  985|       |
  986|  7.56k|    if (dst->writeb + len > param->allocated) {
  ------------------
  |  Branch (986:9): [True: 4.76k, False: 2.79k]
  ------------------
  987|  4.76k|        if ((param->maxalloc > 0) && (dst->writeb + len > param->maxalloc)) {
  ------------------
  |  Branch (987:13): [True: 0, False: 4.76k]
  |  Branch (987:38): [True: 0, False: 0]
  ------------------
  988|      0|            RNP_LOG("attempt to alloc more then allowed");
  ------------------
  |  |   76|      0|#define RNP_LOG(...) RNP_LOG_FD(stderr, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |   68|      0|    do {                                                                                 \
  |  |  |  |   69|      0|        if (!rnp_log_switch())                                                           \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (69:13): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |   70|      0|            break;                                                                       \
  |  |  |  |   71|      0|        (void) fprintf((fd), "[%s() %s:%d] ", __func__, __SOURCE_PATH_FILE__, __LINE__); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   65|      0|#define __SOURCE_PATH_FILE__ (&(__FILE__[SOURCE_PATH_SIZE + 3]))
  |  |  |  |  ------------------
  |  |  |  |   72|      0|        (void) fprintf((fd), __VA_ARGS__);                                               \
  |  |  |  |   73|      0|        (void) fprintf((fd), "\n");                                                      \
  |  |  |  |   74|      0|    } while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (74:14): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  989|      0|            return RNP_ERROR_OUT_OF_MEMORY;
  990|      0|        }
  991|       |
  992|       |        /* round up to the page boundary and do it exponentially */
  993|  4.76k|        size_t alloc = ((dst->writeb + len) * 2 + 4095) / 4096 * 4096;
  994|  4.76k|        if ((param->maxalloc > 0) && (alloc > param->maxalloc)) {
  ------------------
  |  Branch (994:13): [True: 0, False: 4.76k]
  |  Branch (994:38): [True: 0, False: 0]
  ------------------
  995|      0|            alloc = param->maxalloc;
  996|      0|        }
  997|       |
  998|  4.76k|        void *newalloc = param->secure ? calloc(1, alloc) : realloc(param->memory, alloc);
  ------------------
  |  Branch (998:26): [True: 0, False: 4.76k]
  ------------------
  999|  4.76k|        if (!newalloc) {
  ------------------
  |  Branch (999:13): [True: 0, False: 4.76k]
  ------------------
 1000|      0|            return RNP_ERROR_OUT_OF_MEMORY;
 1001|      0|        }
 1002|  4.76k|        if (param->secure && param->memory) {
  ------------------
  |  Branch (1002:13): [True: 0, False: 4.76k]
  |  Branch (1002:30): [True: 0, False: 0]
  ------------------
 1003|      0|            memcpy(newalloc, param->memory, dst->writeb);
 1004|      0|            secure_clear(param->memory, dst->writeb);
 1005|      0|            free(param->memory);
 1006|      0|        }
 1007|  4.76k|        param->memory = newalloc;
 1008|  4.76k|        param->allocated = alloc;
 1009|  4.76k|    }
 1010|       |
 1011|  7.56k|    memcpy((uint8_t *) param->memory + dst->writeb, buf, len);
 1012|  7.56k|    return RNP_SUCCESS;
 1013|  7.56k|}
stream-common.cpp:_ZL13mem_dst_closeP10pgp_dest_tb:
 1017|  4.17k|{
 1018|  4.17k|    pgp_dest_mem_param_t *param = (pgp_dest_mem_param_t *) dst->param;
 1019|  4.17k|    if (!param) {
  ------------------
  |  Branch (1019:9): [True: 0, False: 4.17k]
  ------------------
 1020|      0|        return;
 1021|      0|    }
 1022|       |
 1023|  4.17k|    if (param->free) {
  ------------------
  |  Branch (1023:9): [True: 0, False: 4.17k]
  ------------------
 1024|      0|        if (param->secure) {
  ------------------
  |  Branch (1024:13): [True: 0, False: 0]
  ------------------
 1025|      0|            secure_clear(param->memory, param->allocated);
 1026|      0|        }
 1027|      0|        free(param->memory);
 1028|      0|    }
 1029|  4.17k|    free(param);
 1030|       |    dst->param = NULL;
 1031|  4.17k|}

_ZN3rnp6SourceC2Ev:
  399|  4.17k|    Source() : src_({})
  400|  4.17k|    {
  401|  4.17k|    }
_ZN3rnp6SourceD2Ev:
  404|  4.17k|    {
  405|  4.17k|        src_.close();
  406|  4.17k|    }
_ZN3rnp6Source3srcEv:
  410|  4.32k|    {
  411|  4.32k|        return src_;
  412|  4.32k|    }
_ZN3rnp6Source4sizeEv:
  416|  4.32k|    {
  417|  4.32k|        return src().size;
  418|  4.32k|    }
_ZN3rnp12MemorySourceC2ER12pgp_source_t:
  468|  4.17k|    MemorySource(pgp_source_t &src) : Source()
  469|  4.17k|    {
  470|  4.17k|        auto res = read_mem_src(&src_, &src);
  471|  4.17k|        if (res) {
  ------------------
  |  Branch (471:13): [True: 0, False: 4.17k]
  ------------------
  472|      0|            throw rnp::rnp_exception(res);
  473|      0|        }
  474|  4.17k|    }
_ZN3rnp12MemorySource6memoryEb:
  478|  4.32k|    {
  479|  4.32k|        return mem_src_get_memory(&src_, own);
  480|  4.32k|    }

_ZN13pgp_key_pkt_taSEOS_:
  744|  1.06k|{
  745|  1.06k|    if (this == &src) {
  ------------------
  |  Branch (745:9): [True: 0, False: 1.06k]
  ------------------
  746|      0|        return *this;
  747|      0|    }
  748|  1.06k|    tag = src.tag;
  749|  1.06k|    version = src.version;
  750|  1.06k|    creation_time = src.creation_time;
  751|  1.06k|    alg = src.alg;
  752|  1.06k|    v3_days = src.v3_days;
  753|  1.06k|    pub_data = std::move(src.pub_data);
  754|  1.06k|    material = std::move(src.material);
  755|  1.06k|    secure_clear(sec_data.data(), sec_data.size());
  756|  1.06k|    sec_data = std::move(src.sec_data);
  757|  1.06k|    sec_protection = src.sec_protection;
  758|  1.06k|    return *this;
  759|  1.06k|}
_ZN13pgp_key_pkt_taSERKS_:
  763|    304|{
  764|    304|    if (this == &src) {
  ------------------
  |  Branch (764:9): [True: 0, False: 304]
  ------------------
  765|      0|        return *this;
  766|      0|    }
  767|    304|    tag = src.tag;
  768|    304|    version = src.version;
  769|    304|    creation_time = src.creation_time;
  770|    304|    alg = src.alg;
  771|    304|    v3_days = src.v3_days;
  772|    304|    pub_data = src.pub_data;
  773|    304|    material = src.material ? src.material->clone() : nullptr;
  ------------------
  |  Branch (773:16): [True: 304, False: 0]
  ------------------
  774|    304|    secure_clear(sec_data.data(), sec_data.size());
  775|    304|    sec_data = std::move(src.sec_data);
  776|    304|    sec_protection = src.sec_protection;
  777|    304|    return *this;
  778|    304|}
_ZN13pgp_key_pkt_tD2Ev:
  781|  5.54k|{
  782|  5.54k|    secure_clear(sec_data.data(), sec_data.size());
  783|  5.54k|}

_ZN13pgp_key_pkt_tC2Ev:
   59|  5.54k|        : tag(PGP_PKT_RESERVED), version(PGP_VUNKNOWN), creation_time(0), alg(PGP_PKA_NOTHING),
   60|  5.54k|          v3_days(0), v5_pub_len(0), material(nullptr), sec_protection({}), v5_s2k_len(0),
   61|  5.54k|          v5_sec_len(0){};

_Z13is_subkey_pkti:
  409|    760|{
  410|    760|    return (tag == PGP_PKT_PUBLIC_SUBKEY) || (tag == PGP_PKT_SECRET_SUBKEY);
  ------------------
  |  Branch (410:12): [True: 0, False: 760]
  |  Branch (410:46): [True: 0, False: 760]
  ------------------
  411|    760|}
_Z18is_primary_key_pkti:
  415|    152|{
  416|    152|    return (tag == PGP_PKT_PUBLIC_KEY) || (tag == PGP_PKT_SECRET_KEY);
  ------------------
  |  Branch (416:12): [True: 0, False: 152]
  |  Branch (416:43): [True: 0, False: 152]
  ------------------
  417|    152|}

_ZN14ext_key_format22ext_key_input_stream_tC2EPNSt3__113basic_istreamIcNS1_11char_traitsIcEEEEm:
   89|  4.17k|        : sexp_input_stream_t(i, md), is_scanning_value(false), has_key(false)
   90|  4.17k|    {
   91|  4.17k|    }
_ZNK14ext_key_format22extended_private_key_t7ci_lessclERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_:
   44|   221k|        {
   45|   221k|            return std::lexicographical_compare(
   46|   221k|              s1.begin(), s1.end(), s2.begin(), s2.end(), [](char a, char b) {
   47|   221k|                  return std::tolower(a) < std::tolower(b);
   48|   221k|              });
   49|   221k|        }
_ZN14ext_key_format22extended_private_key_t7iequalsERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_:
   54|  23.4k|    {
   55|  23.4k|        size_t sz = a.size();
   56|  23.4k|        if (b.size() != sz)
  ------------------
  |  Branch (56:13): [True: 21.0k, False: 2.35k]
  ------------------
   57|  21.0k|            return false;
   58|  3.43k|        for (size_t i = 0; i < sz; ++i)
  ------------------
  |  Branch (58:28): [True: 3.36k, False: 63]
  ------------------
   59|  3.36k|            if (tolower(a[i]) != tolower(b[i]))
  ------------------
  |  Branch (59:17): [True: 2.29k, False: 1.07k]
  ------------------
   60|  2.29k|                return false;
   61|     63|        return true;
   62|  2.35k|    }
_ZN14ext_key_format22ext_key_input_stream_t15is_newline_charEi:
   76|  26.8M|    static bool is_newline_char(int c) { return c == '\r' || c == '\n'; };
  ------------------
  |  Branch (76:49): [True: 3.79k, False: 26.8M]
  |  Branch (76:62): [True: 48.2k, False: 26.8M]
  ------------------
_ZN14ext_key_format22ext_key_input_stream_t11is_namecharEi:
   77|  4.95M|    static bool is_namechar(int c) { return ((c >= 0 && c <= 255) && namechar[c]); }
  ------------------
  |  Branch (77:47): [True: 4.95M, False: 0]
  |  Branch (77:57): [True: 4.95M, False: 0]
  |  Branch (77:70): [True: 4.95M, False: 38]
  ------------------
_ZZNK14ext_key_format22extended_private_key_t7ci_lessclERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESA_ENKUlccE_clEcc:
   46|  2.46M|              s1.begin(), s1.end(), s2.begin(), s2.end(), [](char a, char b) {
   47|  2.46M|                  return std::tolower(a) < std::tolower(b);
   48|  2.46M|              });

_ZN4sexp16sexp_exception_tC2ENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEENS0_8severityEiPKc:
   53|  2.84k|        : position{error_position}, level{error_level},
   54|  2.84k|          message{format(prefix, std::move(error_message), error_level, error_position)} {};
_ZN4sexp16sexp_exception_t11shall_throwENS0_8severityE:
   61|  10.4k|    static bool shall_throw(severity level) { return level == error || verbosity != error; };
  ------------------
  |  Branch (61:54): [True: 2.84k, False: 7.61k]
  |  Branch (61:72): [True: 0, False: 7.61k]
  ------------------
_ZN4sexp16sexp_exception_t14is_interactiveEv:
   66|  7.61k|    static bool         is_interactive(void) { return interactive; };

_ZN4sexp20sexp_simple_string_tC2Ev:
  192|  5.87M|    sexp_simple_string_t(void) = default;
_ZN4sexp20sexp_simple_string_t6appendEi:
  196|  84.5M|    {
  197|  84.5M|        (*this) += (octet_t)(c & 0xFF);
  198|  84.5M|        return *this;
  199|  84.5M|    }
_ZNSt3__111char_traitsIhE4copyEPhPKhm:
   98|  30.3k|    {
   99|  30.3k|        return static_cast<char_type *>(memcpy(__s1, __s2, __n));
  100|  30.3k|    }
_ZNSt3__111char_traitsIhE6assignERhRKh:
   65|   169M|    static void assign(char_type &__c1, const char_type &__c2) noexcept { __c1 = __c2; }
_ZN4sexp13sexp_string_t10set_stringERKNS_20sexp_simple_string_tE:
  314|  1.95M|    {
  315|  1.95M|        return data_string = ss;
  316|  1.95M|    }
_ZN4sexp13sexp_object_tD2Ev:
  253|  3.74M|    virtual ~sexp_object_t(){};
_ZNK4sexp13sexp_string_t10get_stringEv:
  312|  5.70k|    const sexp_simple_string_t &get_string(void) const noexcept { return data_string; }
_ZNK4sexp20sexp_simple_string_teqEPKc:
  221|  10.2k|    {
  222|  10.2k|        return length() == std::strlen(right) && std::memcmp(data(), right, length()) == 0;
  ------------------
  |  Branch (222:16): [True: 7.14k, False: 3.06k]
  |  Branch (222:50): [True: 4.08k, False: 3.05k]
  ------------------
  223|  10.2k|    }
_ZN4sexpeqEPKNS_13sexp_string_tERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
  342|  8.09k|{
  343|  8.09k|    return *left == right.c_str();
  344|  8.09k|}
_ZNK4sexp20sexp_simple_string_tneEPKc:
  226|    150|    {
  227|    150|        return length() != std::strlen(right) || std::memcmp(data(), right, length()) != 0;
  ------------------
  |  Branch (227:16): [True: 38, False: 112]
  |  Branch (227:50): [True: 2, False: 110]
  ------------------
  228|    150|    }
_ZNK4sexp11sexp_list_t12sexp_list_atEm:
  368|  1.44k|    {
  369|  1.44k|        return pos < size() ? (*at(pos)).sexp_list_view() : nullptr;
  ------------------
  |  Branch (369:16): [True: 1.44k, False: 0]
  ------------------
  370|  1.44k|    }
_ZN4sexp11sexp_list_tD2Ev:
  358|  1.78M|    virtual ~sexp_list_t() {}
_ZN4sexp11sexp_list_t14sexp_list_viewEv:
  364|  21.4k|    virtual sexp_list_t *sexp_list_view(void) noexcept { return this; }
_ZN4sexp13sexp_object_t16sexp_string_viewEv:
  260|    302|    virtual sexp_string_t *sexp_string_view(void) noexcept { return nullptr; }
_ZNK4sexp11sexp_list_t12is_sexp_listEv:
  365|  1.29k|    virtual bool         is_sexp_list(void) const noexcept { return true; }
_ZNK4sexp13sexp_object_t14is_sexp_stringEv:
  262|    795|    virtual bool           is_sexp_string(void) const noexcept { return false; }
_ZNK4sexp11sexp_list_t14sexp_string_atEm:
  372|  14.1k|    {
  373|  14.1k|        return pos < size() ? (*at(pos)).sexp_string_view() : nullptr;
  ------------------
  |  Branch (373:16): [True: 14.1k, False: 0]
  ------------------
  374|  14.1k|    }
_ZN4sexp13sexp_string_tC2Ev:
  308|  1.95M|    sexp_string_t(void) : with_presentation_hint(false) {}
_ZN4sexp16sexp_char_defs_t14is_white_spaceEi:
  148|  17.7M|    {
  149|  17.7M|        return c >= 0 && c <= 255 && std::isspace((char) c, c_locale);
  ------------------
  |  Branch (149:16): [True: 17.6M, False: 1.77k]
  |  Branch (149:26): [True: 17.6M, False: 0]
  |  Branch (149:38): [True: 4.74k, False: 17.6M]
  ------------------
  150|  17.7M|    };
_ZN4sexp16sexp_char_defs_t12is_dec_digitEi:
  152|  2.88M|    {
  153|  2.88M|        return c >= 0 && c <= 255 && std::isdigit((char) c, c_locale);
  ------------------
  |  Branch (153:16): [True: 2.88M, False: 502]
  |  Branch (153:26): [True: 2.88M, False: 0]
  |  Branch (153:38): [True: 922k, False: 1.95M]
  ------------------
  154|  2.88M|    };
_ZN4sexp16sexp_char_defs_t12is_hex_digitEi:
  156|  2.72M|    {
  157|  2.72M|        return c >= 0 && c <= 255 && std::isxdigit((char) c, c_locale);
  ------------------
  |  Branch (157:16): [True: 2.72M, False: 11]
  |  Branch (157:26): [True: 2.72M, False: 0]
  |  Branch (157:38): [True: 2.72M, False: 71]
  ------------------
  158|  2.72M|    };
_ZN4sexp16sexp_char_defs_t15is_base64_digitEi:
  159|  1.76k|    static bool is_base64_digit(int c) { return c >= 0 && c <= 255 && base64digit[c]; };
  ------------------
  |  Branch (159:49): [True: 1.76k, False: 0]
  |  Branch (159:59): [True: 1.76k, False: 0]
  |  Branch (159:71): [True: 1.73k, False: 25]
  ------------------
_ZN4sexp16sexp_char_defs_t13is_token_charEi:
  160|  11.7M|    static bool is_token_char(int c) { return c >= 0 && c <= 255 && tokenchar[c]; };
  ------------------
  |  Branch (160:47): [True: 11.7M, False: 631]
  |  Branch (160:57): [True: 11.7M, False: 0]
  |  Branch (160:69): [True: 10.0M, False: 1.73M]
  ------------------
_ZN4sexp16sexp_char_defs_t8is_alphaEi:
  162|  23.5k|    {
  163|  23.5k|        return c >= 0 && c <= 255 && std::isalpha((char) c, c_locale);
  ------------------
  |  Branch (163:16): [True: 23.5k, False: 0]
  |  Branch (163:26): [True: 23.5k, False: 0]
  |  Branch (163:38): [True: 23.4k, False: 39]
  ------------------
  164|  23.5k|    };
_ZN4sexp16sexp_char_defs_t8decvalueEi:
  167|   482k|    static unsigned char decvalue(int c) { return (c >= 0 && c <= 255) ? values[c][0] : 0; };
  ------------------
  |  Branch (167:52): [True: 482k, False: 0]
  |  Branch (167:62): [True: 482k, False: 0]
  ------------------
_ZN4sexp16sexp_char_defs_t8hexvalueEi:
  169|  2.72M|    static unsigned char hexvalue(int c) { return (c >= 0 && c <= 255) ? values[c][1] : 0; };
  ------------------
  |  Branch (169:52): [True: 2.72M, False: 0]
  |  Branch (169:62): [True: 2.72M, False: 0]
  ------------------
_ZN4sexp16sexp_char_defs_t11base64valueEi:
  172|  1.73k|    {
  173|  1.73k|        return (c >= 0 && c <= 255) ? values[c][2] : 0;
  ------------------
  |  Branch (173:17): [True: 1.73k, False: 0]
  |  Branch (173:27): [True: 1.73k, False: 0]
  ------------------
  174|  1.73k|    };
_ZNK4sexp20sexp_simple_string_t11as_unsignedEv:
  231|     87|    {
  232|     87|        return empty() ? std::numeric_limits<uint32_t>::max() :
  ------------------
  |  Branch (232:16): [True: 1, False: 86]
  ------------------
  233|     87|                         (unsigned) atoi(reinterpret_cast<const char *>(c_str()));
  234|     87|    }
_ZN4sexp13sexp_object_t14sexp_list_viewEv:
  259|  11.5k|    virtual sexp_list_t *  sexp_list_view(void) noexcept { return nullptr; }
_ZNK4sexp13sexp_object_t12is_sexp_listEv:
  261|      3|    virtual bool           is_sexp_list(void) const noexcept { return false; }
_ZN4sexp13sexp_string_t21set_presentation_hintERKNS_20sexp_simple_string_tE:
  322|    721|    {
  323|    721|        with_presentation_hint = true;
  324|    721|        return presentation_hint = ph;
  325|    721|    }
_ZN4sexp13sexp_string_t16sexp_string_viewEv:
  331|  13.8k|    virtual sexp_string_t *sexp_string_view(void) noexcept { return this; }
_ZNK4sexp13sexp_string_t14is_sexp_stringEv:
  332|  6.59k|    virtual bool           is_sexp_string(void) const noexcept { return true; }
_ZNK4sexp13sexp_string_teqEPKc:
  334|  8.09k|    virtual bool operator==(const char *right) const noexcept { return data_string == right; }
_ZNK4sexp13sexp_string_t11as_unsignedEv:
  338|     87|    virtual unsigned as_unsigned() const noexcept { return data_string.as_unsigned(); }
_ZN4sexp19sexp_input_stream_t13get_byte_sizeEv:
  426|  6.59k|    uint32_t                       get_byte_size(void) { return byte_size; }
_ZNK4sexp19sexp_input_stream_t13get_next_charEv:
  442|  9.25M|    int get_next_char(void) const { return next_char; }
_ZN4sexp19sexp_input_stream_t13set_next_charEi:
  443|  3.51k|    int set_next_char(int c) { return next_char = c; }

_ZN14ext_key_format13ext_key_errorEN4sexp16sexp_exception_t8severityEPKcmmi:
   32|    671|{
   33|    671|    char                       tmp[256];
   34|    671|    sexp_exception_t::severity l = (sexp_exception_t::severity) level;
   35|    671|    snprintf(tmp, sizeof(tmp) / sizeof(tmp[0]), msg, c1, c2);
   36|    671|    if (sexp_exception_t::shall_throw(l))
  ------------------
  |  Branch (36:9): [True: 671, False: 0]
  ------------------
   37|    671|        throw sexp_exception_t(tmp, l, pos, "EXTENDED KEY FORMAT");
   38|      0|    if (sexp_exception_t::is_interactive()) {
  ------------------
  |  Branch (38:9): [True: 0, False: 0]
  ------------------
   39|      0|        std::cout.flush() << std::endl
   40|      0|                          << "*** "
   41|      0|                          << sexp_exception_t::format("EXTENDED KEY FORMAT", tmp, l, pos)
   42|      0|                          << " ***" << std::endl;
   43|      0|    }
   44|      0|}
_ZN14ext_key_format22ext_key_input_stream_t9skip_lineEv:
  139|    395|{
  140|    395|    int c;
  141|  47.0k|    do {
  142|  47.0k|        c = input_file->get();
  143|  47.0k|    } while (!is_newline_char(c) && c != EOF);
  ------------------
  |  Branch (143:14): [True: 46.6k, False: 371]
  |  Branch (143:37): [True: 46.6k, False: 24]
  ------------------
  144|    395|    return c;
  145|    395|}
_ZN14ext_key_format22ext_key_input_stream_t9read_charEv:
  151|   104M|{
  152|   104M|    int lookahead_1 = input_file->get();
  153|   104M|    count++;
  154|   104M|    if (is_scanning_value && is_newline_char(lookahead_1)) {
  ------------------
  |  Branch (154:9): [True: 12.7M, False: 91.7M]
  |  Branch (154:30): [True: 28.3k, False: 12.6M]
  ------------------
  155|  29.2k|        while (true) {
  ------------------
  |  Branch (155:16): [True: 29.2k, Folded]
  ------------------
  156|  29.2k|            int lookahead_2 = input_file->peek();
  157|  29.2k|            if (lookahead_1 == '\r' && lookahead_2 == '\n') {
  ------------------
  |  Branch (157:17): [True: 3.04k, False: 26.1k]
  |  Branch (157:40): [True: 1.05k, False: 1.98k]
  ------------------
  158|  1.05k|                lookahead_1 = input_file->get();
  159|  1.05k|                count++;
  160|  1.05k|                lookahead_2 = input_file->peek();
  161|  1.05k|            }
  162|  29.2k|            if (lookahead_2 == ' ') {
  ------------------
  |  Branch (162:17): [True: 1.29k, False: 27.9k]
  ------------------
  163|  1.29k|                input_file->get();
  164|  1.29k|                count++;
  165|  1.29k|                lookahead_2 = input_file->peek();
  166|  1.29k|                if (lookahead_2 == '#') {
  ------------------
  |  Branch (166:21): [True: 395, False: 901]
  ------------------
  167|    395|                    lookahead_1 = skip_line();
  168|    395|                    continue;
  169|    395|                }
  170|    901|                if (is_newline_char(lookahead_2)) {
  ------------------
  |  Branch (170:21): [True: 490, False: 411]
  ------------------
  171|    490|                    lookahead_1 = lookahead_2;
  172|    490|                    continue;
  173|    490|                }
  174|    411|                lookahead_1 = input_file->get();
  175|    411|                count++;
  176|    411|            }
  177|  28.3k|            return lookahead_1;
  178|  29.2k|        }
  179|  28.3k|    }
  180|   104M|    return lookahead_1;
  181|   104M|}
_ZN14ext_key_format22ext_key_input_stream_t9scan_nameEi:
  192|  23.5k|{
  193|  23.5k|    std::string name;
  194|  23.5k|    if (!is_alpha(c)) {
  ------------------
  |  Branch (194:9): [True: 39, False: 23.4k]
  ------------------
  195|     39|        ext_key_error(sexp_exception_t::error,
  196|     39|                      isprint(next_char) ?
  ------------------
  |  Branch (196:23): [True: 38, False: 1]
  ------------------
  197|     38|                        "unexpected character '%c' (0x%x) found starting a name field" :
  198|     39|                        "unexpected character '0x%x' found starting a name field",
  199|     39|                      c,
  200|     39|                      c,
  201|     39|                      count);
  202|  23.4k|    } else {
  203|  23.4k|        name += (char) c;
  204|  23.4k|        c = read_char();
  205|  4.97M|        while (c != ':') {
  ------------------
  |  Branch (205:16): [True: 4.95M, False: 23.4k]
  ------------------
  206|  4.95M|            if (c == EOF) {
  ------------------
  |  Branch (206:17): [True: 39, False: 4.95M]
  ------------------
  207|     39|                ext_key_error(sexp_exception_t::error, "unexpected end of file", 0, 0, count);
  208|     39|            }
  209|  4.95M|            if (is_newline_char(c)) {
  ------------------
  |  Branch (209:17): [True: 3, False: 4.95M]
  ------------------
  210|      3|                ext_key_error(sexp_exception_t::error, "unexpected end of line", 0, 0, count);
  211|      3|            }
  212|  4.95M|            if (!is_namechar(c)) {
  ------------------
  |  Branch (212:17): [True: 38, False: 4.95M]
  ------------------
  213|     38|                ext_key_error(sexp_exception_t::error,
  214|     38|                              isprint(next_char) ?
  ------------------
  |  Branch (214:31): [True: 37, False: 1]
  ------------------
  215|     37|                                "unexpected character '%c' (0x%x) found in a name field" :
  216|     38|                                "unexpected character '0x%x' found in a name field",
  217|     38|                              c,
  218|     38|                              c,
  219|     38|                              count);
  220|     38|            }
  221|  4.95M|            name += (int) c;
  222|  4.95M|            c = read_char();
  223|  4.95M|        }
  224|  23.4k|    }
  225|  23.5k|    return name;
  226|  23.5k|}
_ZN14ext_key_format22ext_key_input_stream_t10scan_valueEv:
  236|  23.3k|{
  237|  23.3k|    std::string value;
  238|  23.3k|    int         c;
  239|  25.6k|    do {
  240|  25.6k|        c = read_char();
  241|  25.6k|    } while (is_white_space(c));
  ------------------
  |  Branch (241:14): [True: 2.30k, False: 23.3k]
  ------------------
  242|  9.16M|    while (c != EOF && !is_newline_char(c)) {
  ------------------
  |  Branch (242:12): [True: 9.16M, False: 531]
  |  Branch (242:24): [True: 9.14M, False: 22.8k]
  ------------------
  243|  9.14M|        value += c;
  244|  9.14M|        c = read_char();
  245|  9.14M|    }
  246|  23.3k|    return value;
  247|  23.3k|}
_ZN14ext_key_format22ext_key_input_stream_t4scanERNS_22extended_private_key_tE:
  256|  4.17k|{
  257|  4.17k|    set_byte_size(8);
  258|  4.17k|    int c = read_char();
  259|  4.17k|    if (c == '(') {
  ------------------
  |  Branch (259:9): [True: 3.44k, False: 729]
  ------------------
  260|  3.44k|        set_next_char(c);
  261|  3.44k|        res.key.parse(this);
  262|  3.44k|        has_key = true;
  263|  3.44k|    } else {
  264|  24.2k|        while (c != EOF) {
  ------------------
  |  Branch (264:16): [True: 23.5k, False: 729]
  ------------------
  265|       |            // Comparison of names is done case insensitively
  266|  23.5k|            std::string name = scan_name(c);
  267|       |            // The name “Key” is special in that it is mandatory and must occur only once.
  268|       |            // The associated value holds the actual S-expression with the cryptographic key.
  269|       |            // The S-expression is formatted using the ‘Advanced Format’
  270|       |            // (GCRYSEXP_FMT_ADVANCED) that avoids non-printable characters so that the file
  271|       |            // can be easily inspected and edited.
  272|  23.5k|            is_scanning_value = true;
  273|  23.5k|            if (extended_private_key_t::iequals(name, "key")) {
  ------------------
  |  Branch (273:17): [True: 63, False: 23.4k]
  ------------------
  274|     63|                if (has_key) {
  ------------------
  |  Branch (274:21): [True: 1, False: 62]
  ------------------
  275|      1|                    ext_key_error(sexp_exception_t::error,
  276|      1|                                  "'key' field must occur only once",
  277|      1|                                  0,
  278|      1|                                  0,
  279|      1|                                  count);
  280|      1|                }
  281|    278|                do {
  282|    278|                    c = read_char();
  283|    278|                } while (is_white_space(c));
  ------------------
  |  Branch (283:26): [True: 215, False: 63]
  ------------------
  284|     63|                set_next_char(c);
  285|     63|                res.key.parse(this);
  286|     63|                has_key = true;
  287|  23.4k|            } else {
  288|  23.4k|                std::string value = scan_value();
  289|  23.4k|                res.fields.insert(std::pair<std::string, std::string>{name, value});
  290|  23.4k|            }
  291|  23.5k|            c = read_char();
  292|  23.5k|            is_scanning_value = false;
  293|  23.5k|        }
  294|    729|    }
  295|  4.17k|    if (!has_key) {
  ------------------
  |  Branch (295:9): [True: 551, False: 3.62k]
  ------------------
  296|    551|        ext_key_error(sexp_exception_t::error, "missing mandatory 'key' field", 0, 0, count);
  297|    551|    }
  298|  4.17k|}

_ZN4sexp18sexp_depth_managerC2Em:
   29|  4.17k|{
   30|  4.17k|    reset_depth(m_depth);
   31|  4.17k|}
_ZN4sexp18sexp_depth_manager11reset_depthEm:
   33|  8.35k|{
   34|  8.35k|    depth = 0;
   35|  8.35k|    max_depth = m_depth;
   36|  8.35k|}
_ZN4sexp18sexp_depth_manager14increase_depthEi:
   38|  1.78M|{
   39|  1.78M|    if (max_depth != 0 && ++depth > max_depth)
  ------------------
  |  Branch (39:9): [True: 1.78M, False: 0]
  |  Branch (39:27): [True: 10, False: 1.78M]
  ------------------
   40|     10|        sexp_error(sexp_exception_t::error,
   41|     10|                   "Maximum allowed SEXP list depth (%u) is exceeded",
   42|     10|                   max_depth,
   43|     10|                   0,
   44|     10|                   count);
   45|  1.78M|}
_ZN4sexp18sexp_depth_manager14decrease_depthEv:
   47|  1.78M|{
   48|  1.78M|    depth--;
   49|  1.78M|}

_ZN4sexp16sexp_exception_t6formatENSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES7_NS0_8severityEi:
   35|  2.84k|{
   36|  2.84k|    std::string r = prf + (level == error ? " ERROR: " : " WARNING: ") + message;
  ------------------
  |  Branch (36:28): [True: 2.84k, False: 0]
  ------------------
   37|  2.84k|    if (position >= 0)
  ------------------
  |  Branch (37:9): [True: 2.84k, False: 0]
  ------------------
   38|  2.84k|        r += " at position " + std::to_string(position);
   39|  2.84k|    return r;
   40|  2.84k|};
_ZN4sexp10sexp_errorENS_16sexp_exception_t8severityEPKcmmi:
   44|  9.78k|{
   45|  9.78k|    char                       tmp[256];
   46|  9.78k|    sexp_exception_t::severity l = (sexp_exception_t::severity) level;
   47|  9.78k|    snprintf(tmp, sizeof(tmp) / sizeof(tmp[0]), msg, c1, c2);
   48|  9.78k|    if (sexp_exception_t::shall_throw(l))
  ------------------
  |  Branch (48:9): [True: 2.16k, False: 7.61k]
  ------------------
   49|  2.16k|        throw sexp_exception_t(tmp, l, pos);
   50|  7.61k|    if (sexp_exception_t::is_interactive()) {
  ------------------
  |  Branch (50:9): [True: 0, False: 7.61k]
  ------------------
   51|      0|        std::cout.flush() << std::endl
   52|      0|                          << "*** " << sexp_exception_t::format("SEXP", tmp, l, pos) << " ***"
   53|      0|                          << std::endl;
   54|      0|    }
   55|  7.61k|}

_ZN4sexp19sexp_input_stream_tC2EPNSt3__113basic_istreamIcNS1_11char_traitsIcEEEEm:
   39|  4.17k|{
   40|  4.17k|    set_input(i, m_depth);
   41|  4.17k|}
_ZN4sexp19sexp_input_stream_t9set_inputEPNSt3__113basic_istreamIcNS1_11char_traitsIcEEEEm:
   48|  4.17k|{
   49|  4.17k|    input_file = i;
   50|  4.17k|    byte_size = 8;
   51|  4.17k|    next_char = ' ';
   52|  4.17k|    bits = 0;
   53|  4.17k|    n_bits = 0;
   54|  4.17k|    count = -1;
   55|  4.17k|    reset_depth(m_depth);
   56|  4.17k|    return this;
   57|  4.17k|}
_ZN4sexp19sexp_input_stream_t13set_byte_sizeEj:
   63|  17.3k|{
   64|  17.3k|    byte_size = newByteSize;
   65|  17.3k|    n_bits = 0;
   66|  17.3k|    bits = 0;
   67|  17.3k|    return this;
   68|  17.3k|}
_ZN4sexp19sexp_input_stream_t8get_charEv:
   86|  88.8M|{
   87|  88.8M|    int c;
   88|  88.8M|    if (next_char == EOF) {
  ------------------
  |  Branch (88:9): [True: 0, False: 88.8M]
  ------------------
   89|      0|        byte_size = 8;
   90|      0|        return this;
   91|      0|    }
   92|       |
   93|  90.2M|    while (true) {
  ------------------
  |  Branch (93:12): [True: 90.2M, Folded]
  ------------------
   94|  90.2M|        c = next_char = read_char();
   95|  90.2M|        if (c == EOF)
  ------------------
  |  Branch (95:13): [True: 2.99k, False: 90.2M]
  ------------------
   96|  2.99k|            return this;
   97|  90.2M|        if ((byte_size == 6 && (c == '|' || c == '}')) || (byte_size == 4 && (c == '#'))) {
  ------------------
  |  Branch (97:14): [True: 5.92k, False: 90.2M]
  |  Branch (97:33): [True: 3.07k, False: 2.85k]
  |  Branch (97:45): [True: 803, False: 2.05k]
  |  Branch (97:60): [True: 2.72M, False: 87.5M]
  |  Branch (97:78): [True: 2.59k, False: 2.72M]
  ------------------
   98|       |            // end of region reached; return terminating character, after checking for
   99|       |            // unused bits
  100|  6.47k|            if (n_bits > 0 && (((1 << n_bits) - 1) & bits) != 0) {
  ------------------
  |  Branch (100:17): [True: 646, False: 5.82k]
  |  Branch (100:31): [True: 442, False: 204]
  ------------------
  101|    442|                sexp_error(sexp_exception_t::warning,
  102|    442|                           "%d-bit region ended with %d unused bits left-over",
  103|    442|                           byte_size,
  104|    442|                           n_bits,
  105|    442|                           count);
  106|    442|            }
  107|  6.47k|            return set_byte_size(8);
  108|  90.2M|        } else if (byte_size != 8 && is_white_space(c))
  ------------------
  |  Branch (108:20): [True: 2.72M, False: 87.5M]
  |  Branch (108:38): [True: 265, False: 2.72M]
  ------------------
  109|    265|            ; /* ignore white space in hex and base64 regions */
  110|  90.2M|        else if (byte_size == 6 && c == '=')
  ------------------
  |  Branch (110:18): [True: 1.97k, False: 90.2M]
  |  Branch (110:36): [True: 210, False: 1.76k]
  ------------------
  111|    210|            ; /* ignore equals signs in base64 regions */
  112|  90.2M|        else if (byte_size == 8) {
  ------------------
  |  Branch (112:18): [True: 87.5M, False: 2.72M]
  ------------------
  113|  87.5M|            return this;
  114|  87.5M|        } else if (byte_size < 8) {
  ------------------
  |  Branch (114:20): [True: 2.72M, False: 0]
  ------------------
  115|  2.72M|            bits = bits << byte_size;
  116|  2.72M|            n_bits += byte_size;
  117|  2.72M|            if (byte_size == 6 && is_base64_digit(c))
  ------------------
  |  Branch (117:17): [True: 1.76k, False: 2.72M]
  |  Branch (117:35): [True: 1.73k, False: 25]
  ------------------
  118|  1.73k|                bits = bits | base64value(c);
  119|  2.72M|            else if (byte_size == 4 && is_hex_digit(c))
  ------------------
  |  Branch (119:22): [True: 2.72M, False: 25]
  |  Branch (119:40): [True: 2.72M, False: 36]
  ------------------
  120|  2.72M|                bits = bits | hexvalue(c);
  121|     61|            else {
  122|     61|                sexp_error(sexp_exception_t::error,
  123|     61|                           "character '%c' found in %u-bit coding region",
  124|     61|                           next_char,
  125|     61|                           byte_size,
  126|     61|                           count);
  127|     61|            }
  128|  2.72M|            if (n_bits >= 8) {
  ------------------
  |  Branch (128:17): [True: 1.36M, False: 1.36M]
  ------------------
  129|  1.36M|                next_char = (bits >> (n_bits - 8)) & 0xFF;
  130|  1.36M|                n_bits -= 8;
  131|  1.36M|                return this;
  132|  1.36M|            }
  133|  2.72M|        }
  134|  90.2M|    }
  135|  88.8M|}
_ZN4sexp19sexp_input_stream_t16skip_white_spaceEv:
  142|  14.9M|{
  143|  14.9M|    while (is_white_space(next_char))
  ------------------
  |  Branch (143:12): [True: 1.96k, False: 14.9M]
  ------------------
  144|  1.96k|        get_char();
  145|  14.9M|    return this;
  146|  14.9M|}
_ZN4sexp19sexp_input_stream_t9skip_charEi:
  154|  3.81M|{
  155|  3.81M|    if (next_char != c)
  ------------------
  |  Branch (155:9): [True: 317, False: 3.81M]
  ------------------
  156|    317|        sexp_error(sexp_exception_t::error,
  157|    317|                   "character '%c' found where '%c' was expected",
  158|    317|                   next_char,
  159|    317|                   c,
  160|    317|                   count);
  161|  3.81M|    return get_char();
  162|  3.81M|}
_ZN4sexp19sexp_input_stream_t10scan_tokenERNS_20sexp_simple_string_tE:
  169|  1.72M|{
  170|  1.72M|    skip_white_space();
  171|  9.80M|    while (is_token_char(next_char)) {
  ------------------
  |  Branch (171:12): [True: 8.07M, False: 1.72M]
  ------------------
  172|  8.07M|        ss.append(next_char);
  173|  8.07M|        get_char();
  174|  8.07M|    }
  175|  1.72M|}
_ZN4sexp19sexp_input_stream_t19scan_decimal_stringEv:
  200|   220k|{
  201|   220k|    uint32_t value = 0;
  202|   220k|    uint32_t i = 0;
  203|   702k|    while (is_dec_digit(next_char)) {
  ------------------
  |  Branch (203:12): [True: 482k, False: 220k]
  ------------------
  204|   482k|        value = value * 10 + decvalue(next_char);
  205|   482k|        get_char();
  206|   482k|        if (i++ > 8)
  ------------------
  |  Branch (206:13): [True: 3, False: 482k]
  ------------------
  207|      3|            sexp_error(sexp_exception_t::error, "Decimal number is too long", 0, 0, count);
  208|   482k|    }
  209|   220k|    return value;
  210|   220k|}
_ZN4sexp19sexp_input_stream_t20scan_verbatim_stringERNS_20sexp_simple_string_tEj:
  217|   217k|{
  218|   217k|    skip_white_space()->skip_char(':');
  219|       |
  220|       |    // Some length is specified always, this is ensured by the caller's logic
  221|   217k|    assert(length != std::numeric_limits<uint32_t>::max());
  222|       |    // We should not handle too large strings
  223|   217k|    if (length > 1024 * 1024) {
  ------------------
  |  Branch (223:9): [True: 9, False: 217k]
  ------------------
  224|      9|        sexp_error(sexp_exception_t::error, "Too long verbatim string: %zu", length, 0, count);
  225|      9|    }
  226|  2.28M|    for (uint32_t i = 0; i < length; i++) {
  ------------------
  |  Branch (226:26): [True: 2.06M, False: 217k]
  ------------------
  227|  2.06M|        if (next_char == EOF) {
  ------------------
  |  Branch (227:13): [True: 97, False: 2.06M]
  ------------------
  228|     97|            sexp_error(
  229|     97|              sexp_exception_t::error, "EOF while reading verbatim string", 0, 0, count);
  230|     97|        }
  231|  2.06M|        ss.append(next_char);
  232|  2.06M|        get_char();
  233|  2.06M|    }
  234|   217k|}
_ZN4sexp19sexp_input_stream_t18scan_quoted_stringERNS_20sexp_simple_string_tEj:
  243|  9.03k|{
  244|  9.03k|    skip_char('"');
  245|  61.0M|    while (ss.length() <= length) {
  ------------------
  |  Branch (245:12): [True: 60.9M, False: 1.15k]
  ------------------
  246|  60.9M|        if (next_char == '\"') {
  ------------------
  |  Branch (246:13): [True: 7.73k, False: 60.9M]
  ------------------
  247|  7.73k|            if (length == std::numeric_limits<uint32_t>::max() || (ss.length() == length)) {
  ------------------
  |  Branch (247:17): [True: 7.30k, False: 433]
  |  Branch (247:67): [True: 398, False: 35]
  ------------------
  248|  7.70k|                skip_char('\"');
  249|  7.70k|                return;
  250|  7.70k|            } else
  251|     35|                sexp_error(sexp_exception_t::error,
  252|     35|                           "Declared length was %d, but quoted string ended too early",
  253|     35|                           (int) length,
  254|     35|                           0,
  255|     35|                           count);
  256|  60.9M|        } else if (next_char == '\\') /* handle escape sequence */
  ------------------
  |  Branch (256:20): [True: 43.2k, False: 60.9M]
  ------------------
  257|  43.2k|        {
  258|  43.2k|            get_char();
  259|  43.2k|            switch (next_char) {
  260|  2.39k|            case 'b':
  ------------------
  |  Branch (260:13): [True: 2.39k, False: 40.8k]
  ------------------
  261|  2.39k|                ss.append('\b');
  262|  2.39k|                break;
  263|  2.88k|            case 't':
  ------------------
  |  Branch (263:13): [True: 2.88k, False: 40.3k]
  ------------------
  264|  2.88k|                ss.append('\t');
  265|  2.88k|                break;
  266|  2.61k|            case 'v':
  ------------------
  |  Branch (266:13): [True: 2.61k, False: 40.6k]
  ------------------
  267|  2.61k|                ss.append('\v');
  268|  2.61k|                break;
  269|  2.76k|            case 'n':
  ------------------
  |  Branch (269:13): [True: 2.76k, False: 40.4k]
  ------------------
  270|  2.76k|                ss.append('\n');
  271|  2.76k|                break;
  272|  2.49k|            case 'f':
  ------------------
  |  Branch (272:13): [True: 2.49k, False: 40.7k]
  ------------------
  273|  2.49k|                ss.append('\f');
  274|  2.49k|                break;
  275|  1.33k|            case 'r':
  ------------------
  |  Branch (275:13): [True: 1.33k, False: 41.9k]
  ------------------
  276|  1.33k|                ss.append('\r');
  277|  1.33k|                break;
  278|  1.98k|            case '\"':
  ------------------
  |  Branch (278:13): [True: 1.98k, False: 41.2k]
  ------------------
  279|  1.98k|                ss.append('\"');
  280|  1.98k|                break;
  281|  1.41k|            case '\'':
  ------------------
  |  Branch (281:13): [True: 1.41k, False: 41.8k]
  ------------------
  282|  1.41k|                ss.append('\'');
  283|  1.41k|                break;
  284|  6.86k|            case '\\':
  ------------------
  |  Branch (284:13): [True: 6.86k, False: 36.3k]
  ------------------
  285|  6.86k|                ss.append('\\');
  286|  6.86k|                break;
  287|  2.47k|            case 'x': /* hexadecimal number */
  ------------------
  |  Branch (287:13): [True: 2.47k, False: 40.7k]
  ------------------
  288|  2.47k|            {
  289|  2.47k|                int j, val;
  290|  2.47k|                val = 0;
  291|  2.47k|                get_char();
  292|  7.39k|                for (j = 0; j < 2; j++) {
  ------------------
  |  Branch (292:29): [True: 4.92k, False: 2.47k]
  ------------------
  293|  4.92k|                    if (is_hex_digit(next_char)) {
  ------------------
  |  Branch (293:25): [True: 4.87k, False: 46]
  ------------------
  294|  4.87k|                        val = ((val << 4) | hexvalue(next_char));
  295|  4.87k|                        if (j < 1) {
  ------------------
  |  Branch (295:29): [True: 2.45k, False: 2.42k]
  ------------------
  296|  2.45k|                            get_char();
  297|  2.45k|                        }
  298|  4.87k|                    } else
  299|     46|                        sexp_error(sexp_exception_t::error,
  300|     46|                                   "Hex character \x5cx%x... too short",
  301|     46|                                   val,
  302|     46|                                   0,
  303|     46|                                   count);
  304|  4.92k|                }
  305|  2.47k|                ss.append(val);
  306|  2.47k|            } break;
  307|    603|            case '\n':      /* ignore backslash line feed */
  ------------------
  |  Branch (307:13): [True: 603, False: 42.6k]
  ------------------
  308|    603|                get_char(); /* also ignore following carriage-return if present */
  309|    603|                if (next_char != '\r')
  ------------------
  |  Branch (309:21): [True: 349, False: 254]
  ------------------
  310|    349|                    continue;
  311|    254|                break;
  312|    586|            case '\r':      /* ignore backslash carriage-return */
  ------------------
  |  Branch (312:13): [True: 586, False: 42.6k]
  ------------------
  313|    586|                get_char(); /* also ignore following linefeed if present */
  314|    586|                if (next_char != '\n')
  ------------------
  |  Branch (314:21): [True: 366, False: 220]
  ------------------
  315|    366|                    continue;
  316|    220|                break;
  317|  1.83k|            case '0':
  ------------------
  |  Branch (317:13): [True: 1.83k, False: 41.4k]
  ------------------
  318|  13.2k|            case '1':
  ------------------
  |  Branch (318:13): [True: 11.4k, False: 31.8k]
  ------------------
  319|  14.4k|            case '2':
  ------------------
  |  Branch (319:13): [True: 1.24k, False: 42.0k]
  ------------------
  320|  14.8k|            case '3':
  ------------------
  |  Branch (320:13): [True: 311, False: 42.9k]
  ------------------
  321|  14.8k|            case '4':
  ------------------
  |  Branch (321:13): [True: 4, False: 43.2k]
  ------------------
  322|  14.8k|            case '5':
  ------------------
  |  Branch (322:13): [True: 1, False: 43.2k]
  ------------------
  323|  14.8k|            case '6':
  ------------------
  |  Branch (323:13): [True: 3, False: 43.2k]
  ------------------
  324|  14.8k|            case '7': { /* octal number */
  ------------------
  |  Branch (324:13): [True: 5, False: 43.2k]
  ------------------
  325|  14.8k|                int j, val;
  326|  14.8k|                val = 0;
  327|  59.1k|                for (j = 0; j < 3; j++) {
  ------------------
  |  Branch (327:29): [True: 44.3k, False: 14.8k]
  ------------------
  328|  44.3k|                    if (next_char >= '0' && next_char <= '7') {
  ------------------
  |  Branch (328:25): [True: 44.3k, False: 59]
  |  Branch (328:45): [True: 44.2k, False: 26]
  ------------------
  329|  44.2k|                        val = ((val << 3) | (next_char - '0'));
  330|  44.2k|                        if (j < 2)
  ------------------
  |  Branch (330:29): [True: 29.5k, False: 14.7k]
  ------------------
  331|  29.5k|                            get_char();
  332|  44.2k|                    } else
  333|     85|                        sexp_error(sexp_exception_t::error,
  334|     85|                                   "Octal character \\%o... too short",
  335|     85|                                   val,
  336|     85|                                   0,
  337|     85|                                   count);
  338|  44.3k|                }
  339|  14.8k|                if (val > 255)
  ------------------
  |  Branch (339:21): [True: 2, False: 14.8k]
  ------------------
  340|      2|                    sexp_error(sexp_exception_t::error,
  341|      2|                               "Octal character \\%o... too big",
  342|      2|                               val,
  343|      2|                               0,
  344|      2|                               count);
  345|  14.8k|                ss.append(val);
  346|  14.8k|            } break;
  347|     42|            default:
  ------------------
  |  Branch (347:13): [True: 42, False: 43.2k]
  ------------------
  348|     42|                sexp_error(sexp_exception_t::error,
  349|     42|                           "Unknown escape sequence \\%c",
  350|     42|                           next_char,
  351|     42|                           0,
  352|     42|                           count);
  353|  43.2k|            }
  354|  43.2k|        } /* end of handling escape sequence */
  355|  60.9M|        else if (next_char == EOF) {
  ------------------
  |  Branch (355:18): [True: 862, False: 60.9M]
  ------------------
  356|    862|            sexp_error(sexp_exception_t::error, "unexpected end of file", 0, 0, count);
  357|  60.9M|        } else {
  358|  60.9M|            ss.append(next_char);
  359|  60.9M|        }
  360|  60.9M|        get_char();
  361|  60.9M|    } /* end of main while loop */
  362|  9.03k|}
_ZN4sexp19sexp_input_stream_t23scan_hexadecimal_stringERNS_20sexp_simple_string_tEj:
  371|  2.71k|{
  372|  2.71k|    set_byte_size(4)->skip_char('#');
  373|  1.36M|    while (next_char != EOF && (next_char != '#' || get_byte_size() == 4)) {
  ------------------
  |  Branch (373:12): [True: 1.36M, False: 113]
  |  Branch (373:33): [True: 1.36M, False: 3.07k]
  |  Branch (373:53): [True: 476, False: 2.59k]
  ------------------
  374|  1.36M|        ss.append(next_char);
  375|  1.36M|        get_char();
  376|  1.36M|    }
  377|  2.71k|    skip_char('#');
  378|  2.71k|    if (ss.length() != length && length != std::numeric_limits<uint32_t>::max())
  ------------------
  |  Branch (378:9): [True: 2.40k, False: 309]
  |  Branch (378:34): [True: 448, False: 1.95k]
  ------------------
  379|    448|        sexp_error(sexp_exception_t::warning,
  380|    448|                   "Hex string has length %d different than declared length %d",
  381|    448|                   ss.length(),
  382|    448|                   length,
  383|    448|                   count);
  384|  2.71k|}
_ZN4sexp19sexp_input_stream_t18scan_base64_stringERNS_20sexp_simple_string_tEj:
  393|  3.27k|{
  394|  3.27k|    set_byte_size(6)->skip_char('|');
  395|  12.0M|    while (next_char != EOF && (next_char != '|' || get_byte_size() == 6)) {
  ------------------
  |  Branch (395:12): [True: 12.0M, False: 144]
  |  Branch (395:33): [True: 12.0M, False: 3.51k]
  |  Branch (395:53): [True: 383, False: 3.13k]
  ------------------
  396|  12.0M|        ss.append(next_char);
  397|  12.0M|        get_char();
  398|  12.0M|    }
  399|  3.27k|    skip_char('|');
  400|  3.27k|    if (ss.length() != length && length != std::numeric_limits<uint32_t>::max())
  ------------------
  |  Branch (400:9): [True: 2.93k, False: 338]
  |  Branch (400:34): [True: 590, False: 2.34k]
  ------------------
  401|    590|        sexp_error(sexp_exception_t::warning,
  402|    590|                   "Base64 string has length %d different than declared length %d",
  403|    590|                   ss.length(),
  404|    590|                   length,
  405|    590|                   count);
  406|  3.27k|}
_ZN4sexp19sexp_input_stream_t18scan_simple_stringEv:
  415|  1.95M|{
  416|  1.95M|    int                  length;
  417|  1.95M|    sexp_simple_string_t ss;
  418|  1.95M|    skip_white_space();
  419|       |    /* Note that it is important in the following code to test for token-ness
  420|       |     * before checking the other cases, so that a token may begin with ":",
  421|       |     * which would otherwise be treated as a verbatim string missing a length.
  422|       |     */
  423|  1.95M|    if (is_token_char(next_char) && !is_dec_digit(next_char)) {
  ------------------
  |  Branch (423:9): [True: 1.94M, False: 13.4k]
  |  Branch (423:37): [True: 1.72M, False: 220k]
  ------------------
  424|  1.72M|        scan_token(ss);
  425|  1.72M|    } else {
  426|   233k|        length = is_dec_digit(next_char) ? scan_decimal_string() :
  ------------------
  |  Branch (426:18): [True: 220k, False: 13.4k]
  ------------------
  427|   233k|                                           std::numeric_limits<uint32_t>::max();
  428|       |
  429|   233k|        switch (next_char) {
  430|  9.03k|        case '\"':
  ------------------
  |  Branch (430:9): [True: 9.03k, False: 224k]
  ------------------
  431|  9.03k|            scan_quoted_string(ss, length);
  432|  9.03k|            break;
  433|  2.71k|        case '#':
  ------------------
  |  Branch (433:9): [True: 2.71k, False: 230k]
  ------------------
  434|  2.71k|            scan_hexadecimal_string(ss, length);
  435|  2.71k|            break;
  436|  3.27k|        case '|':
  ------------------
  |  Branch (436:9): [True: 3.27k, False: 230k]
  ------------------
  437|  3.27k|            scan_base64_string(ss, length);
  438|  3.27k|            break;
  439|   217k|        case ':':
  ------------------
  |  Branch (439:9): [True: 217k, False: 15.6k]
  ------------------
  440|       |            // ':' is 'tokenchar', so some length shall be defined
  441|   217k|            scan_verbatim_string(ss, length);
  442|   217k|            break;
  443|    600|        default: {
  ------------------
  |  Branch (443:9): [True: 600, False: 232k]
  ------------------
  444|    600|            const char *const msg = (next_char == EOF) ? "unexpected end of file" :
  ------------------
  |  Branch (444:37): [True: 502, False: 98]
  ------------------
  445|    600|                                    isprint(next_char) ? "illegal character '%c' (0x%x)" :
  ------------------
  |  Branch (445:37): [True: 23, False: 75]
  ------------------
  446|     98|                                                         "illegal character 0x%x";
  447|    600|            sexp_error(sexp_exception_t::error, msg, next_char, next_char, count);
  448|    600|        }
  449|   233k|        }
  450|   233k|    }
  451|       |
  452|  1.95M|    if (ss.length() == 0)
  ------------------
  |  Branch (452:9): [True: 6.13k, False: 1.95M]
  ------------------
  453|  6.13k|        sexp_error(sexp_exception_t::warning, "Simple string has zero length", 0, 0, count);
  454|  1.95M|    return ss;
  455|  1.95M|}
_ZN4sexp19sexp_input_stream_t11scan_stringEv:
  462|  1.95M|{
  463|  1.95M|    auto s = std::make_shared<sexp_string_t>();
  464|  1.95M|    ;
  465|  1.95M|    s->parse(this);
  466|  1.95M|    return s;
  467|  1.95M|}
_ZN4sexp19sexp_input_stream_t9scan_listEv:
  474|  1.78M|{
  475|  1.78M|    auto list = std::make_shared<sexp_list_t>();
  476|  1.78M|    list->parse(this);
  477|  1.78M|    return list;
  478|  1.78M|}
_ZN4sexp19sexp_input_stream_t11scan_objectEv:
  485|  3.74M|{
  486|  3.74M|    std::shared_ptr<sexp_object_t> object;
  487|  3.74M|    skip_white_space();
  488|  3.74M|    if (next_char == '{' && byte_size != 6) {
  ------------------
  |  Branch (488:9): [True: 722, False: 3.74M]
  |  Branch (488:29): [True: 720, False: 2]
  ------------------
  489|    720|        set_byte_size(6)->skip_char('{');
  490|    720|        object = scan_object();
  491|    720|        skip_char('}');
  492|  3.74M|    } else {
  493|  3.74M|        if (next_char == '(')
  ------------------
  |  Branch (493:13): [True: 1.78M, False: 1.95M]
  ------------------
  494|  1.78M|            object = scan_list();
  495|  1.95M|        else
  496|  1.95M|            object = scan_string();
  497|  3.74M|    }
  498|  3.74M|    return object;
  499|  3.74M|}
_ZN4sexp19sexp_input_stream_t9open_listEv:
  505|  1.78M|{
  506|  1.78M|    skip_char('(');
  507|       |    // gcc 4.8.5 generates wrong code in case of chaining like
  508|       |    //           skip_char('(')->increase_depth(count)
  509|  1.78M|    increase_depth(count);
  510|  1.78M|    return this;
  511|  1.78M|}
_ZN4sexp19sexp_input_stream_t10close_listEv:
  516|  1.78M|{
  517|  1.78M|    skip_char(')');
  518|  1.78M|    decrease_depth();
  519|  1.78M|    return this;
  520|  1.78M|}

_ZN4sexp13sexp_string_t5parseEPNS_19sexp_input_stream_tE:
   39|  1.95M|{
   40|  1.95M|    if (sis->get_next_char() == '[') { /* scan presentation hint */
  ------------------
  |  Branch (40:9): [True: 738, False: 1.95M]
  ------------------
   41|    738|        sis->skip_char('[');
   42|    738|        set_presentation_hint(sis->scan_simple_string());
   43|    738|        sis->skip_white_space()->skip_char(']')->skip_white_space();
   44|    738|    }
   45|  1.95M|    set_string(sis->scan_simple_string());
   46|  1.95M|}
_ZN4sexp11sexp_list_t5parseEPNS_19sexp_input_stream_tE:
   98|  1.78M|{
   99|  1.78M|    sis->open_list()->skip_white_space();
  100|  1.78M|    if (sis->get_next_char() == ')') {
  ------------------
  |  Branch (100:9): [True: 1.77M, False: 11.4k]
  ------------------
  101|  1.77M|        ;
  102|  1.77M|    } else {
  103|  11.4k|        push_back(sis->scan_object());
  104|  11.4k|    }
  105|       |
  106|  5.51M|    while (true) {
  ------------------
  |  Branch (106:12): [True: 5.51M, Folded]
  ------------------
  107|  5.51M|        sis->skip_white_space();
  108|  5.51M|        if (sis->get_next_char() == ')') { /* we just grabbed last element of list */
  ------------------
  |  Branch (108:13): [True: 1.78M, False: 3.73M]
  ------------------
  109|  1.78M|            sis->close_list();
  110|  1.78M|            return;
  111|       |
  112|  3.73M|        } else {
  113|  3.73M|            push_back(sis->scan_object());
  114|  3.73M|        }
  115|  5.51M|    }
  116|  1.78M|}

