_Z16htole32_internalj:
   39|  35.6k|{
   40|       |    if constexpr (std::endian::native == std::endian::big) return internal_bswap_32(host_32bits);
   41|  35.6k|        else return host_32bits;
   42|  35.6k|}
_Z16le32toh_internalj:
   49|  2.62k|{
   50|       |    if constexpr (std::endian::native == std::endian::big) return internal_bswap_32(little_endian_32bits);
   51|  2.62k|        else return little_endian_32bits;
   52|  2.62k|}
_Z16le64toh_internalm:
   69|  2.96k|{
   70|       |    if constexpr (std::endian::native == std::endian::big) return internal_bswap_64(little_endian_64bits);
   71|  2.96k|        else return little_endian_64bits;
   72|  2.96k|}

_ZN15ChaCha20Aligned6SetKeyE4SpanIKSt4byteE:
   26|    328|{
   27|    328|    assert(key.size() == KEYLEN);
   28|    328|    input[0] = ReadLE32(key.data() + 0);
   29|    328|    input[1] = ReadLE32(key.data() + 4);
   30|    328|    input[2] = ReadLE32(key.data() + 8);
   31|    328|    input[3] = ReadLE32(key.data() + 12);
   32|    328|    input[4] = ReadLE32(key.data() + 16);
   33|    328|    input[5] = ReadLE32(key.data() + 20);
   34|    328|    input[6] = ReadLE32(key.data() + 24);
   35|    328|    input[7] = ReadLE32(key.data() + 28);
   36|    328|    input[8] = 0;
   37|    328|    input[9] = 0;
   38|    328|    input[10] = 0;
   39|    328|    input[11] = 0;
   40|    328|}
_ZN15ChaCha20AlignedD2Ev:
   43|    328|{
   44|    328|    memory_cleanse(input, sizeof(input));
   45|    328|}
_ZN15ChaCha20AlignedC2E4SpanIKSt4byteE:
   48|    328|{
   49|    328|    SetKey(key);
   50|    328|}
_ZN8ChaCha209KeystreamE4SpanISt4byteE:
  283|  3.62k|{
  284|  3.62k|    if (out.empty()) return;
  ------------------
  |  Branch (284:9): [True: 170, False: 3.45k]
  ------------------
  285|  3.45k|    if (m_bufleft) {
  ------------------
  |  Branch (285:9): [True: 2.98k, False: 472]
  ------------------
  286|  2.98k|        unsigned reuse = std::min<size_t>(m_bufleft, out.size());
  287|  2.98k|        std::copy(m_buffer.end() - m_bufleft, m_buffer.end() - m_bufleft + reuse, out.begin());
  288|  2.98k|        m_bufleft -= reuse;
  289|  2.98k|        out = out.subspan(reuse);
  290|  2.98k|    }
  291|  3.45k|    if (out.size() >= m_aligned.BLOCKLEN) {
  ------------------
  |  Branch (291:9): [True: 136, False: 3.31k]
  ------------------
  292|    136|        size_t blocks = out.size() / m_aligned.BLOCKLEN;
  293|    136|        m_aligned.Keystream(out.first(blocks * m_aligned.BLOCKLEN));
  294|    136|        out = out.subspan(blocks * m_aligned.BLOCKLEN);
  295|    136|    }
  296|  3.45k|    if (!out.empty()) {
  ------------------
  |  Branch (296:9): [True: 854, False: 2.60k]
  ------------------
  297|    854|        m_aligned.Keystream(m_buffer);
  298|    854|        std::copy(m_buffer.begin(), m_buffer.begin() + out.size(), out.begin());
  299|    854|        m_bufleft = m_aligned.BLOCKLEN - out.size();
  300|    854|    }
  301|  3.45k|}
_ZN8ChaCha20D2Ev:
  333|    328|{
  334|    328|    memory_cleanse(m_buffer.data(), m_buffer.size());
  335|    328|}
