File indexing completed on 2025-09-17 08:33:43
0001 #ifndef BOOST_HASH2_HMAC_HPP_INCLUDED
0002 #define BOOST_HASH2_HMAC_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010 #include <boost/hash2/detail/write.hpp>
0011 #include <boost/hash2/detail/memcpy.hpp>
0012 #include <boost/assert.hpp>
0013 #include <boost/config.hpp>
0014 #include <boost/config/workaround.hpp>
0015 #include <cstdint>
0016 #include <cstring>
0017 #include <cstddef>
0018
0019 #if !defined(BOOST_NO_CXX14_CONSTEXPR) && !BOOST_WORKAROUND(BOOST_GCC, < 60000)
0020
0021 # define BOOST_HASH2_HMAC_CONSTEXPR constexpr
0022
0023 #else
0024
0025
0026
0027
0028
0029 # define BOOST_HASH2_HMAC_CONSTEXPR
0030
0031 #endif
0032
0033 namespace boost
0034 {
0035 namespace hash2
0036 {
0037
0038 template<class H> class hmac
0039 {
0040 public:
0041
0042 using result_type = typename H::result_type;
0043 static constexpr std::size_t block_size = H::block_size;
0044
0045 private:
0046
0047 H outer_;
0048 H inner_;
0049
0050 private:
0051
0052 BOOST_HASH2_HMAC_CONSTEXPR void init( unsigned char const* p, std::size_t n )
0053 {
0054 constexpr std::size_t m = block_size;
0055
0056 unsigned char key[ m ] = {};
0057
0058 if( n == 0 )
0059 {
0060
0061 }
0062 else if( n <= m )
0063 {
0064 detail::memcpy( key, p, n );
0065 }
0066 else
0067 {
0068 H h;
0069 h.update( p, n );
0070
0071 result_type r = h.result();
0072
0073 detail::memcpy( key, &r[0], m < r.size()? m: r.size() );
0074 }
0075
0076 for( std::size_t i = 0; i < m; ++i )
0077 {
0078 key[ i ] = static_cast<unsigned char>( key[ i ] ^ 0x36 );
0079 }
0080
0081 inner_.update( key, m );
0082
0083 for( std::size_t i = 0; i < m; ++i )
0084 {
0085 key[ i ] = static_cast<unsigned char>( key[ i ] ^ 0x36 ^ 0x5C );
0086 }
0087
0088 outer_.update( key, m );
0089 }
0090
0091 public:
0092
0093 BOOST_HASH2_HMAC_CONSTEXPR hmac()
0094 {
0095 init( 0, 0 );
0096 }
0097
0098 explicit BOOST_HASH2_HMAC_CONSTEXPR hmac( std::uint64_t seed )
0099 {
0100 if( seed == 0 )
0101 {
0102 init( 0, 0 );
0103 }
0104 else
0105 {
0106 unsigned char tmp[ 8 ] = {};
0107 detail::write64le( tmp, seed );
0108
0109 init( tmp, 8 );
0110 }
0111 }
0112
0113 BOOST_HASH2_HMAC_CONSTEXPR hmac( unsigned char const* p, std::size_t n )
0114 {
0115 init( p, n );
0116 }
0117
0118 hmac( void const* p, std::size_t n )
0119 {
0120 init( static_cast<unsigned char const*>( p ), n );
0121 }
0122
0123 BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0124 {
0125 inner_.update( p, n );
0126 }
0127
0128 void update( void const* pv, std::size_t n )
0129 {
0130 inner_.update( pv, n );
0131 }
0132
0133 BOOST_CXX14_CONSTEXPR result_type result()
0134 {
0135 result_type r = inner_.result();
0136
0137 outer_.update( &r[0], r.size() );
0138
0139 return outer_.result();
0140 }
0141 };
0142
0143 }
0144 }
0145
0146 #endif