123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- //
- // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/beast
- //
- //
- // This is a derivative work, original copyright follows:
- //
- /*
- Copyright (c) 2015 Orson Peters <orsonpeters@gmail.com>
-
- This software is provided 'as-is', without any express or implied warranty. In no event will the
- authors be held liable for any damages arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose, including commercial
- applications, and to alter it and redistribute it freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the
- original software. If you use this software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as
- being the original software.
-
- 3. This notice may not be removed or altered from any source distribution.
- */
- #ifndef BHO_BEAST_CORE_DETAIL_CHACHA_HPP
- #define BHO_BEAST_CORE_DETAIL_CHACHA_HPP
- #include <cstdint>
- #include <limits>
- namespace bho {
- namespace beast {
- namespace detail {
- template<std::size_t R>
- class chacha
- {
- alignas(16) std::uint32_t block_[16];
- std::uint32_t keysetup_[8];
- std::uint64_t ctr_ = 0;
- int idx_ = 16;
- void generate_block()
- {
- std::uint32_t constexpr constants[4] = {
- 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574 };
- std::uint32_t input[16];
- for (int i = 0; i < 4; ++i)
- input[i] = constants[i];
- for (int i = 0; i < 8; ++i)
- input[4 + i] = keysetup_[i];
- input[12] = (ctr_ / 16) & 0xffffffffu;
- input[13] = (ctr_ / 16) >> 32;
- input[14] = input[15] = 0xdeadbeef; // Could use 128-bit counter.
- for (int i = 0; i < 16; ++i)
- block_[i] = input[i];
- chacha_core();
- for (int i = 0; i < 16; ++i)
- block_[i] += input[i];
- }
- void chacha_core()
- {
- #define BHO_BEAST_CHACHA_ROTL32(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
- #define BHO_BEAST_CHACHA_QUARTERROUND(x, a, b, c, d) \
- x[a] = x[a] + x[b]; x[d] ^= x[a]; x[d] = BHO_BEAST_CHACHA_ROTL32(x[d], 16); \
- x[c] = x[c] + x[d]; x[b] ^= x[c]; x[b] = BHO_BEAST_CHACHA_ROTL32(x[b], 12); \
- x[a] = x[a] + x[b]; x[d] ^= x[a]; x[d] = BHO_BEAST_CHACHA_ROTL32(x[d], 8); \
- x[c] = x[c] + x[d]; x[b] ^= x[c]; x[b] = BHO_BEAST_CHACHA_ROTL32(x[b], 7)
- for (unsigned i = 0; i < R; i += 2)
- {
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 0, 4, 8, 12);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 1, 5, 9, 13);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 2, 6, 10, 14);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 3, 7, 11, 15);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 0, 5, 10, 15);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 1, 6, 11, 12);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 2, 7, 8, 13);
- BHO_BEAST_CHACHA_QUARTERROUND(block_, 3, 4, 9, 14);
- }
- #undef BHO_BEAST_CHACHA_QUARTERROUND
- #undef BHO_BEAST_CHACHA_ROTL32
- }
- public:
- static constexpr std::size_t state_size = sizeof(chacha::keysetup_);
- using result_type = std::uint32_t;
- chacha(std::uint32_t const* v, std::uint64_t stream)
- {
- for (int i = 0; i < 6; ++i)
- keysetup_[i] = v[i];
- keysetup_[6] = v[6] + (stream & 0xffffffff);
- keysetup_[7] = v[7] + ((stream >> 32) & 0xffffffff);
- }
- std::uint32_t
- operator()()
- {
- if(idx_ == 16)
- {
- idx_ = 0;
- ++ctr_;
- generate_block();
- }
- return block_[idx_++];
- }
- };
- } // detail
- } // beast
- } // bho
- #endif
|