_ZN15ChaCha20Aligned9KeystreamE4SpanISt4byteE:
   61|    990|{
   62|    990|    std::byte* c = output.data();
   63|    990|    size_t blocks = output.size() / BLOCKLEN;
   64|    990|    assert(blocks * BLOCKLEN == output.size());
   65|       |
   66|    990|    uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
   67|    990|    uint32_t j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
   68|       |
   69|    990|    if (!blocks) return;
  ------------------
  |  Branch (69:9): [True: 0, False: 990]
  ------------------
   70|       |
   71|    990|    j4 = input[0];
   72|    990|    j5 = input[1];
   73|    990|    j6 = input[2];
   74|    990|    j7 = input[3];
   75|    990|    j8 = input[4];
   76|    990|    j9 = input[5];
   77|    990|    j10 = input[6];
   78|    990|    j11 = input[7];
   79|    990|    j12 = input[8];
   80|    990|    j13 = input[9];
   81|    990|    j14 = input[10];
   82|    990|    j15 = input[11];
   83|       |
   84|  2.22k|    for (;;) {
   85|  2.22k|        x0 = 0x61707865;
   86|  2.22k|        x1 = 0x3320646e;
   87|  2.22k|        x2 = 0x79622d32;
   88|  2.22k|        x3 = 0x6b206574;
   89|  2.22k|        x4 = j4;
   90|  2.22k|        x5 = j5;
   91|  2.22k|        x6 = j6;
   92|  2.22k|        x7 = j7;
   93|  2.22k|        x8 = j8;
   94|  2.22k|        x9 = j9;
   95|  2.22k|        x10 = j10;
   96|  2.22k|        x11 = j11;
   97|  2.22k|        x12 = j12;
   98|  2.22k|        x13 = j13;
   99|  2.22k|        x14 = j14;
  100|  2.22k|        x15 = j15;
  101|       |
  102|       |        // The 20 inner ChaCha20 rounds are unrolled here for performance.
  103|  2.22k|        REPEAT10(
  ------------------
  |  |   23|  2.22k|#define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0)
  |  |  ------------------
  |  |  |  Branch (23:84): [Folded - Ignored]
  |  |  ------------------
  ------------------
  104|  2.22k|            QUARTERROUND( x0, x4, x8,x12);
  105|  2.22k|            QUARTERROUND( x1, x5, x9,x13);
  106|  2.22k|            QUARTERROUND( x2, x6,x10,x14);
  107|  2.22k|            QUARTERROUND( x3, x7,x11,x15);
  108|  2.22k|            QUARTERROUND( x0, x5,x10,x15);
  109|  2.22k|            QUARTERROUND( x1, x6,x11,x12);
  110|  2.22k|            QUARTERROUND( x2, x7, x8,x13);
  111|  2.22k|            QUARTERROUND( x3, x4, x9,x14);
  112|  2.22k|        );
  113|       |
  114|  2.22k|        x0 += 0x61707865;
  115|  2.22k|        x1 += 0x3320646e;
  116|  2.22k|        x2 += 0x79622d32;
  117|  2.22k|        x3 += 0x6b206574;
  118|  2.22k|        x4 += j4;
  119|  2.22k|        x5 += j5;
  120|  2.22k|        x6 += j6;
  121|  2.22k|        x7 += j7;
  122|  2.22k|        x8 += j8;
  123|  2.22k|        x9 += j9;
  124|  2.22k|        x10 += j10;
  125|  2.22k|        x11 += j11;
  126|  2.22k|        x12 += j12;
  127|  2.22k|        x13 += j13;
  128|  2.22k|        x14 += j14;
  129|  2.22k|        x15 += j15;
  130|       |
  131|  2.22k|        ++j12;
  132|  2.22k|        if (!j12) ++j13;
  ------------------
  |  Branch (132:13): [True: 0, False: 2.22k]
  ------------------
  133|       |
  134|  2.22k|        WriteLE32(c + 0, x0);
  135|  2.22k|        WriteLE32(c + 4, x1);
  136|  2.22k|        WriteLE32(c + 8, x2);
  137|  2.22k|        WriteLE32(c + 12, x3);
  138|  2.22k|        WriteLE32(c + 16, x4);
  139|  2.22k|        WriteLE32(c + 20, x5);
  140|  2.22k|        WriteLE32(c + 24, x6);
  141|  2.22k|        WriteLE32(c + 28, x7);
  142|  2.22k|        WriteLE32(c + 32, x8);
  143|  2.22k|        WriteLE32(c + 36, x9);
  144|  2.22k|        WriteLE32(c + 40, x10);
  145|  2.22k|        WriteLE32(c + 44, x11);
  146|  2.22k|        WriteLE32(c + 48, x12);
  147|  2.22k|        WriteLE32(c + 52, x13);
  148|  2.22k|        WriteLE32(c + 56, x14);
  149|  2.22k|        WriteLE32(c + 60, x15);
  150|       |
  151|  2.22k|        if (blocks == 1) {
  ------------------
  |  Branch (151:13): [True: 990, False: 1.23k]
  ------------------
  152|    990|            input[8] = j12;
  153|    990|            input[9] = j13;
  154|    990|            return;
  155|    990|        }
  156|  1.23k|        blocks -= 1;
  157|  1.23k|        c += BLOCKLEN;
  158|  1.23k|    }
  159|    990|}

_ZN8ChaCha20C2E4SpanIKSt4byteE:
   92|    328|    ChaCha20(Span<const std::byte> key) noexcept : m_aligned(key) {}

_Z8ReadLE64ITk8ByteTypeSt4byteEmPKT_:
   36|  2.96k|{
   37|  2.96k|    uint64_t x;
   38|  2.96k|    memcpy(&x, ptr, 8);
   39|  2.96k|    return le64toh_internal(x);
   40|  2.96k|}
_Z9WriteLE32ITk8ByteTypeSt4byteEvPT_j:
   51|  35.6k|{
   52|  35.6k|    uint32_t v = htole32_internal(x);
   53|  35.6k|    memcpy(ptr, &v, 4);
   54|  35.6k|}
_Z8ReadLE32ITk8ByteTypeSt4byteEjPKT_:
   28|  2.62k|{
   29|  2.62k|    uint32_t x;
   30|  2.62k|    memcpy(&x, ptr, 4);
   31|  2.62k|    return le32toh_internal(x);
   32|  2.62k|}

_ZN17FastRandomContext8fillrandE4SpanISt4byteE:
  702|    656|{
  703|    656|    if (requires_seed) RandomSeed();
  ------------------
  |  Branch (703:9): [True: 0, False: 656]
  ------------------
  704|    656|    rng.Keystream(output);
  705|    656|}
_ZN17FastRandomContextC2ERK7uint256:
  707|    328|FastRandomContext::FastRandomContext(const uint256& seed) noexcept : requires_seed(false), rng(MakeByteSpan(seed)) {}

