File indexing completed on 2025-01-18 09:29:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #ifndef BOOST_BEAST_CORE_DETAIL_CHACHA_HPP
0034 #define BOOST_BEAST_CORE_DETAIL_CHACHA_HPP
0035
0036 #include <cstdint>
0037 #include <limits>
0038
0039 namespace boost {
0040 namespace beast {
0041 namespace detail {
0042
0043 template<std::size_t R>
0044 class chacha
0045 {
0046 alignas(16) std::uint32_t block_[16];
0047 std::uint32_t keysetup_[8];
0048 std::uint64_t ctr_ = 0;
0049 int idx_ = 16;
0050
0051 void generate_block()
0052 {
0053 std::uint32_t constexpr constants[4] = {
0054 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 };
0055 std::uint32_t input[16];
0056 for (int i = 0; i < 4; ++i)
0057 input[i] = constants[i];
0058 for (int i = 0; i < 8; ++i)
0059 input[4 + i] = keysetup_[i];
0060 input[12] = (ctr_ / 16) & 0xffffffffu;
0061 input[13] = (ctr_ / 16) >> 32;
0062 input[14] = input[15] = 0xdeadbeef;
0063 for (int i = 0; i < 16; ++i)
0064 block_[i] = input[i];
0065 chacha_core();
0066 for (int i = 0; i < 16; ++i)
0067 block_[i] += input[i];
0068 }
0069
0070 void chacha_core()
0071 {
0072 #define BOOST_BEAST_CHACHA_ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
0073
0074 #define BOOST_BEAST_CHACHA_QUARTERROUND(x, a, b, c, d) \
0075 x[a] = x[a] + x[b]; x[d] ^= x[a]; x[d] = BOOST_BEAST_CHACHA_ROTL32(x[d], 16); \
0076 x[c] = x[c] + x[d]; x[b] ^= x[c]; x[b] = BOOST_BEAST_CHACHA_ROTL32(x[b], 12); \
0077 x[a] = x[a] + x[b]; x[d] ^= x[a]; x[d] = BOOST_BEAST_CHACHA_ROTL32(x[d], 8); \
0078 x[c] = x[c] + x[d]; x[b] ^= x[c]; x[b] = BOOST_BEAST_CHACHA_ROTL32(x[b], 7)
0079
0080 for (unsigned i = 0; i < R; i += 2)
0081 {
0082 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 0, 4, 8, 12);
0083 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 1, 5, 9, 13);
0084 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 2, 6, 10, 14);
0085 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 3, 7, 11, 15);
0086 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 0, 5, 10, 15);
0087 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 1, 6, 11, 12);
0088 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 2, 7, 8, 13);
0089 BOOST_BEAST_CHACHA_QUARTERROUND(block_, 3, 4, 9, 14);
0090 }
0091
0092 #undef BOOST_BEAST_CHACHA_QUARTERROUND
0093 #undef BOOST_BEAST_CHACHA_ROTL32
0094 }
0095
0096 public:
0097 static constexpr std::size_t state_size = sizeof(chacha::keysetup_);
0098
0099 using result_type = std::uint32_t;
0100
0101 chacha(std::uint32_t const* v, std::uint64_t stream)
0102 {
0103 for (int i = 0; i < 6; ++i)
0104 keysetup_[i] = v[i];
0105 keysetup_[6] = v[6] + (stream & 0xffffffff);
0106 keysetup_[7] = v[7] + ((stream >> 32) & 0xffffffff);
0107 }
0108
0109 std::uint32_t
0110 operator()()
0111 {
0112 if(idx_ == 16)
0113 {
0114 idx_ = 0;
0115 ++ctr_;
0116 generate_block();
0117 }
0118 return block_[idx_++];
0119 }
0120 };
0121
0122 }
0123 }
0124 }
0125
0126 #endif