File indexing completed on 2025-09-17 08:33:42
0001 #ifndef BOOST_HASH2_DETAIL_KECCAK_HPP_INCLUDED
0002 #define BOOST_HASH2_DETAIL_KECCAK_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/hash2/detail/read.hpp>
0010 #include <boost/hash2/detail/rot.hpp>
0011 #include <boost/hash2/detail/write.hpp>
0012 #include <boost/config.hpp>
0013 #include <boost/config/workaround.hpp>
0014
0015 #include <cstdint>
0016
0017 #if BOOST_WORKAROUND(BOOST_GCC, >= 50000 && BOOST_GCC < 60000)
0018 #define BOOST_HASH2_SHA3_CONSTEXPR
0019 #else
0020 #define BOOST_HASH2_SHA3_CONSTEXPR BOOST_CXX14_CONSTEXPR
0021 #endif
0022
0023 namespace boost
0024 {
0025 namespace hash2
0026 {
0027 namespace detail
0028 {
0029
0030 BOOST_FORCEINLINE BOOST_HASH2_SHA3_CONSTEXPR std::uint64_t read_lane( unsigned char const (&state)[ 200 ], int x, int y )
0031 {
0032 return detail::read64le( state + ( x + 5 * y ) * 8 );
0033 }
0034
0035 BOOST_FORCEINLINE BOOST_HASH2_SHA3_CONSTEXPR void write_lane( unsigned char (&state)[ 200 ], int x, int y, std::uint64_t v )
0036 {
0037 detail::write64le( state + ( x + 5 * y ) * 8, v );
0038 }
0039
0040 BOOST_FORCEINLINE BOOST_HASH2_SHA3_CONSTEXPR void xor_lane( unsigned char (&state)[ 200 ], int x, int y, std::uint64_t v )
0041 {
0042 write_lane( state, x, y, read_lane( state, x, y ) ^ v );
0043 }
0044
0045 BOOST_FORCEINLINE BOOST_HASH2_SHA3_CONSTEXPR void rho_and_pi_round( unsigned char (&state)[ 200 ], std::uint64_t& lane, int rot, int x, int y )
0046 {
0047 std::uint64_t temp = read_lane( state, x, y );
0048 write_lane( state, x, y, detail::rotl( lane, rot ) );
0049 lane = temp;
0050 }
0051
0052 inline BOOST_HASH2_SHA3_CONSTEXPR void keccak_round( unsigned char (&state)[ 200 ] )
0053 {
0054 {
0055
0056
0057 std::uint64_t const C1[ 5 ] =
0058 {
0059
0060
0061 read_lane( state, 0, 0 ) ^ read_lane( state, 0, 1 ) ^ read_lane( state, 0, 2 ) ^ read_lane( state, 0, 3 ) ^ read_lane( state, 0, 4 ),
0062 read_lane( state, 1, 0 ) ^ read_lane( state, 1, 1 ) ^ read_lane( state, 1, 2 ) ^ read_lane( state, 1, 3 ) ^ read_lane( state, 1, 4 ),
0063 read_lane( state, 2, 0 ) ^ read_lane( state, 2, 1 ) ^ read_lane( state, 2, 2 ) ^ read_lane( state, 2, 3 ) ^ read_lane( state, 2, 4 ),
0064 read_lane( state, 3, 0 ) ^ read_lane( state, 3, 1 ) ^ read_lane( state, 3, 2 ) ^ read_lane( state, 3, 3 ) ^ read_lane( state, 3, 4 ),
0065 read_lane( state, 4, 0 ) ^ read_lane( state, 4, 1 ) ^ read_lane( state, 4, 2 ) ^ read_lane( state, 4, 3 ) ^ read_lane( state, 4, 4 ),
0066 };
0067
0068 std::uint64_t const C2[ 5 ] =
0069 {
0070
0071
0072 detail::rotl( C1[ 0 ], 1 ),
0073 detail::rotl( C1[ 1 ], 1 ),
0074 detail::rotl( C1[ 2 ], 1 ),
0075 detail::rotl( C1[ 3 ], 1 ),
0076 detail::rotl( C1[ 4 ], 1 ),
0077 };
0078
0079 for( int y = 0; y < 5; ++y )
0080 {
0081
0082
0083
0084
0085
0086 xor_lane( state, 0, y, C1[ 4 ] ^ C2[ 1 ] );
0087 xor_lane( state, 1, y, C1[ 0 ] ^ C2[ 2 ] );
0088 xor_lane( state, 2, y, C1[ 1 ] ^ C2[ 3 ] );
0089 xor_lane( state, 3, y, C1[ 2 ] ^ C2[ 4 ] );
0090 xor_lane( state, 4, y, C1[ 3 ] ^ C2[ 0 ] );
0091 }
0092 }
0093
0094 {
0095
0096
0097 std::uint64_t lane = read_lane( state, 1, 0 );
0098
0099 rho_and_pi_round( state, lane, 1, 0, 2 );
0100 rho_and_pi_round( state, lane, 3, 2, 1 );
0101 rho_and_pi_round( state, lane, 6, 1, 2 );
0102 rho_and_pi_round( state, lane, 10, 2, 3 );
0103 rho_and_pi_round( state, lane, 15, 3, 3 );
0104 rho_and_pi_round( state, lane, 21, 3, 0 );
0105 rho_and_pi_round( state, lane, 28, 0, 1 );
0106 rho_and_pi_round( state, lane, 36, 1, 3 );
0107 rho_and_pi_round( state, lane, 45, 3, 1 );
0108 rho_and_pi_round( state, lane, 55, 1, 4 );
0109 rho_and_pi_round( state, lane, 2, 4, 4 );
0110 rho_and_pi_round( state, lane, 14, 4, 0 );
0111 rho_and_pi_round( state, lane, 27, 0, 3 );
0112 rho_and_pi_round( state, lane, 41, 3, 4 );
0113 rho_and_pi_round( state, lane, 56, 4, 3 );
0114 rho_and_pi_round( state, lane, 8, 3, 2 );
0115 rho_and_pi_round( state, lane, 25, 2, 2 );
0116 rho_and_pi_round( state, lane, 43, 2, 0 );
0117 rho_and_pi_round( state, lane, 62, 0, 4 );
0118 rho_and_pi_round( state, lane, 18, 4, 2 );
0119 rho_and_pi_round( state, lane, 39, 2, 4 );
0120 rho_and_pi_round( state, lane, 61, 4, 1 );
0121 rho_and_pi_round( state, lane, 20, 1, 1 );
0122 rho_and_pi_round( state, lane, 44, 1, 0 );
0123 }
0124
0125 {
0126
0127
0128 for( int y = 0; y < 5; ++y )
0129 {
0130 std::uint64_t const plane[ 5 ] =
0131 {
0132 read_lane( state, 0, y ),
0133 read_lane( state, 1, y ),
0134 read_lane( state, 2, y ),
0135 read_lane( state, 3, y ),
0136 read_lane( state, 4, y ),
0137 };
0138
0139
0140
0141 write_lane( state, 0, y, plane[ 0 ] ^ ( ~plane[ 1 ] & plane[ 2 ] ) );
0142 write_lane( state, 1, y, plane[ 1 ] ^ ( ~plane[ 2 ] & plane[ 3 ] ) );
0143 write_lane( state, 2, y, plane[ 2 ] ^ ( ~plane[ 3 ] & plane[ 4 ] ) );
0144 write_lane( state, 3, y, plane[ 3 ] ^ ( ~plane[ 4 ] & plane[ 0 ] ) );
0145 write_lane( state, 4, y, plane[ 4 ] ^ ( ~plane[ 0 ] & plane[ 1 ] ) );
0146 }
0147 }
0148 }
0149
0150 template<class = void> struct iota_rc_holder
0151 {
0152 static constexpr std::uint64_t data[ 24 ] =
0153 {
0154 0x0000000000000001ull, 0x0000000000008082ull, 0x800000000000808aull,
0155 0x8000000080008000ull, 0x000000000000808bull, 0x0000000080000001ull,
0156 0x8000000080008081ull, 0x8000000000008009ull, 0x000000000000008aull,
0157 0x0000000000000088ull, 0x0000000080008009ull, 0x000000008000000aull,
0158 0x000000008000808bull, 0x800000000000008bull, 0x8000000000008089ull,
0159 0x8000000000008003ull, 0x8000000000008002ull, 0x8000000000000080ull,
0160 0x000000000000800aull, 0x800000008000000aull, 0x8000000080008081ull,
0161 0x8000000000008080ull, 0x0000000080000001ull, 0x8000000080008008ull,
0162 };
0163 };
0164
0165 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0166
0167 template<class T> constexpr std::uint64_t iota_rc_holder<T>::data[ 24 ];
0168
0169 #endif
0170
0171 inline BOOST_HASH2_SHA3_CONSTEXPR void keccak_permute( unsigned char (&state)[ 200 ] )
0172 {
0173 for( int i = 0; i < 24; ++i )
0174 {
0175 keccak_round( state );
0176 xor_lane( state, 0, 0, iota_rc_holder<>::data[ i ] );
0177 }
0178 }
0179
0180 }
0181 }
0182 }
0183
0184
0185 #endif