_ZN11RandomMixinI17FastRandomContextE4ImplEv:
  185|  4.79k|    RandomNumberGenerator auto& Impl() noexcept { return static_cast<T&>(*this); }
_ZN11RandomMixinI17FastRandomContextE8randbitsEi:
  205|  1.16k|    {
  206|  1.16k|        Assume(bits <= 64);
  ------------------
  |  |   97|  1.16k|#define Assume(val) inline_assertion_check<false>(val, __FILE__, __LINE__, __func__, #val)
  ------------------
  207|       |        // Requests for the full 64 bits are passed through.
  208|  1.16k|        if (bits == 64) return Impl().rand64();
  ------------------
  |  Branch (208:13): [True: 366, False: 803]
  ------------------
  209|    803|        uint64_t ret;
  210|    803|        if (bits <= bitbuf_size) {
  ------------------
  |  Branch (210:13): [True: 284, False: 519]
  ------------------
  211|       |            // If there is enough entropy left in bitbuf, return its bottom bits bits.
  212|    284|            ret = bitbuf;
  213|    284|            bitbuf >>= bits;
  214|    284|            bitbuf_size -= bits;
  215|    519|        } else {
  216|       |            // If not, return all of bitbuf, supplemented with the (bits - bitbuf_size) bottom
  217|       |            // bits of a newly generated 64-bit number on top. The remainder of that generated
  218|       |            // number becomes the new bitbuf.
  219|    519|            uint64_t gen = Impl().rand64();
  220|    519|            ret = (gen << bitbuf_size) | bitbuf;
  221|    519|            bitbuf = gen >> (bits - bitbuf_size);
  222|    519|            bitbuf_size = 64 + bitbuf_size - bits;
  223|    519|        }
  224|       |        // Return the bottom bits bits of ret.
  225|    803|        return ret & ((uint64_t{1} << bits) - 1);
  226|  1.16k|    }
_ZN17FastRandomContext6rand64Ev:
  396|  2.96k|    {
  397|  2.96k|        if (requires_seed) RandomSeed();
  ------------------
  |  Branch (397:13): [True: 0, False: 2.96k]
  ------------------
  398|  2.96k|        std::array<std::byte, 8> buf;
  399|  2.96k|        rng.Keystream(buf);
  400|  2.96k|        return ReadLE64(buf.data());
  401|  2.96k|    }
_ZN11RandomMixinI17FastRandomContextE3maxEv:
  366|    328|    static constexpr uint64_t max() noexcept { return std::numeric_limits<uint64_t>::max(); }
_ZN11RandomMixinI17FastRandomContextE3minEv:
  365|    328|    static constexpr uint64_t min() noexcept { return 0; }
_ZN11RandomMixinI17FastRandomContextEclEv:
  367|  1.52k|    inline uint64_t operator()() noexcept { return Impl().rand64(); }
_ZN11RandomMixinI17FastRandomContextE8randboolEv:
  316|    328|    bool randbool() noexcept { return Impl().template randbits<1>(); }
_ZN11RandomMixinI17FastRandomContextE8randbitsILi1EEEmv:
  231|    328|    {
  232|    328|        static_assert(Bits >= 0 && Bits <= 64);
  233|       |        if constexpr (Bits == 64) {
  234|       |            return Impl().rand64();
  235|    328|        } else {
  236|    328|            uint64_t ret;
  237|    328|            if (Bits <= bitbuf_size) {
  ------------------
  |  Branch (237:17): [True: 314, False: 14]
  ------------------
  238|    314|                ret = bitbuf;
  239|    314|                bitbuf >>= Bits;
  240|    314|                bitbuf_size -= Bits;
  241|    314|            } else {
  242|     14|                uint64_t gen = Impl().rand64();
  243|     14|                ret = (gen << bitbuf_size) | bitbuf;
  244|     14|                bitbuf = gen >> (Bits - bitbuf_size);
  245|     14|                bitbuf_size = 64 + bitbuf_size - Bits;
  246|     14|            }
  247|    328|            constexpr uint64_t MASK = (uint64_t{1} << Bits) - 1;
  248|    328|            return ret & MASK;
  249|    328|        }
  250|    328|    }
_ZN11RandomMixinI17FastRandomContextE9randrangeITkNSt3__18integralEmEET_S4_:
  255|    328|    {
  256|    328|        static_assert(std::numeric_limits<I>::max() <= std::numeric_limits<uint64_t>::max());
  257|    328|        Assume(range > 0);
  ------------------
  |  |   97|    328|#define Assume(val) inline_assertion_check<false>(val, __FILE__, __LINE__, __func__, #val)
  ------------------
  258|    328|        uint64_t maxval = range - 1U;
  259|    328|        int bits = std::bit_width(maxval);
  260|    841|        while (true) {
  ------------------
  |  Branch (260:16): [Folded - Ignored]
  ------------------
  261|    841|            uint64_t ret = Impl().randbits(bits);
  262|    841|            if (ret <= maxval) return ret;
  ------------------
  |  Branch (262:17): [True: 328, False: 513]
  ------------------
  263|    841|        }
  264|    328|    }
