Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:33:43

0001 #ifndef BOOST_HASH2_MD5_HPP_INCLUDED
0002 #define BOOST_HASH2_MD5_HPP_INCLUDED
0003 
0004 // Copyright 2017, 2018 Peter Dimov.
0005 // Distributed under the Boost Software License, Version 1.0.
0006 // https://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // MD5 message digest algorithm, https://tools.ietf.org/html/rfc1321
0009 
0010 #include <boost/hash2/digest.hpp>
0011 #include <boost/hash2/hmac.hpp>
0012 #include <boost/hash2/detail/read.hpp>
0013 #include <boost/hash2/detail/write.hpp>
0014 #include <boost/hash2/detail/rot.hpp>
0015 #include <boost/hash2/detail/memcpy.hpp>
0016 #include <boost/hash2/detail/memset.hpp>
0017 #include <boost/hash2/detail/config.hpp>
0018 #include <boost/assert.hpp>
0019 #include <boost/config.hpp>
0020 #include <cstdint>
0021 #include <array>
0022 #include <cstring>
0023 #include <cstddef>
0024 
0025 namespace boost
0026 {
0027 namespace hash2
0028 {
0029 
0030 class md5_128
0031 {
0032 private:
0033 
0034     std::uint32_t state_[ 4 ] = { 0x67452301u, 0xefcdab89u, 0x98badcfeu, 0x10325476u };
0035 
0036     static constexpr int N = 64;
0037 
0038     unsigned char buffer_[ N ] = {};
0039     std::size_t m_ = 0; // == n_ % N
0040 
0041     std::uint64_t n_ = 0;
0042 
0043 private:
0044 
0045     static BOOST_FORCEINLINE constexpr std::uint32_t F( std::uint32_t x, std::uint32_t y, std::uint32_t z )
0046     {
0047         return (x & y) | (~x & z);
0048     }
0049 
0050     static BOOST_FORCEINLINE constexpr std::uint32_t G( std::uint32_t x, std::uint32_t y, std::uint32_t z )
0051     {
0052         return (x & z) | (y & ~z);
0053     }
0054 
0055     static BOOST_FORCEINLINE constexpr std::uint32_t H( std::uint32_t x, std::uint32_t y, std::uint32_t z )
0056     {
0057         return x ^ y ^ z;
0058     }
0059 
0060     static BOOST_FORCEINLINE constexpr std::uint32_t I( std::uint32_t x, std::uint32_t y, std::uint32_t z )
0061     {
0062         return y ^ (x | ~z);
0063     }
0064 
0065     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void FF( std::uint32_t & a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, int s, std::uint32_t ac )
0066     {
0067         a += F( b, c, d ) + x + ac;
0068         a = detail::rotl( a, s );
0069         a += b;
0070     }
0071 
0072     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void GG( std::uint32_t & a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, int s, std::uint32_t ac )
0073     {
0074         a += G( b, c, d ) + x + ac;
0075         a = detail::rotl( a, s );
0076         a += b;
0077     }
0078 
0079     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void HH( std::uint32_t & a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, int s, std::uint32_t ac )
0080     {
0081         a += H( b, c, d ) + x + ac;
0082         a = detail::rotl( a, s );
0083         a += b;
0084     }
0085 
0086     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void II( std::uint32_t & a, std::uint32_t b, std::uint32_t c, std::uint32_t d, std::uint32_t x, int s, std::uint32_t ac )
0087     {
0088         a += I( b, c, d ) + x + ac;
0089         a = detail::rotl( a, s );
0090         a += b;
0091     }
0092 
0093     static constexpr int S11 = 7;
0094     static constexpr int S12 = 12;
0095     static constexpr int S13 = 17;
0096     static constexpr int S14 = 22;
0097     static constexpr int S21 = 5;
0098     static constexpr int S22 = 9;
0099     static constexpr int S23 = 14;
0100     static constexpr int S24 = 20;
0101     static constexpr int S31 = 4;
0102     static constexpr int S32 = 11;
0103     static constexpr int S33 = 16;
0104     static constexpr int S34 = 23;
0105     static constexpr int S41 = 6;
0106     static constexpr int S42 = 10;
0107     static constexpr int S43 = 15;
0108     static constexpr int S44 = 21;
0109 
0110     BOOST_CXX14_CONSTEXPR void transform( unsigned char const block[ 64 ] )
0111     {
0112         std::uint32_t a = state_[ 0 ];
0113         std::uint32_t b = state_[ 1 ];
0114         std::uint32_t c = state_[ 2 ];
0115         std::uint32_t d = state_[ 3 ];
0116 
0117         std::uint32_t x[ 16 ] = {};
0118 
0119         for( int i = 0; i < 16; ++i )
0120         {
0121             x[ i ] = detail::read32le( block + i * 4 );
0122         }
0123 
0124         FF( a, b, c, d, x[ 0], S11, 0xd76aa478 );
0125         FF( d, a, b, c, x[ 1], S12, 0xe8c7b756 );
0126         FF( c, d, a, b, x[ 2], S13, 0x242070db );
0127         FF( b, c, d, a, x[ 3], S14, 0xc1bdceee );
0128         FF( a, b, c, d, x[ 4], S11, 0xf57c0faf );
0129         FF( d, a, b, c, x[ 5], S12, 0x4787c62a );
0130         FF( c, d, a, b, x[ 6], S13, 0xa8304613 );
0131         FF( b, c, d, a, x[ 7], S14, 0xfd469501 );
0132         FF( a, b, c, d, x[ 8], S11, 0x698098d8 );
0133         FF( d, a, b, c, x[ 9], S12, 0x8b44f7af );
0134         FF( c, d, a, b, x[10], S13, 0xffff5bb1 );
0135         FF( b, c, d, a, x[11], S14, 0x895cd7be );
0136         FF( a, b, c, d, x[12], S11, 0x6b901122 );
0137         FF( d, a, b, c, x[13], S12, 0xfd987193 );
0138         FF( c, d, a, b, x[14], S13, 0xa679438e );
0139         FF( b, c, d, a, x[15], S14, 0x49b40821 );
0140 
0141         GG( a, b, c, d, x[ 1], S21, 0xf61e2562 );
0142         GG( d, a, b, c, x[ 6], S22, 0xc040b340 );
0143         GG( c, d, a, b, x[11], S23, 0x265e5a51 );
0144         GG( b, c, d, a, x[ 0], S24, 0xe9b6c7aa );
0145         GG( a, b, c, d, x[ 5], S21, 0xd62f105d );
0146         GG( d, a, b, c, x[10], S22,  0x2441453 );
0147         GG( c, d, a, b, x[15], S23, 0xd8a1e681 );
0148         GG( b, c, d, a, x[ 4], S24, 0xe7d3fbc8 );
0149         GG( a, b, c, d, x[ 9], S21, 0x21e1cde6 );
0150         GG( d, a, b, c, x[14], S22, 0xc33707d6 );
0151         GG( c, d, a, b, x[ 3], S23, 0xf4d50d87 );
0152         GG( b, c, d, a, x[ 8], S24, 0x455a14ed );
0153         GG( a, b, c, d, x[13], S21, 0xa9e3e905 );
0154         GG( d, a, b, c, x[ 2], S22, 0xfcefa3f8 );
0155         GG( c, d, a, b, x[ 7], S23, 0x676f02d9 );
0156         GG( b, c, d, a, x[12], S24, 0x8d2a4c8a );
0157 
0158         HH( a, b, c, d, x[ 5], S31, 0xfffa3942 );
0159         HH( d, a, b, c, x[ 8], S32, 0x8771f681 );
0160         HH( c, d, a, b, x[11], S33, 0x6d9d6122 );
0161         HH( b, c, d, a, x[14], S34, 0xfde5380c );
0162         HH( a, b, c, d, x[ 1], S31, 0xa4beea44 );
0163         HH( d, a, b, c, x[ 4], S32, 0x4bdecfa9 );
0164         HH( c, d, a, b, x[ 7], S33, 0xf6bb4b60 );
0165         HH( b, c, d, a, x[10], S34, 0xbebfbc70 );
0166         HH( a, b, c, d, x[13], S31, 0x289b7ec6 );
0167         HH( d, a, b, c, x[ 0], S32, 0xeaa127fa );
0168         HH( c, d, a, b, x[ 3], S33, 0xd4ef3085 );
0169         HH( b, c, d, a, x[ 6], S34,  0x4881d05 );
0170         HH( a, b, c, d, x[ 9], S31, 0xd9d4d039 );
0171         HH( d, a, b, c, x[12], S32, 0xe6db99e5 );
0172         HH( c, d, a, b, x[15], S33, 0x1fa27cf8 );
0173         HH( b, c, d, a, x[ 2], S34, 0xc4ac5665 );
0174 
0175         II( a, b, c, d, x[ 0], S41, 0xf4292244 );
0176         II( d, a, b, c, x[ 7], S42, 0x432aff97 );
0177         II( c, d, a, b, x[14], S43, 0xab9423a7 );
0178         II( b, c, d, a, x[ 5], S44, 0xfc93a039 );
0179         II( a, b, c, d, x[12], S41, 0x655b59c3 );
0180         II( d, a, b, c, x[ 3], S42, 0x8f0ccc92 );
0181         II( c, d, a, b, x[10], S43, 0xffeff47d );
0182         II( b, c, d, a, x[ 1], S44, 0x85845dd1 );
0183         II( a, b, c, d, x[ 8], S41, 0x6fa87e4f );
0184         II( d, a, b, c, x[15], S42, 0xfe2ce6e0 );
0185         II( c, d, a, b, x[ 6], S43, 0xa3014314 );
0186         II( b, c, d, a, x[13], S44, 0x4e0811a1 );
0187         II( a, b, c, d, x[ 4], S41, 0xf7537e82 );
0188         II( d, a, b, c, x[11], S42, 0xbd3af235 );
0189         II( c, d, a, b, x[ 2], S43, 0x2ad7d2bb );
0190         II( b, c, d, a, x[ 9], S44, 0xeb86d391 );
0191 
0192         state_[ 0 ] += a;
0193         state_[ 1 ] += b;
0194         state_[ 2 ] += c;
0195         state_[ 3 ] += d;
0196     }
0197 
0198 public:
0199 
0200     using result_type = digest<16>;
0201 
0202     static constexpr std::size_t block_size = 64;
0203 
0204     md5_128() = default;
0205 
0206     BOOST_CXX14_CONSTEXPR explicit md5_128( std::uint64_t seed )
0207     {
0208         if( seed != 0 )
0209         {
0210             unsigned char tmp[ 8 ] = {};
0211             detail::write64le( tmp, seed );
0212 
0213             update( tmp, 8 );
0214             result();
0215         }
0216     }
0217 
0218     BOOST_CXX14_CONSTEXPR md5_128( unsigned char const * p, std::size_t n )
0219     {
0220         if( n != 0 )
0221         {
0222             update( p, n );
0223             result();
0224         }
0225     }
0226 
0227     md5_128( void const * p, std::size_t n ): md5_128( static_cast<unsigned char const*>( p ), n )
0228     {
0229     }
0230 
0231     BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0232     {
0233         BOOST_ASSERT( m_ == n_ % N );
0234 
0235         if( n == 0 ) return;
0236 
0237         n_ += n;
0238 
0239         if( m_ > 0 )
0240         {
0241             std::size_t k = N - m_;
0242 
0243             if( n < k )
0244             {
0245                 k = n;
0246             }
0247 
0248             detail::memcpy( buffer_ + m_, p, k );
0249 
0250             p += k;
0251             n -= k;
0252             m_ += k;
0253 
0254             if( m_ < N ) return;
0255 
0256             BOOST_ASSERT( m_ == N );
0257 
0258             transform( buffer_ );
0259             m_ = 0;
0260 
0261             detail::memset( buffer_, 0, N );
0262         }
0263 
0264         BOOST_ASSERT( m_ == 0 );
0265 
0266         while( n >= N )
0267         {
0268             transform( p );
0269 
0270             p += N;
0271             n -= N;
0272         }
0273 
0274         BOOST_ASSERT( n < N );
0275 
0276         if( n > 0 )
0277         {
0278             detail::memcpy( buffer_, p, n );
0279             m_ = n;
0280         }
0281 
0282         BOOST_ASSERT( m_ == n_ % N );
0283     }
0284 
0285     void update( void const* pv, std::size_t n )
0286     {
0287         unsigned char const* p = static_cast<unsigned char const*>( pv );
0288         update( p, n );
0289     }
0290 
0291     BOOST_CXX14_CONSTEXPR result_type result()
0292     {
0293         BOOST_ASSERT( m_ == n_ % N );
0294 
0295         unsigned char bits[ 8 ] = {};
0296 
0297         detail::write64le( bits, n_ * 8 );
0298 
0299         std::size_t k = m_ < 56? 56 - m_: 120 - m_;
0300 
0301         unsigned char padding[ 64 ] = { 0x80 };
0302 
0303         update( padding, k );
0304 
0305         update( bits, 8 );
0306 
0307         BOOST_ASSERT( m_ == 0 );
0308 
0309         result_type digest = {{}};
0310 
0311         for( int i = 0; i < 4; ++i )
0312         {
0313             detail::write32le( digest.data() + i * 4, state_[ i ] );
0314         }
0315 
0316         return digest;
0317     }
0318 };
0319 
0320 using hmac_md5_128 = hmac<md5_128>;
0321 
0322 } // namespace hash2
0323 } // namespace boost
0324 
0325 #endif // #ifndef BOOST_HASH2_MD5_HPP_INCLUDED