Warning, file /include/boost/uuid/detail/chacha20.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 #ifndef BOOST_UUID_DETAIL_CHACHA20_HPP_INCLUDED
0002 #define BOOST_UUID_DETAIL_CHACHA20_HPP_INCLUDED
0003
0004
0005
0006
0007
0008 #include <limits>
0009 #include <cstdint>
0010 #include <cstddef>
0011
0012 namespace boost {
0013 namespace uuids {
0014 namespace detail {
0015
0016 class chacha20_12
0017 {
0018 private:
0019
0020 std::uint32_t state_[ 16 ];
0021 std::uint32_t block_[ 16 ];
0022 std::size_t index_;
0023
0024 private:
0025
0026 static inline std::uint32_t rotl( std::uint32_t x, int n ) noexcept
0027 {
0028 return ( x << n ) | ( x >> (32 - n) );
0029 }
0030
0031 static inline void quarter_round( std::uint32_t (&x)[ 16 ], int a, int b, int c, int d ) noexcept
0032 {
0033 x[ a ] += x[ b ]; x[ d ] = rotl( x[d] ^ x[a], 16 );
0034 x[ c ] += x[ d ]; x[ b ] = rotl( x[b] ^ x[c], 12 );
0035 x[ a ] += x[ b ]; x[ d ] = rotl( x[d] ^ x[a], 8 );
0036 x[ c ] += x[ d ]; x[ b ] = rotl( x[b] ^ x[c], 7 );
0037 }
0038
0039 void get_next_block() noexcept
0040 {
0041 for( int i = 0; i < 16; ++i )
0042 {
0043 block_[ i ] = state_[ i ];
0044 }
0045
0046 for( int i = 0; i < 6; ++i )
0047 {
0048 quarter_round( block_, 0, 4, 8, 12 );
0049 quarter_round( block_, 1, 5, 9, 13 );
0050 quarter_round( block_, 2, 6, 10, 14 );
0051 quarter_round( block_, 3, 7, 11, 15 );
0052 quarter_round( block_, 0, 5, 10, 15 );
0053 quarter_round( block_, 1, 6, 11, 12 );
0054 quarter_round( block_, 2, 7, 8, 13 );
0055 quarter_round( block_, 3, 4, 9, 14 );
0056 }
0057
0058 for( int i = 0; i < 16; ++i )
0059 {
0060 block_[ i ] += state_[ i ];
0061 }
0062
0063 if( ++state_[ 12 ] == 0 ) ++state_[ 13 ];
0064 }
0065
0066 public:
0067
0068 using result_type = std::uint32_t;
0069
0070 chacha20_12() noexcept: index_( 16 )
0071 {
0072 state_[ 0 ] = 0x61707865;
0073 state_[ 1 ] = 0x3320646e;
0074 state_[ 2 ] = 0x79622d32;
0075 state_[ 3 ] = 0x6b206574;
0076
0077 for( int i = 4; i < 16; ++i )
0078 {
0079 state_[ i ] = 0;
0080 }
0081 }
0082
0083 chacha20_12( std::uint32_t const (&key)[ 8 ], std::uint32_t const (&nonce)[ 2 ] ) noexcept: index_( 16 )
0084 {
0085 state_[ 0 ] = 0x61707865;
0086 state_[ 1 ] = 0x3320646e;
0087 state_[ 2 ] = 0x79622d32;
0088 state_[ 3 ] = 0x6b206574;
0089
0090 for( int i = 0; i < 8; ++i )
0091 {
0092 state_[ i + 4 ] = key[ i ];
0093 }
0094
0095 state_[ 12 ] = 0;
0096 state_[ 13 ] = 0;
0097
0098 state_[ 14 ] = nonce[ 0 ];
0099 state_[ 15 ] = nonce[ 1 ];
0100 }
0101
0102
0103 void seed() noexcept
0104 {
0105 index_ = 16;
0106
0107 for( int i = 4; i < 16; ++i )
0108 {
0109 state_[ i ] = 0;
0110 }
0111 }
0112
0113 template<class Seq> void seed( Seq& seq )
0114 {
0115 index_ = 16;
0116
0117 seq.generate( state_ + 4, state_ + 16 );
0118
0119
0120 state_[ 12 ] = 0;
0121 state_[ 13 ] = 0;
0122 }
0123
0124
0125
0126 void perturb() noexcept
0127 {
0128 index_ = 16;
0129
0130 for( int i = 12; i < 16; ++i )
0131 {
0132 ++state_[ i ];
0133 }
0134 }
0135
0136 static constexpr result_type min() noexcept
0137 {
0138 return std::numeric_limits<result_type>::min();
0139 }
0140
0141 static constexpr result_type max() noexcept
0142 {
0143 return std::numeric_limits<result_type>::max();
0144 }
0145
0146 result_type operator()() noexcept
0147 {
0148 if( index_ == 16 )
0149 {
0150 get_next_block();
0151 index_ = 0;
0152 }
0153
0154 return block_[ index_++ ];
0155 }
0156 };
0157
0158 }}}
0159
0160 #endif