_ZN11RandomMixinI17FastRandomContextE9randbytesITk9BasicBytehEENSt3__16vectorIT_NS3_9allocatorIS5_EEEEm:
  298|    328|    {
  299|    328|        std::vector<B> ret(len);
  300|    328|        Impl().fillrand(MakeWritableByteSpan(ret));
  301|    328|        return ret;
  302|    328|    }
_ZN11RandomMixinI17FastRandomContextE6rand32Ev:
  305|    328|    uint32_t rand32() noexcept { return Impl().template randbits<32>(); }
_ZN11RandomMixinI17FastRandomContextE8randbitsILi32EEEmv:
  231|    328|    {
  232|    328|        static_assert(Bits >= 0 && Bits <= 64);
  233|       |        if constexpr (Bits == 64) {
  234|       |            return Impl().rand64();
  235|    328|        } else {
  236|    328|            uint64_t ret;
  237|    328|            if (Bits <= bitbuf_size) {
  ------------------
  |  Branch (237:17): [True: 113, False: 215]
  ------------------
  238|    113|                ret = bitbuf;
  239|    113|                bitbuf >>= Bits;
  240|    113|                bitbuf_size -= Bits;
  241|    215|            } else {
  242|    215|                uint64_t gen = Impl().rand64();
  243|    215|                ret = (gen << bitbuf_size) | bitbuf;
  244|    215|                bitbuf = gen >> (Bits - bitbuf_size);
  245|    215|                bitbuf_size = 64 + bitbuf_size - Bits;
  246|    215|            }
  247|    328|            constexpr uint64_t MASK = (uint64_t{1} << Bits) - 1;
  248|    328|            return ret & MASK;
  249|    328|        }
  250|    328|    }
_ZN11RandomMixinI17FastRandomContextE7rand256Ev:
  309|    328|    {
  310|    328|        uint256 ret;
  311|    328|        Impl().fillrand(MakeWritableByteSpan(ret));
  312|    328|        return ret;
  313|    328|    }
_ZN11RandomMixinI17FastRandomContextEC2Ev:
  195|    328|    constexpr RandomMixin() noexcept = default;

_ZNK4SpanISt4byteE5firstEm:
  206|    136|    {
  207|    136|        ASSERT_IF_DEBUG(size() >= count);
  208|    136|        return Span<C>(m_data, count);
  209|    136|    }
_ZNK4SpanIKSt4byteE4sizeEv:
  187|    328|    constexpr std::size_t size() const noexcept { return m_size; }
_ZNK4SpanIKSt4byteE4dataEv:
  174|  2.62k|    constexpr C* data() const noexcept { return m_data; }
_ZNK4SpanIKhE4sizeEv:
  187|    316|    constexpr std::size_t size() const noexcept { return m_size; }
_ZNK4SpanIKhE5beginEv:
  175|    316|    constexpr C* begin() const noexcept { return m_data; }
_ZNK4SpanIKhE3endEv:
  176|    316|    constexpr C* end() const noexcept { return m_data + m_size; }
_ZNK4SpanIhE4dataEv:
  174|    656|    constexpr C* data() const noexcept { return m_data; }
_ZNK4SpanIKhE4dataEv:
  174|    328|    constexpr C* data() const noexcept { return m_data; }
_ZNK4SpanISt4byteE4sizeEv:
  187|  17.3k|    constexpr std::size_t size() const noexcept { return m_size; }
_ZNK4SpanISt4byteE4dataEv:
  174|    990|    constexpr C* data() const noexcept { return m_data; }
_ZNK4SpanISt4byteE7subspanEm:
  196|  3.11k|    {
  197|  3.11k|        ASSERT_IF_DEBUG(size() >= offset);
  198|  3.11k|        return Span<C>(m_data + offset, m_size - offset);
  199|  3.11k|    }
_ZNK4SpanIKhE10size_bytesEv:
  188|    328|    constexpr std::size_t size_bytes() const noexcept { return sizeof(C) * m_size; }
_Z7AsBytesIKhE4SpanIKSt4byteES1_IT_E:
  259|    328|{
  260|    328|    return {reinterpret_cast<const std::byte*>(s.data()), s.size_bytes()};
  261|    328|}
_ZN4SpanIKhEC2INSt3__16vectorIhNS3_9allocatorIhEEEEEERKT_NS3_9enable_ifIXaaaantsr7is_SpanIS8_EE5valuesr3std14is_convertibleIPA_NS3_14remove_pointerIDTcldtclsr3stdE7declvalISA_EE4dataEEE4typeEPA_S0_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalISA_EE4sizeEEmEE5valueEDnE4typeE:
  172|    316|        : m_data(other.data()), m_size(other.size()){}
_ZN4SpanIKSt4byteEC2IS1_TnNSt3__19enable_ifIXsr3std14is_convertibleIPA_T_PA_S1_EE5valueEiE4typeELi0EEEPS6_m:
  119|    328|    constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
_ZN4SpanISt4byteEC2INSt3__15arrayIS0_Lm8EEEEERT_NS3_9enable_ifIXaaaantsr7is_SpanIS6_EE5valuesr3std14is_convertibleIPA_NS3_14remove_pointerIDTcldtclsr3stdE7declvalIS7_EE4dataEEE4typeEPA_S0_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalIS7_EE4sizeEEmEE5valueEDnE4typeE:
  165|  2.96k|        : m_data(other.data()), m_size(other.size()){}
_ZNK4SpanIhE10size_bytesEv:
  188|    656|    constexpr std::size_t size_bytes() const noexcept { return sizeof(C) * m_size; }
