Back to home page

EIC code displayed by LXR

 
 

    


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 // Copyright 2025 Christian Mazakas
0005 // Copyright 2025 Peter Dimov
0006 // Distributed under the Boost Software License, Version 1.0.
0007 // https://www.boost.org/LICENSE_1_0.txt
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         // theta
0056 
0057         std::uint64_t const C1[ 5 ] =
0058         {
0059             // state[ x ] ^ state[ x + 5 ] ^ state[ x + 10 ] ^ state[ x + 15 ] ^ state[ x + 20 ]
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             // detail::rotl( C1[ x ], 1 )
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             // for( int x = 0; x < 5; ++x )
0082             // {
0083             //     state[ 5 * y + x ] ^= C1[ ( x + 4 ) % 5] ^ C2[ ( x + 1 ) % 5 ];
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         // rho and pi fused
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         // chi
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             // state[ 5 * y + x ] = plane[ x ] ^ ( ( ~plane[ ( x + 1 ) % 5 ] ) & plane[ ( x + 2 ) % 5 ] );
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 } // namespace detail
0181 } // namespace hash2
0182 } // namespace boost
0183 
0184 
0185 #endif // BOOST_HASH2_DETAIL_KECCAK_HPP_INCLUDED