Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef BOOST_HASH2_SHA1_HPP_INCLUDED
0002 #define BOOST_HASH2_SHA1_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 // SHA1 message digest algorithm, https://tools.ietf.org/html/rfc3174
0009 
0010 #include <boost/hash2/hmac.hpp>
0011 #include <boost/hash2/digest.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/assert.hpp>
0018 #include <boost/config.hpp>
0019 #include <cstdint>
0020 #include <array>
0021 #include <cstring>
0022 #include <cstddef>
0023 
0024 namespace boost
0025 {
0026 namespace hash2
0027 {
0028 
0029 class sha1_160
0030 {
0031 private:
0032 
0033     std::uint32_t state_[ 5 ] = { 0x67452301u, 0xefcdab89u, 0x98badcfeu, 0x10325476u, 0xc3d2e1f0u };
0034 
0035     static constexpr int N = 64;
0036 
0037     unsigned char buffer_[ N ] = {};
0038     std::size_t m_ = 0; // == n_ % N
0039 
0040     std::uint64_t n_ = 0;
0041 
0042 private:
0043 
0044     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R1( std::uint32_t a, std::uint32_t & b, std::uint32_t c, std::uint32_t d, std::uint32_t & e, std::uint32_t w[], unsigned char const block[ 64 ], int i )
0045     {
0046         w[ i ] = detail::read32be( block + i * 4 );
0047 
0048         std::uint32_t f = (b & c) | (~b & d);
0049 
0050         e += detail::rotl( a, 5 ) + f + 0x5A827999 + w[ i ];
0051         b = detail::rotl( b, 30 );
0052     }
0053 
0054     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t W( std::uint32_t w[], int i )
0055     {
0056         return w[ i ] = detail::rotl( w[ i - 3 ] ^ w[ i - 8 ] ^ w[ i - 14 ] ^ w[ i - 16 ], 1 );
0057     }
0058 
0059     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R2( std::uint32_t a, std::uint32_t & b, std::uint32_t c, std::uint32_t d, std::uint32_t & e, std::uint32_t w[], int i )
0060     {
0061         std::uint32_t f = (b & c) | (~b & d);
0062 
0063         e += detail::rotl( a, 5 ) + f + 0x5A827999 + W( w, i );
0064         b = detail::rotl( b, 30 );
0065     }
0066 
0067     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R3( std::uint32_t a, std::uint32_t & b, std::uint32_t c, std::uint32_t d, std::uint32_t & e, std::uint32_t w[], int i )
0068     {
0069         std::uint32_t f = b ^ c ^ d;
0070 
0071         e += detail::rotl( a, 5 ) + f + 0x6ED9EBA1 + W( w, i );
0072         b = detail::rotl( b, 30 );
0073     }
0074 
0075     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R4( std::uint32_t a, std::uint32_t & b, std::uint32_t c, std::uint32_t d, std::uint32_t & e, std::uint32_t w[], int i )
0076     {
0077         std::uint32_t f = (b & c) | (b & d) | (c & d);
0078 
0079         e += detail::rotl( a, 5 ) + f + 0x8F1BBCDC + W( w, i );
0080         b = detail::rotl( b, 30 );
0081     }
0082 
0083     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void R5( std::uint32_t a, std::uint32_t & b, std::uint32_t c, std::uint32_t d, std::uint32_t & e, std::uint32_t w[], int i )
0084     {
0085         std::uint32_t f = b ^ c ^ d;
0086 
0087         e += detail::rotl( a, 5 ) + f + 0xCA62C1D6 + W( w, i );
0088         b = detail::rotl( b, 30 );
0089     }
0090 
0091     BOOST_CXX14_CONSTEXPR void transform( unsigned char const block[ 64 ] )
0092     {
0093         std::uint32_t a = state_[ 0 ];
0094         std::uint32_t b = state_[ 1 ];
0095         std::uint32_t c = state_[ 2 ];
0096         std::uint32_t d = state_[ 3 ];
0097         std::uint32_t e = state_[ 4 ];
0098 
0099         std::uint32_t w[ 80 ] = {};
0100 
0101         R1( a, b, c, d, e, w, block,  0 );
0102         R1( e, a, b, c, d, w, block,  1 );
0103         R1( d, e, a, b, c, w, block,  2 );
0104         R1( c, d, e, a, b, w, block,  3 );
0105         R1( b, c, d, e, a, w, block,  4 );
0106         R1( a, b, c, d, e, w, block,  5 );
0107         R1( e, a, b, c, d, w, block,  6 );
0108         R1( d, e, a, b, c, w, block,  7 );
0109         R1( c, d, e, a, b, w, block,  8 );
0110         R1( b, c, d, e, a, w, block,  9 );
0111         R1( a, b, c, d, e, w, block, 10 );
0112         R1( e, a, b, c, d, w, block, 11 );
0113         R1( d, e, a, b, c, w, block, 12 );
0114         R1( c, d, e, a, b, w, block, 13 );
0115         R1( b, c, d, e, a, w, block, 14 );
0116         R1( a, b, c, d, e, w, block, 15 );
0117 
0118         R2( e, a, b, c, d, w, 16 );
0119         R2( d, e, a, b, c, w, 17 );
0120         R2( c, d, e, a, b, w, 18 );
0121         R2( b, c, d, e, a, w, 19 );
0122 
0123         R3( a, b, c, d, e, w, 20 );
0124         R3( e, a, b, c, d, w, 21 );
0125         R3( d, e, a, b, c, w, 22 );
0126         R3( c, d, e, a, b, w, 23 );
0127         R3( b, c, d, e, a, w, 24 );
0128         R3( a, b, c, d, e, w, 25 );
0129         R3( e, a, b, c, d, w, 26 );
0130         R3( d, e, a, b, c, w, 27 );
0131         R3( c, d, e, a, b, w, 28 );
0132         R3( b, c, d, e, a, w, 29 );
0133         R3( a, b, c, d, e, w, 30 );
0134         R3( e, a, b, c, d, w, 31 );
0135         R3( d, e, a, b, c, w, 32 );
0136         R3( c, d, e, a, b, w, 33 );
0137         R3( b, c, d, e, a, w, 34 );
0138         R3( a, b, c, d, e, w, 35 );
0139         R3( e, a, b, c, d, w, 36 );
0140         R3( d, e, a, b, c, w, 37 );
0141         R3( c, d, e, a, b, w, 38 );
0142         R3( b, c, d, e, a, w, 39 );
0143 
0144         R4( a, b, c, d, e, w, 40 );
0145         R4( e, a, b, c, d, w, 41 );
0146         R4( d, e, a, b, c, w, 42 );
0147         R4( c, d, e, a, b, w, 43 );
0148         R4( b, c, d, e, a, w, 44 );
0149         R4( a, b, c, d, e, w, 45 );
0150         R4( e, a, b, c, d, w, 46 );
0151         R4( d, e, a, b, c, w, 47 );
0152         R4( c, d, e, a, b, w, 48 );
0153         R4( b, c, d, e, a, w, 49 );
0154         R4( a, b, c, d, e, w, 50 );
0155         R4( e, a, b, c, d, w, 51 );
0156         R4( d, e, a, b, c, w, 52 );
0157         R4( c, d, e, a, b, w, 53 );
0158         R4( b, c, d, e, a, w, 54 );
0159         R4( a, b, c, d, e, w, 55 );
0160         R4( e, a, b, c, d, w, 56 );
0161         R4( d, e, a, b, c, w, 57 );
0162         R4( c, d, e, a, b, w, 58 );
0163         R4( b, c, d, e, a, w, 59 );
0164 
0165         R5( a, b, c, d, e, w, 60 );
0166         R5( e, a, b, c, d, w, 61 );
0167         R5( d, e, a, b, c, w, 62 );
0168         R5( c, d, e, a, b, w, 63 );
0169         R5( b, c, d, e, a, w, 64 );
0170         R5( a, b, c, d, e, w, 65 );
0171         R5( e, a, b, c, d, w, 66 );
0172         R5( d, e, a, b, c, w, 67 );
0173         R5( c, d, e, a, b, w, 68 );
0174         R5( b, c, d, e, a, w, 69 );
0175         R5( a, b, c, d, e, w, 70 );
0176         R5( e, a, b, c, d, w, 71 );
0177         R5( d, e, a, b, c, w, 72 );
0178         R5( c, d, e, a, b, w, 73 );
0179         R5( b, c, d, e, a, w, 74 );
0180         R5( a, b, c, d, e, w, 75 );
0181         R5( e, a, b, c, d, w, 76 );
0182         R5( d, e, a, b, c, w, 77 );
0183         R5( c, d, e, a, b, w, 78 );
0184         R5( b, c, d, e, a, w, 79 );
0185 
0186         state_[ 0 ] += a;
0187         state_[ 1 ] += b;
0188         state_[ 2 ] += c;
0189         state_[ 3 ] += d;
0190         state_[ 4 ] += e;
0191     }
0192 
0193 public:
0194 
0195     typedef digest<20> result_type;
0196 
0197     static constexpr std::size_t block_size = 64;
0198 
0199     sha1_160() = default;
0200 
0201     explicit BOOST_CXX14_CONSTEXPR sha1_160( std::uint64_t seed )
0202     {
0203         if( seed != 0 )
0204         {
0205             unsigned char tmp[ 8 ] = {};
0206             detail::write64le( tmp, seed );
0207 
0208             update( tmp, 8 );
0209             result();
0210         }
0211     }
0212 
0213     BOOST_CXX14_CONSTEXPR sha1_160( unsigned char const * p, std::size_t n )
0214     {
0215         if( n != 0 )
0216         {
0217             update( p, n );
0218             result();
0219         }
0220     }
0221 
0222     sha1_160( void const * p, std::size_t n ): sha1_160( static_cast<unsigned char const*>( p ), n )
0223     {
0224     }
0225 
0226     BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0227     {
0228         BOOST_ASSERT( m_ == n_ % N );
0229 
0230         if( n == 0 ) return;
0231 
0232         n_ += n;
0233 
0234         if( m_ > 0 )
0235         {
0236             std::size_t k = N - m_;
0237 
0238             if( n < k )
0239             {
0240                 k = n;
0241             }
0242 
0243             detail::memcpy( buffer_ + m_, p, k );
0244 
0245             p += k;
0246             n -= k;
0247             m_ += k;
0248 
0249             if( m_ < N ) return;
0250 
0251             BOOST_ASSERT( m_ == N );
0252 
0253             transform( buffer_ );
0254             m_ = 0;
0255 
0256             detail::memset( buffer_, 0, N );
0257         }
0258 
0259         BOOST_ASSERT( m_ == 0 );
0260 
0261         while( n >= N )
0262         {
0263             transform( p );
0264 
0265             p += N;
0266             n -= N;
0267         }
0268 
0269         BOOST_ASSERT( n < N );
0270 
0271         if( n > 0 )
0272         {
0273             detail::memcpy( buffer_, p, n );
0274             m_ = n;
0275         }
0276 
0277         BOOST_ASSERT( m_ == n_ % N );
0278     }
0279 
0280     void update( void const* pv, std::size_t n )
0281     {
0282         unsigned char const* p = static_cast<unsigned char const*>( pv );
0283         update( p, n );
0284     }
0285 
0286     BOOST_CXX14_CONSTEXPR result_type result()
0287     {
0288         BOOST_ASSERT( m_ == n_ % N );
0289 
0290         unsigned char bits[ 8 ] = {};
0291 
0292         detail::write64be( bits, n_ * 8 );
0293 
0294         std::size_t k = m_ < 56? 56 - m_: 120 - m_;
0295 
0296         unsigned char padding[ 64 ] = { 0x80 };
0297 
0298         update( padding, k );
0299 
0300         update( bits, 8 );
0301 
0302         BOOST_ASSERT( m_ == 0 );
0303 
0304         result_type digest;
0305 
0306         for( int i = 0; i < 5; ++i )
0307         {
0308             detail::write32be( digest.data() + i * 4, state_[ i ] );
0309         }
0310 
0311         return digest;
0312     }
0313 };
0314 
0315 using hmac_sha1_160 = hmac<sha1_160>;
0316 
0317 } // namespace hash2
0318 } // namespace boost
0319 
0320 #endif // #ifndef BOOST_HASH2_SHA1_HPP_INCLUDED