_ZN4SpanISt4byteEC2IS0_TnNSt3__19enable_ifIXsr3std14is_convertibleIPA_T_PA_S0_EE5valueEiE4typeELi0EEEPS5_m:
  119|  3.91k|    constexpr Span(T* begin, std::size_t size) noexcept : m_data(begin), m_size(size) {}
_Z15AsWritableBytesIhE4SpanISt4byteES0_IT_E:
  264|    656|{
  265|    656|    return {reinterpret_cast<std::byte*>(s.data()), s.size_bytes()};
  266|    656|}
_ZN4SpanIKhEC2I7uint256EERKT_NSt3__19enable_ifIXaaaantsr7is_SpanIS4_EE5valuesr3std14is_convertibleIPA_NS7_14remove_pointerIDTcldtclsr3stdE7declvalIS6_EE4dataEEE4typeEPA_S0_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalIS6_EE4sizeEEmEE5valueEDnE4typeE:
  172|    328|        : m_data(other.data()), m_size(other.size()){}
_ZN4SpanIhEC2I7uint256EERT_NSt3__19enable_ifIXaaaantsr7is_SpanIS3_EE5valuesr3std14is_convertibleIPA_NS5_14remove_pointerIDTcldtclsr3stdE7declvalIS4_EE4dataEEE4typeEPA_hEE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalIS4_EE4sizeEEmEE5valueEDnE4typeE:
  165|    328|        : m_data(other.data()), m_size(other.size()){}
_ZN4SpanIhEC2INSt3__16vectorIhNS2_9allocatorIhEEEEEERT_NS2_9enable_ifIXaaaantsr7is_SpanIS7_EE5valuesr3std14is_convertibleIPA_NS2_14remove_pointerIDTcldtclsr3stdE7declvalIS8_EE4dataEEE4typeEPA_hEE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalIS8_EE4sizeEEmEE5valueEDnE4typeE:
  165|    328|        : m_data(other.data()), m_size(other.size()){}
_Z20MakeWritableByteSpanIRNSt3__16vectorIhNS0_9allocatorIhEEEEE4SpanISt4byteEOT_:
  275|    328|{
  276|    328|    return AsWritableBytes(Span{std::forward<V>(v)});
  277|    328|}
_ZNK4SpanISt4byteE5beginEv:
  175|  3.83k|    constexpr C* begin() const noexcept { return m_data; }
_Z20MakeWritableByteSpanIR7uint256E4SpanISt4byteEOT_:
  275|    328|{
  276|    328|    return AsWritableBytes(Span{std::forward<V>(v)});
  277|    328|}
_Z12MakeByteSpanIRK7uint256E4SpanIKSt4byteEOT_:
  270|    328|{
  271|    328|    return AsBytes(Span{std::forward<V>(v)});
  272|    328|}
_ZNK4SpanISt4byteE5emptyEv:
  189|  7.07k|    constexpr bool empty() const noexcept { return size() == 0; }
_ZN4SpanISt4byteEC2INSt3__15arrayIS0_Lm64EEEEERT_NS3_9enable_ifIXaaaantsr7is_SpanIS6_EE5valuesr3std14is_convertibleIPA_NS3_14remove_pointerIDTcldtclsr3stdE7declvalIS7_EE4dataEEE4typeEPA_S0_EE5valuesr3std14is_convertibleIDTcldtclsr3stdE7declvalIS7_EE4sizeEEmEE5valueEDnE4typeE:
  165|    854|        : m_data(other.data()), m_size(other.size()){}

_Z14memory_cleansePvm:
   15|    656|{
   16|       |#if defined(WIN32)
   17|       |    /* SecureZeroMemory is guaranteed not to be optimized out. */
   18|       |    SecureZeroMemory(ptr, len);
   19|       |#else
   20|    656|    std::memset(ptr, 0, len);
   21|       |
   22|       |    /* Memory barrier that scares the compiler away from optimizing out the memset.
   23|       |     *
   24|       |     * Quoting Adam Langley <agl@google.com> in commit ad1907fe73334d6c696c8539646c21b11178f20f
   25|       |     * in BoringSSL (ISC License):
   26|       |     *    As best as we can tell, this is sufficient to break any optimisations that
   27|       |     *    might try to eliminate "superfluous" memsets.
   28|       |     * This method is used in memzero_explicit() the Linux kernel, too. Its advantage is that it
   29|       |     * is pretty efficient because the compiler can still implement the memset() efficiently,
   30|       |     * just not remove it entirely. See "Dead Store Elimination (Still) Considered Harmful" by
   31|       |     * Yang et al. (USENIX Security 2017) for more background.
   32|       |     */
   33|    656|    __asm__ __volatile__("" : : "r"(ptr) : "memory");
   34|    656|#endif
   35|    656|}

_ZN18FuzzedDataProviderC2EPKhm:
   37|    328|      : data_ptr_(data), remaining_bytes_(size) {}
