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
0005
0006
0007
0008
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;
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 }
0318 }
0319
0320 #endif