_ZN18FuzzedDataProvider15ConsumeIntegralIlEET_v:
  195|  1.02k|template <typename T> T FuzzedDataProvider::ConsumeIntegral() {
  196|  1.02k|  return ConsumeIntegralInRange(std::numeric_limits<T>::min(),
  197|  1.02k|                                std::numeric_limits<T>::max());
  198|  1.02k|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeIlEET_S1_S1_:
  205|  1.02k|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|  1.02k|  static_assert(std::is_integral<T>::value, "An integral type is required.");
  207|  1.02k|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|  1.02k|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 1.02k]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|  1.02k|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|  1.02k|  uint64_t result = 0;
  215|  1.02k|  size_t offset = 0;
  216|       |
  217|  6.35k|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 5.70k, False: 656]
  |  Branch (217:43): [True: 5.70k, False: 0]
  ------------------
  218|  6.35k|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 5.33k, False: 368]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  5.33k|    --remaining_bytes_;
  226|  5.33k|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  5.33k|    offset += CHAR_BIT;
  228|  5.33k|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|  1.02k|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 0, False: 1.02k]
  ------------------
  232|      0|    result = result % (range + 1);
  233|       |
  234|  1.02k|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|  1.02k|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeImEET_S1_S1_:
  205|    984|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|    984|  static_assert(std::is_integral<T>::value, "An integral type is required.");
  207|    984|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|    984|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 984]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|    984|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|    984|  uint64_t result = 0;
  215|    984|  size_t offset = 0;
  216|       |
  217|  3.57k|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 3.34k, False: 235]
  |  Branch (217:43): [True: 3.05k, False: 284]
  ------------------
  218|  3.57k|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 2.59k, False: 465]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|  2.59k|    --remaining_bytes_;
  226|  2.59k|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|  2.59k|    offset += CHAR_BIT;
  228|  2.59k|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|    984|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 984, False: 0]
  ------------------
  232|    984|    result = result % (range + 1);
  233|       |
  234|    984|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|    984|}
_ZN18FuzzedDataProvider22ConsumeIntegralInRangeIiEET_S1_S1_:
  205|    328|T FuzzedDataProvider::ConsumeIntegralInRange(T min, T max) {
  206|    328|  static_assert(std::is_integral<T>::value, "An integral type is required.");
  207|    328|  static_assert(sizeof(T) <= sizeof(uint64_t), "Unsupported integral type.");
  208|       |
  209|    328|  if (min > max)
  ------------------
  |  Branch (209:7): [True: 0, False: 328]
  ------------------
  210|      0|    abort();
  211|       |
  212|       |  // Use the biggest type possible to hold the range and the result.
  213|    328|  uint64_t range = static_cast<uint64_t>(max) - static_cast<uint64_t>(min);
  214|    328|  uint64_t result = 0;
  215|    328|  size_t offset = 0;
  216|       |
  217|    643|  while (offset < sizeof(T) * CHAR_BIT && (range >> offset) > 0 &&
  ------------------
  |  Branch (217:10): [True: 643, False: 0]
  |  Branch (217:43): [True: 328, False: 315]
  ------------------
  218|    643|         remaining_bytes_ != 0) {
  ------------------
  |  Branch (218:10): [True: 315, False: 13]
  ------------------
  219|       |    // Pull bytes off the end of the seed data. Experimentally, this seems to
  220|       |    // allow the fuzzer to more easily explore the input space. This makes
  221|       |    // sense, since it works by modifying inputs that caused new code to run,
  222|       |    // and this data is often used to encode length of data read by
  223|       |    // |ConsumeBytes|. Separating out read lengths makes it easier modify the
  224|       |    // contents of the data that is actually read.
  225|    315|    --remaining_bytes_;
  226|    315|    result = (result << CHAR_BIT) | data_ptr_[remaining_bytes_];
  227|    315|    offset += CHAR_BIT;
  228|    315|  }
  229|       |
  230|       |  // Avoid division by 0, in case |range + 1| results in overflow.
  231|    328|  if (range != std::numeric_limits<decltype(range)>::max())
  ------------------
  |  Branch (231:7): [True: 328, False: 0]
  ------------------
  232|    328|    result = result % (range + 1);
  233|       |
  234|    328|  return static_cast<T>(static_cast<uint64_t>(min) + result);
  235|    328|}
_ZN18FuzzedDataProvider14CopyAndAdvanceEPvm:
  339|    328|                                               size_t num_bytes) {
  340|    328|  std::memcpy(destination, data_ptr_, num_bytes);
  341|    328|  Advance(num_bytes);
  342|    328|}
_ZN18FuzzedDataProvider7AdvanceEm:
  344|    328|inline void FuzzedDataProvider::Advance(size_t num_bytes) {
  345|    328|  if (num_bytes > remaining_bytes_)
  ------------------
  |  Branch (345:7): [True: 0, False: 328]
  ------------------
  346|      0|    abort();
  347|       |
  348|    328|  data_ptr_ += num_bytes;
  349|    328|  remaining_bytes_ -= num_bytes;
  350|    328|}
_ZN18FuzzedDataProvider12ConsumeBytesIhEENSt3__16vectorIT_NS1_9allocatorIS3_EEEEm:
  109|    328|std::vector<T> FuzzedDataProvider::ConsumeBytes(size_t num_bytes) {
  110|    328|  num_bytes = std::min(num_bytes, remaining_bytes_);
  111|    328|  return ConsumeBytes<T>(num_bytes, num_bytes);
  112|    328|}
_ZN18FuzzedDataProvider12ConsumeBytesIhEENSt3__16vectorIT_NS1_9allocatorIS3_EEEEmm:
  353|    328|std::vector<T> FuzzedDataProvider::ConsumeBytes(size_t size, size_t num_bytes) {
  354|    328|  static_assert(sizeof(T) == sizeof(uint8_t), "Incompatible data type.");
  355|       |
  356|       |  // The point of using the size-based constructor below is to increase the
  357|       |  // odds of having a vector object with capacity being equal to the length.
  358|       |  // That part is always implementation specific, but at least both libc++ and
  359|       |  // libstdc++ allocate the requested number of bytes in that constructor,
  360|       |  // which seems to be a natural choice for other implementations as well.
  361|       |  // To increase the odds even more, we also call |shrink_to_fit| below.
  362|    328|  std::vector<T> result(size);
  363|    328|  if (size == 0) {
  ------------------
  |  Branch (363:7): [True: 0, False: 328]
  ------------------
  364|      0|    if (num_bytes != 0)
  ------------------
  |  Branch (364:9): [True: 0, False: 0]
  ------------------
  365|      0|      abort();
  366|      0|    return result;
  367|      0|  }
  368|       |
  369|    328|  CopyAndAdvance(result.data(), num_bytes);
  370|       |
  371|       |  // Even though |shrink_to_fit| is also implementation specific, we expect it
  372|       |  // to provide an additional assurance in case vector's constructor allocated
  373|       |  // a buffer which is larger than the actual amount of data we put inside it.
  374|    328|  result.shrink_to_fit();
  375|    328|  return result;
  376|    328|}

LLVMFuzzerTestOneInput:
  222|    328|{
  223|    328|    test_one_input({data, size});
  224|    328|    return 0;
  225|    328|}
fuzz.cpp:_ZL14test_one_inputNSt3__14spanIKhLm18446744073709551615EEE:
   83|    328|{
   84|    328|    CheckGlobals check{};
   85|    328|    (*Assert(g_test_one_input))(buffer);
  ------------------
  |  |   85|    328|#define Assert(val) inline_assertion_check<true>(val, __FILE__, __LINE__, __func__, #val)
  ------------------
   86|    328|}

_Z18random_fuzz_targetNSt3__14spanIKhLm18446744073709551615EEE:
   16|    328|{
   17|    328|    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
   18|    328|    FastRandomContext fast_random_context{ConsumeUInt256(fuzzed_data_provider)};
   19|    328|    (void)fast_random_context.rand64();
   20|    328|    (void)fast_random_context.randbits(fuzzed_data_provider.ConsumeIntegralInRange<int>(0, 64));
   21|    328|    (void)fast_random_context.randrange(fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(FastRandomContext::min() + 1, FastRandomContext::max()));
   22|    328|    (void)fast_random_context.randbytes(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, 1024));
   23|    328|    (void)fast_random_context.rand32();
   24|    328|    (void)fast_random_context.rand256();
   25|    328|    (void)fast_random_context.randbool();
   26|    328|    (void)fast_random_context();
   27|       |
   28|    328|    std::vector<int64_t> integrals = ConsumeRandomLengthIntegralVector<int64_t>(fuzzed_data_provider);
   29|    328|    std::shuffle(integrals.begin(), integrals.end(), fast_random_context);
   30|    328|}

_Z14ConsumeUInt256R18FuzzedDataProvider:
  172|    328|{
  173|    328|    const std::vector<uint8_t> v256 = fuzzed_data_provider.ConsumeBytes<uint8_t>(256 / 8);
  174|    328|    if (v256.size() != 256 / 8) {
  ------------------
  |  Branch (174:9): [True: 12, False: 316]
  ------------------
  175|     12|        return {};
  176|     12|    }
  177|    316|    return uint256{v256};
  178|    328|}
_Z33ConsumeRandomLengthIntegralVectorIlENSt3__16vectorIT_NS0_9allocatorIS2_EEEER18FuzzedDataProviderm:
   91|    328|{
   92|    328|    const size_t n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
   93|    328|    std::vector<T> r;
   94|    328|    r.reserve(n_elements);
   95|  1.35k|    for (size_t i = 0; i < n_elements; ++i) {
  ------------------
  |  Branch (95:24): [True: 1.02k, False: 328]
  ------------------
   96|  1.02k|        r.push_back(fuzzed_data_provider.ConsumeIntegral<T>());
   97|  1.02k|    }
   98|    328|    return r;
   99|    328|}

_ZN12CheckGlobalsC2Ev:
   56|    328|CheckGlobals::CheckGlobals() : m_impl(std::make_unique<CheckGlobalsImpl>()) {}
_ZN12CheckGlobalsD2Ev:
   57|    328|CheckGlobals::~CheckGlobals() = default;
_ZN16CheckGlobalsImplC2Ev:
   17|    328|    {
   18|    328|        g_used_g_prng = false;
   19|    328|        g_seeded_g_prng_zero = false;
   20|    328|        g_used_system_time = false;
   21|    328|        SetMockTime(0s);
   22|    328|    }
_ZN16CheckGlobalsImplD2Ev:
   24|    328|    {
   25|    328|        if (g_used_g_prng && !g_seeded_g_prng_zero) {
  ------------------
  |  Branch (25:13): [True: 0, False: 328]
  |  Branch (25:30): [True: 0, False: 0]
  ------------------
   26|      0|            std::cerr << "\n\n"
   27|      0|                         "The current fuzz target used the global random state.\n\n"
   28|       |
   29|      0|                         "This is acceptable, but requires the fuzz target to call \n"
   30|      0|                         "SeedRandomStateForTest(SeedRand::ZEROS) in the first line \n"
   31|      0|                         "of the FUZZ_TARGET function.\n\n"
   32|       |
   33|      0|                         "An alternative solution would be to avoid any use of globals.\n\n"
   34|       |
   35|      0|                         "Without a solution, fuzz instability and non-determinism can lead \n"
   36|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   37|      0|                      << std::endl;
   38|      0|            std::abort(); // Abort, because AFL may try to recover from a std::exit
   39|      0|        }
   40|       |
   41|    328|        if (g_used_system_time) {
  ------------------
  |  Branch (41:13): [True: 0, False: 328]
  ------------------
   42|      0|            std::cerr << "\n\n"
   43|      0|                         "The current fuzz target accessed system time.\n\n"
   44|       |
   45|      0|                         "This is acceptable, but requires the fuzz target to call \n"
   46|      0|                         "SetMockTime() at the beginning of processing the fuzz input.\n\n"
   47|       |
   48|      0|                         "Without setting mock time, time-dependent behavior can lead \n"
   49|      0|                         "to non-reproducible bugs or inefficient fuzzing.\n\n"
   50|      0|                      << std::endl;
   51|      0|            std::abort();
   52|      0|        }
   53|    328|    }

_ZN7uint256C2E4SpanIKhE:
  208|    316|    constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {}
_ZN9base_blobILj256EE4sizeEv:
  121|    656|    static constexpr unsigned int size() { return WIDTH; }
_ZNK9base_blobILj256EE4dataEv:
  112|    328|    constexpr const unsigned char* data() const { return m_data.data(); }
_ZN9base_blobILj256EE4dataEv:
  113|    328|    constexpr unsigned char* data() { return m_data.data(); }
_ZN7uint256C2Ev:
  205|    340|    constexpr uint256() = default;
_ZN9base_blobILj256EEC2Ev:
   35|    340|    constexpr base_blob() : m_data() {}
_ZN9base_blobILj256EEC2E4SpanIKhE:
   41|    316|    {
   42|    316|        assert(vch.size() == WIDTH);
   43|    316|        std::copy(vch.begin(), vch.end(), m_data.begin());
   44|    316|    }

_Z22inline_assertion_checkILb0EbEOT0_S1_PKciS3_S3_:
   52|  1.49k|{
   53|  1.49k|    if (IS_ASSERT || std::is_constant_evaluated() || G_FUZZING
  ------------------
  |  Branch (53:9): [Folded - Ignored]
  |  Branch (53:22): [Folded - Ignored]
  |  Branch (53:54): [Folded - Ignored]
  ------------------
   54|       |#ifdef ABORT_ON_FAILED_ASSUME
   55|       |        || true
   56|       |#endif
   57|  1.49k|    ) {
   58|  1.49k|        if (!val) {
  ------------------
  |  Branch (58:13): [True: 0, False: 1.49k]
  ------------------
   59|      0|            assertion_fail(file, line, func, assertion);
   60|      0|        }
   61|  1.49k|    }
   62|  1.49k|    return std::forward<T>(val);
   63|  1.49k|}
_Z22inline_assertion_checkILb1EbEOT0_S1_PKciS3_S3_:
   52|    328|{
   53|    328|    if (IS_ASSERT || std::is_constant_evaluated() || G_FUZZING
  ------------------
  |  Branch (53:9): [Folded - Ignored]
  |  Branch (53:22): [Folded - Ignored]
  |  Branch (53:54): [Folded - Ignored]
  ------------------
   54|       |#ifdef ABORT_ON_FAILED_ASSUME
   55|       |        || true
   56|       |#endif
   57|    328|    ) {
   58|    328|        if (!val) {
  ------------------
  |  Branch (58:13): [True: 0, False: 328]
  ------------------
   59|      0|            assertion_fail(file, line, func, assertion);
   60|      0|        }
   61|    328|    }
   62|    328|    return std::forward<T>(val);
   63|    328|}
_Z22inline_assertion_checkILb1ERPKNSt3__18functionIFvNS0_4spanIKhLm18446744073709551615EEEEEEEOT0_SB_PKciSD_SD_:
   52|    328|{
   53|    328|    if (IS_ASSERT || std::is_constant_evaluated() || G_FUZZING
  ------------------
  |  Branch (53:9): [Folded - Ignored]
  |  Branch (53:22): [Folded - Ignored]
  |  Branch (53:54): [Folded - Ignored]
  ------------------
   54|       |#ifdef ABORT_ON_FAILED_ASSUME
   55|       |        || true
   56|       |#endif
   57|    328|    ) {
   58|    328|        if (!val) {
  ------------------
  |  Branch (58:13): [True: 0, False: 328]
  ------------------
   59|      0|            assertion_fail(file, line, func, assertion);
   60|      0|        }
   61|    328|    }
   62|    328|    return std::forward<T>(val);
   63|    328|}

_Z11SetMockTimeNSt3__16chrono8durationIxNS_5ratioILl1ELl1EEEEE:
   42|    328|{
   43|    328|    Assert(mock_time_in >= 0s);
  ------------------
  |  |   85|    328|#define Assert(val) inline_assertion_check<true>(val, __FILE__, __LINE__, __func__, #val)
  ------------------
   44|    328|    g_mock_time.store(mock_time_in, std::memory_order_relaxed);
   45|    328|}

