Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef BOOST_HASH2_SHA2_HPP_INCLUDED
0002 #define BOOST_HASH2_SHA2_HPP_INCLUDED
0003 
0004 // Copyright 2024 Peter Dimov.
0005 // Copyright 2024 Christian Mazakas.
0006 // Distributed under the Boost Software License, Version 1.0.
0007 // https://www.boost.org/LICENSE_1_0.txt
0008 //
0009 // SHA2 message digest algorithm, https://csrc.nist.gov/pubs/fips/180-4/upd1/final, https://www.rfc-editor.org/rfc/rfc6234
0010 
0011 #include <boost/hash2/hmac.hpp>
0012 #include <boost/hash2/digest.hpp>
0013 #include <boost/hash2/detail/read.hpp>
0014 #include <boost/hash2/detail/rot.hpp>
0015 #include <boost/hash2/detail/write.hpp>
0016 #include <boost/hash2/detail/memcpy.hpp>
0017 #include <boost/hash2/detail/memset.hpp>
0018 #include <boost/hash2/detail/is_constant_evaluated.hpp>
0019 #include <boost/assert.hpp>
0020 #include <array>
0021 #include <cstdint>
0022 #include <cstring>
0023 
0024 namespace boost
0025 {
0026 namespace hash2
0027 {
0028 
0029 namespace detail
0030 {
0031 
0032 template<class Word, class Algo, int M>
0033 struct sha2_base
0034 {
0035     Word state_[ 8 ] = {};
0036 
0037     static constexpr int N = M;
0038 
0039     unsigned char buffer_[ N ] = {};
0040     std::size_t m_ = 0; // == n_ % N
0041 
0042     std::uint64_t n_ = 0;
0043 
0044     constexpr sha2_base() = default;
0045 
0046     void update( void const* pv, std::size_t n )
0047     {
0048         unsigned char const* p = static_cast<unsigned char const*>( pv );
0049         update( p, n );
0050     }
0051 
0052     BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0053     {
0054 
0055         BOOST_ASSERT( m_ == n_ % N );
0056 
0057         n_ += n;
0058 
0059         if( m_ > 0 )
0060         {
0061             std::size_t k = N - m_;
0062 
0063             if( n < k )
0064             {
0065                 k = n;
0066             }
0067 
0068             detail::memcpy( buffer_ + m_, p, k );
0069 
0070             p += k;
0071             n -= k;
0072             m_ += k;
0073 
0074             if( m_ < N ) return;
0075 
0076             BOOST_ASSERT( m_ == N );
0077 
0078             Algo::transform( buffer_, state_ );
0079             m_ = 0;
0080 
0081             detail::memset( buffer_, 0, N );
0082         }
0083 
0084         BOOST_ASSERT( m_ == 0 );
0085 
0086         while( n >= N )
0087         {
0088             Algo::transform( p, state_ );
0089 
0090             p += N;
0091             n -= N;
0092         }
0093 
0094         BOOST_ASSERT( n < N );
0095 
0096         if( n > 0 )
0097         {
0098             detail::memcpy( buffer_, p, n );
0099             m_ = n;
0100         }
0101 
0102         BOOST_ASSERT( m_ == n_ % N );
0103     }
0104 };
0105 
0106 template<class = void>
0107 struct sha2_256_constants
0108 {
0109     constexpr static std::uint32_t const K[ 64 ] =
0110     {
0111         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0112         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0113         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0114         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0115         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0116         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0117         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0118         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
0119     };
0120 };
0121 
0122 template<class = void>
0123 struct sha2_512_constants
0124 {
0125     constexpr static std::uint64_t const K[ 80 ] =
0126     {
0127         0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
0128         0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
0129         0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
0130         0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
0131         0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
0132         0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
0133         0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
0134         0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
0135         0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
0136         0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
0137         0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
0138         0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
0139         0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
0140         0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
0141         0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0142         0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
0143         0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
0144         0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
0145         0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
0146         0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
0147     };
0148 };
0149 
0150 
0151 // copy-paste from Boost.Unordered's prime_fmod approach
0152 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0153 
0154 // https://en.cppreference.com/w/cpp/language/static#Constant_static_members
0155 // If a const non-inline (since C++17) static data member or a constexpr
0156 // static data member (since C++11)(until C++17) is odr-used, a definition
0157 // at namespace scope is still required, but it cannot have an
0158 // initializer.
0159 template<class T>
0160 constexpr std::uint32_t sha2_256_constants<T>::K[ 64 ];
0161 
0162 template<class  T>
0163 constexpr std::uint64_t sha2_512_constants<T>::K[ 80 ];
0164 
0165 #endif
0166 
0167 struct sha2_256_base : public sha2_base<std::uint32_t, sha2_256_base, 64>
0168 {
0169     BOOST_CXX14_CONSTEXPR static std::uint32_t Sigma0( std::uint32_t x ) noexcept
0170     {
0171         return detail::rotr( x, 2 ) ^ detail::rotr( x, 13 ) ^ detail::rotr( x, 22 );
0172     }
0173 
0174     BOOST_CXX14_CONSTEXPR static std::uint32_t Sigma1( std::uint32_t x ) noexcept
0175     {
0176         return detail::rotr( x, 6 ) ^ detail::rotr( x, 11 ) ^ detail::rotr( x, 25 );
0177     }
0178 
0179     BOOST_CXX14_CONSTEXPR static std::uint32_t sigma0( std::uint32_t x ) noexcept
0180     {
0181         return detail::rotr( x, 7 ) ^ detail::rotr( x, 18 ) ^ ( x >> 3 );
0182     }
0183 
0184     BOOST_CXX14_CONSTEXPR static std::uint32_t sigma1( std::uint32_t x ) noexcept
0185     {
0186         return detail::rotr( x, 17 ) ^ detail::rotr( x, 19 ) ^ ( x >> 10 );
0187     }
0188 
0189     BOOST_CXX14_CONSTEXPR static std::uint32_t Ch( std::uint32_t x, std::uint32_t y, std::uint32_t z ) noexcept
0190     {
0191         return ( x & y ) ^ ( ~x & z );
0192     }
0193 
0194     BOOST_CXX14_CONSTEXPR static std::uint32_t Maj( std::uint32_t x, std::uint32_t y, std::uint32_t z ) noexcept
0195     {
0196         return ( x & y ) ^ ( x & z ) ^ ( y & z );
0197     }
0198 
0199     BOOST_CXX14_CONSTEXPR static std::uint32_t W( std::uint32_t w[], int t )
0200     {
0201         return w[ t ] = ( sigma1( w[ t - 2 ] ) + w[ t - 7] + sigma0( w[ t - 15 ] ) + w[ t - 16 ] );
0202     }
0203 
0204     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static void R1( std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t& d,
0205                                                              std::uint32_t e, std::uint32_t f, std::uint32_t g, std::uint32_t& h,
0206                                                              unsigned char const block[ 64 ], std::uint32_t const* K, std::uint32_t w[], int t )
0207     {
0208         w[ t ] = detail::read32be( block + t * 4);
0209         std::uint32_t T1 = h + Sigma1( e ) + Ch( e, f, g ) + K[ t ] + w[ t ];
0210         std::uint32_t T2 = Sigma0( a ) + Maj( a, b, c );
0211 
0212         d += T1;
0213         h = T1 + T2;
0214     }
0215 
0216     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static void R2( std::uint32_t a, std::uint32_t b, std::uint32_t c, std::uint32_t& d,
0217                                                             std::uint32_t e, std::uint32_t f, std::uint32_t g, std::uint32_t& h,
0218                                                             unsigned char const block[ 64 ], std::uint32_t const* K, std::uint32_t w[], int t )
0219     {
0220         (void)block;
0221 
0222         std::uint32_t T1 = h + Sigma1( e ) + Ch( e, f, g ) + K[ t ] + W( w, t );
0223         std::uint32_t T2 = Sigma0( a ) + Maj( a, b, c );
0224 
0225         d += T1;
0226         h = T1 + T2;
0227     }
0228 
0229 
0230     BOOST_CXX14_CONSTEXPR static void transform( unsigned char const block[ 64 ], std::uint32_t state[ 8 ] )
0231     {
0232         auto K = sha2_256_constants<>::K;
0233 
0234         std::uint32_t w[ 64 ] = {};
0235 
0236         std::uint32_t a = state[ 0 ];
0237         std::uint32_t b = state[ 1 ];
0238         std::uint32_t c = state[ 2 ];
0239         std::uint32_t d = state[ 3 ];
0240         std::uint32_t e = state[ 4 ];
0241         std::uint32_t f = state[ 5 ];
0242         std::uint32_t g = state[ 6 ];
0243         std::uint32_t h = state[ 7 ];
0244 
0245         R1( a, b, c, d, e, f, g, h, block, K, w, 0 );
0246         R1( h, a, b, c, d, e, f, g, block, K, w, 1 );
0247         R1( g, h, a, b, c, d, e, f, block, K, w, 2 );
0248         R1( f, g, h, a, b, c, d, e, block, K, w, 3 );
0249         R1( e, f, g, h, a, b, c, d, block, K, w, 4 );
0250         R1( d, e, f, g, h, a, b, c, block, K, w, 5 );
0251         R1( c, d, e, f, g, h, a, b, block, K, w, 6 );
0252         R1( b, c, d, e, f, g, h, a, block, K, w, 7 );
0253 
0254         R1( a, b, c, d, e, f, g, h, block, K, w, 8 );
0255         R1( h, a, b, c, d, e, f, g, block, K, w, 9 );
0256         R1( g, h, a, b, c, d, e, f, block, K, w, 10 );
0257         R1( f, g, h, a, b, c, d, e, block, K, w, 11 );
0258         R1( e, f, g, h, a, b, c, d, block, K, w, 12 );
0259         R1( d, e, f, g, h, a, b, c, block, K, w, 13 );
0260         R1( c, d, e, f, g, h, a, b, block, K, w, 14 );
0261         R1( b, c, d, e, f, g, h, a, block, K, w, 15 );
0262 
0263         R2( a, b, c, d, e, f, g, h, block, K, w, 16 );
0264         R2( h, a, b, c, d, e, f, g, block, K, w, 17 );
0265         R2( g, h, a, b, c, d, e, f, block, K, w, 18 );
0266         R2( f, g, h, a, b, c, d, e, block, K, w, 19 );
0267         R2( e, f, g, h, a, b, c, d, block, K, w, 20 );
0268         R2( d, e, f, g, h, a, b, c, block, K, w, 21 );
0269         R2( c, d, e, f, g, h, a, b, block, K, w, 22 );
0270         R2( b, c, d, e, f, g, h, a, block, K, w, 23 );
0271 
0272         R2( a, b, c, d, e, f, g, h, block, K, w, 24 );
0273         R2( h, a, b, c, d, e, f, g, block, K, w, 25 );
0274         R2( g, h, a, b, c, d, e, f, block, K, w, 26 );
0275         R2( f, g, h, a, b, c, d, e, block, K, w, 27 );
0276         R2( e, f, g, h, a, b, c, d, block, K, w, 28 );
0277         R2( d, e, f, g, h, a, b, c, block, K, w, 29 );
0278         R2( c, d, e, f, g, h, a, b, block, K, w, 30 );
0279         R2( b, c, d, e, f, g, h, a, block, K, w, 31 );
0280 
0281         R2( a, b, c, d, e, f, g, h, block, K, w, 32 );
0282         R2( h, a, b, c, d, e, f, g, block, K, w, 33 );
0283         R2( g, h, a, b, c, d, e, f, block, K, w, 34 );
0284         R2( f, g, h, a, b, c, d, e, block, K, w, 35 );
0285         R2( e, f, g, h, a, b, c, d, block, K, w, 36 );
0286         R2( d, e, f, g, h, a, b, c, block, K, w, 37 );
0287         R2( c, d, e, f, g, h, a, b, block, K, w, 38 );
0288         R2( b, c, d, e, f, g, h, a, block, K, w, 39 );
0289 
0290         R2( a, b, c, d, e, f, g, h, block, K, w, 40 );
0291         R2( h, a, b, c, d, e, f, g, block, K, w, 41 );
0292         R2( g, h, a, b, c, d, e, f, block, K, w, 42 );
0293         R2( f, g, h, a, b, c, d, e, block, K, w, 43 );
0294         R2( e, f, g, h, a, b, c, d, block, K, w, 44 );
0295         R2( d, e, f, g, h, a, b, c, block, K, w, 45 );
0296         R2( c, d, e, f, g, h, a, b, block, K, w, 46 );
0297         R2( b, c, d, e, f, g, h, a, block, K, w, 47 );
0298 
0299         R2( a, b, c, d, e, f, g, h, block, K, w, 48 );
0300         R2( h, a, b, c, d, e, f, g, block, K, w, 49 );
0301         R2( g, h, a, b, c, d, e, f, block, K, w, 50 );
0302         R2( f, g, h, a, b, c, d, e, block, K, w, 51 );
0303         R2( e, f, g, h, a, b, c, d, block, K, w, 52 );
0304         R2( d, e, f, g, h, a, b, c, block, K, w, 53 );
0305         R2( c, d, e, f, g, h, a, b, block, K, w, 54 );
0306         R2( b, c, d, e, f, g, h, a, block, K, w, 55 );
0307 
0308         R2( a, b, c, d, e, f, g, h, block, K, w, 56 );
0309         R2( h, a, b, c, d, e, f, g, block, K, w, 57 );
0310         R2( g, h, a, b, c, d, e, f, block, K, w, 58 );
0311         R2( f, g, h, a, b, c, d, e, block, K, w, 59 );
0312         R2( e, f, g, h, a, b, c, d, block, K, w, 60 );
0313         R2( d, e, f, g, h, a, b, c, block, K, w, 61 );
0314         R2( c, d, e, f, g, h, a, b, block, K, w, 62 );
0315         R2( b, c, d, e, f, g, h, a, block, K, w, 63 );
0316 
0317         state[0] += a;
0318         state[1] += b;
0319         state[2] += c;
0320         state[3] += d;
0321         state[4] += e;
0322         state[5] += f;
0323         state[6] += g;
0324         state[7] += h;
0325     }
0326 };
0327 
0328 struct sha2_512_base : public sha2_base<std::uint64_t, sha2_512_base, 128>
0329 {
0330     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t Ch( std::uint64_t x, std::uint64_t y, std::uint64_t z ) noexcept
0331     {
0332         return ( x & y ) ^ ( ~x & z );
0333     }
0334 
0335     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t Maj( std::uint64_t x, std::uint64_t y, std::uint64_t z ) noexcept
0336     {
0337         return ( x & y ) ^ ( x & z ) ^ ( y & z );
0338     }
0339 
0340     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t Sigma0( std::uint64_t x ) noexcept
0341     {
0342         return detail::rotr( x, 28 ) ^ detail::rotr( x, 34 ) ^ detail::rotr( x, 39 );
0343     }
0344 
0345     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t Sigma1( std::uint64_t x ) noexcept
0346     {
0347         return detail::rotr( x, 14 ) ^ detail::rotr( x, 18 ) ^ detail::rotr( x, 41 );
0348     }
0349 
0350     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t sigma0( std::uint64_t x ) noexcept
0351     {
0352         return detail::rotr( x, 1 ) ^ detail::rotr( x, 8 ) ^ ( x >> 7 );
0353     }
0354 
0355     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t sigma1( std::uint64_t x ) noexcept
0356     {
0357         return detail::rotr( x, 19 ) ^ detail::rotr( x, 61 ) ^ ( x >> 6 );
0358     }
0359 
0360     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static std::uint64_t W( std::uint64_t w[], int t )
0361     {
0362         return w[ t ] = ( sigma1( w[ t - 2 ] ) + w[ t - 7] + sigma0( w[ t - 15 ] ) + w[ t - 16 ] );
0363     }
0364 
0365     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static void R1( std::uint64_t a, std::uint64_t b, std::uint64_t c, std::uint64_t& d,
0366                                                             std::uint64_t e, std::uint64_t f, std::uint64_t g, std::uint64_t& h,
0367                                                             unsigned char const block[ 64 ], std::uint64_t const* K, std::uint64_t w[], int t )
0368     {
0369         w[ t ] = detail::read64be( block + t * 8 );
0370         std::uint64_t T1 = h + Sigma1( e ) + Ch( e, f, g ) + K[ t ] + w[ t ];
0371         std::uint64_t T2 = Sigma0( a ) + Maj( a, b, c );
0372 
0373         d += T1;
0374         h = T1 + T2;
0375     }
0376 
0377     BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR static void R2( std::uint64_t a, std::uint64_t b, std::uint64_t c, std::uint64_t& d,
0378                                                             std::uint64_t e, std::uint64_t f, std::uint64_t g, std::uint64_t& h,
0379                                                             unsigned char const block[ 64 ], std::uint64_t const* K, std::uint64_t w[], int t )
0380     {
0381         (void)block;
0382 
0383         std::uint64_t T1 = h + Sigma1( e ) + Ch( e, f, g ) + K[ t ] + W( w, t );
0384         std::uint64_t T2 = Sigma0( a ) + Maj( a, b, c );
0385 
0386         d += T1;
0387         h = T1 + T2;
0388     }
0389 
0390     BOOST_CXX14_CONSTEXPR static void transform( unsigned char const block[ 128 ], std::uint64_t state[ 8 ] )
0391     {
0392         auto K = sha2_512_constants<>::K;
0393 
0394         std::uint64_t w[ 80 ] = {};
0395 
0396         std::uint64_t a = state[ 0 ];
0397         std::uint64_t b = state[ 1 ];
0398         std::uint64_t c = state[ 2 ];
0399         std::uint64_t d = state[ 3 ];
0400         std::uint64_t e = state[ 4 ];
0401         std::uint64_t f = state[ 5 ];
0402         std::uint64_t g = state[ 6 ];
0403         std::uint64_t h = state[ 7 ];
0404 
0405         R1( a, b, c, d, e, f, g, h, block, K, w, 0 );
0406         R1( h, a, b, c, d, e, f, g, block, K, w, 1 );
0407         R1( g, h, a, b, c, d, e, f, block, K, w, 2 );
0408         R1( f, g, h, a, b, c, d, e, block, K, w, 3 );
0409         R1( e, f, g, h, a, b, c, d, block, K, w, 4 );
0410         R1( d, e, f, g, h, a, b, c, block, K, w, 5 );
0411         R1( c, d, e, f, g, h, a, b, block, K, w, 6 );
0412         R1( b, c, d, e, f, g, h, a, block, K, w, 7 );
0413 
0414         R1( a, b, c, d, e, f, g, h, block, K, w, 8 );
0415         R1( h, a, b, c, d, e, f, g, block, K, w, 9 );
0416         R1( g, h, a, b, c, d, e, f, block, K, w, 10 );
0417         R1( f, g, h, a, b, c, d, e, block, K, w, 11 );
0418         R1( e, f, g, h, a, b, c, d, block, K, w, 12 );
0419         R1( d, e, f, g, h, a, b, c, block, K, w, 13 );
0420         R1( c, d, e, f, g, h, a, b, block, K, w, 14 );
0421         R1( b, c, d, e, f, g, h, a, block, K, w, 15 );
0422 
0423         R2( a, b, c, d, e, f, g, h, block, K, w, 16 );
0424         R2( h, a, b, c, d, e, f, g, block, K, w, 17 );
0425         R2( g, h, a, b, c, d, e, f, block, K, w, 18 );
0426         R2( f, g, h, a, b, c, d, e, block, K, w, 19 );
0427         R2( e, f, g, h, a, b, c, d, block, K, w, 20 );
0428         R2( d, e, f, g, h, a, b, c, block, K, w, 21 );
0429         R2( c, d, e, f, g, h, a, b, block, K, w, 22 );
0430         R2( b, c, d, e, f, g, h, a, block, K, w, 23 );
0431 
0432         R2( a, b, c, d, e, f, g, h, block, K, w, 24 );
0433         R2( h, a, b, c, d, e, f, g, block, K, w, 25 );
0434         R2( g, h, a, b, c, d, e, f, block, K, w, 26 );
0435         R2( f, g, h, a, b, c, d, e, block, K, w, 27 );
0436         R2( e, f, g, h, a, b, c, d, block, K, w, 28 );
0437         R2( d, e, f, g, h, a, b, c, block, K, w, 29 );
0438         R2( c, d, e, f, g, h, a, b, block, K, w, 30 );
0439         R2( b, c, d, e, f, g, h, a, block, K, w, 31 );
0440 
0441         R2( a, b, c, d, e, f, g, h, block, K, w, 32 );
0442         R2( h, a, b, c, d, e, f, g, block, K, w, 33 );
0443         R2( g, h, a, b, c, d, e, f, block, K, w, 34 );
0444         R2( f, g, h, a, b, c, d, e, block, K, w, 35 );
0445         R2( e, f, g, h, a, b, c, d, block, K, w, 36 );
0446         R2( d, e, f, g, h, a, b, c, block, K, w, 37 );
0447         R2( c, d, e, f, g, h, a, b, block, K, w, 38 );
0448         R2( b, c, d, e, f, g, h, a, block, K, w, 39 );
0449 
0450         R2( a, b, c, d, e, f, g, h, block, K, w, 40 );
0451         R2( h, a, b, c, d, e, f, g, block, K, w, 41 );
0452         R2( g, h, a, b, c, d, e, f, block, K, w, 42 );
0453         R2( f, g, h, a, b, c, d, e, block, K, w, 43 );
0454         R2( e, f, g, h, a, b, c, d, block, K, w, 44 );
0455         R2( d, e, f, g, h, a, b, c, block, K, w, 45 );
0456         R2( c, d, e, f, g, h, a, b, block, K, w, 46 );
0457         R2( b, c, d, e, f, g, h, a, block, K, w, 47 );
0458 
0459         R2( a, b, c, d, e, f, g, h, block, K, w, 48 );
0460         R2( h, a, b, c, d, e, f, g, block, K, w, 49 );
0461         R2( g, h, a, b, c, d, e, f, block, K, w, 50 );
0462         R2( f, g, h, a, b, c, d, e, block, K, w, 51 );
0463         R2( e, f, g, h, a, b, c, d, block, K, w, 52 );
0464         R2( d, e, f, g, h, a, b, c, block, K, w, 53 );
0465         R2( c, d, e, f, g, h, a, b, block, K, w, 54 );
0466         R2( b, c, d, e, f, g, h, a, block, K, w, 55 );
0467 
0468         R2( a, b, c, d, e, f, g, h, block, K, w, 56 );
0469         R2( h, a, b, c, d, e, f, g, block, K, w, 57 );
0470         R2( g, h, a, b, c, d, e, f, block, K, w, 58 );
0471         R2( f, g, h, a, b, c, d, e, block, K, w, 59 );
0472         R2( e, f, g, h, a, b, c, d, block, K, w, 60 );
0473         R2( d, e, f, g, h, a, b, c, block, K, w, 61 );
0474         R2( c, d, e, f, g, h, a, b, block, K, w, 62 );
0475         R2( b, c, d, e, f, g, h, a, block, K, w, 63 );
0476 
0477         R2( a, b, c, d, e, f, g, h, block, K, w, 64 );
0478         R2( h, a, b, c, d, e, f, g, block, K, w, 65 );
0479         R2( g, h, a, b, c, d, e, f, block, K, w, 66 );
0480         R2( f, g, h, a, b, c, d, e, block, K, w, 67 );
0481         R2( e, f, g, h, a, b, c, d, block, K, w, 68 );
0482         R2( d, e, f, g, h, a, b, c, block, K, w, 69 );
0483         R2( c, d, e, f, g, h, a, b, block, K, w, 70 );
0484         R2( b, c, d, e, f, g, h, a, block, K, w, 71 );
0485 
0486         R2( a, b, c, d, e, f, g, h, block, K, w, 72 );
0487         R2( h, a, b, c, d, e, f, g, block, K, w, 73 );
0488         R2( g, h, a, b, c, d, e, f, block, K, w, 74 );
0489         R2( f, g, h, a, b, c, d, e, block, K, w, 75 );
0490         R2( e, f, g, h, a, b, c, d, block, K, w, 76 );
0491         R2( d, e, f, g, h, a, b, c, block, K, w, 77 );
0492         R2( c, d, e, f, g, h, a, b, block, K, w, 78 );
0493         R2( b, c, d, e, f, g, h, a, block, K, w, 79 );
0494 
0495         state[ 0 ] += a;
0496         state[ 1 ] += b;
0497         state[ 2 ] += c;
0498         state[ 3 ] += d;
0499         state[ 4 ] += e;
0500         state[ 5 ] += f;
0501         state[ 6 ] += g;
0502         state[ 7 ] += h;
0503     }
0504 };
0505 
0506 } // namespace detail
0507 
0508 class sha2_256 : detail::sha2_256_base
0509 {
0510 private:
0511 
0512     BOOST_CXX14_CONSTEXPR void init()
0513     {
0514         state_[ 0 ] = 0x6a09e667;
0515         state_[ 1 ] = 0xbb67ae85;
0516         state_[ 2 ] = 0x3c6ef372;
0517         state_[ 3 ] = 0xa54ff53a;
0518         state_[ 4 ] = 0x510e527f;
0519         state_[ 5 ] = 0x9b05688c;
0520         state_[ 6 ] = 0x1f83d9ab;
0521         state_[ 7 ] = 0x5be0cd19;
0522     }
0523 
0524 public:
0525 
0526     using result_type = digest<32>;
0527 
0528     static constexpr std::size_t block_size = 64;
0529 
0530     BOOST_CXX14_CONSTEXPR sha2_256()
0531     {
0532         init();
0533     }
0534 
0535     BOOST_CXX14_CONSTEXPR explicit sha2_256( std::uint64_t seed )
0536     {
0537         init();
0538 
0539         if( seed != 0 )
0540         {
0541             unsigned char tmp[ 8 ] = {};
0542             detail::write64le( tmp, seed );
0543 
0544             update( tmp, 8 );
0545             result();
0546         }
0547     }
0548 
0549     BOOST_CXX14_CONSTEXPR sha2_256( unsigned char const * p, std::size_t n )
0550     {
0551         init();
0552 
0553         if( n != 0 )
0554         {
0555             update( p, n );
0556             result();
0557         }
0558     }
0559 
0560     sha2_256( void const * p, std::size_t n ): sha2_256( static_cast<unsigned char const*>( p ), n )
0561     {
0562     }
0563 
0564     using detail::sha2_256_base::update;
0565 
0566     BOOST_CXX14_CONSTEXPR result_type result()
0567     {
0568         unsigned char bits[ 8 ] = {};
0569         detail::write64be( bits, n_ * 8 );
0570 
0571         std::size_t k = m_ < 56 ? 56 - m_ : 64 + 56 - m_;
0572         unsigned char padding[ 64 ] = { 0x80 };
0573 
0574         update( padding, k );
0575         update( bits, 8 );
0576         BOOST_ASSERT( m_ == 0 );
0577 
0578         result_type digest;
0579         for( int i = 0; i < 8; ++i )
0580         {
0581             detail::write32be( &digest[ i * 4 ], state_[ i ] );
0582         }
0583 
0584         return digest;
0585     }
0586 };
0587 
0588 class sha2_224 : detail::sha2_256_base
0589 {
0590 private:
0591 
0592     BOOST_CXX14_CONSTEXPR void init()
0593     {
0594         state_[ 0 ] = 0xc1059ed8;
0595         state_[ 1 ] = 0x367cd507;
0596         state_[ 2 ] = 0x3070dd17;
0597         state_[ 3 ] = 0xf70e5939;
0598         state_[ 4 ] = 0xffc00b31;
0599         state_[ 5 ] = 0x68581511;
0600         state_[ 6 ] = 0x64f98fa7;
0601         state_[ 7 ] = 0xbefa4fa4;
0602     }
0603 
0604 public:
0605 
0606     using result_type = digest<28>;
0607 
0608     static constexpr std::size_t block_size = 64;
0609 
0610     BOOST_CXX14_CONSTEXPR sha2_224()
0611     {
0612         init();
0613     }
0614 
0615     BOOST_CXX14_CONSTEXPR explicit sha2_224( std::uint64_t seed )
0616     {
0617         init();
0618 
0619         if( seed != 0 )
0620         {
0621             unsigned char tmp[ 8 ] = {};
0622             detail::write64le( tmp, seed );
0623 
0624             update( tmp, 8 );
0625             result();
0626         }
0627     }
0628 
0629     BOOST_CXX14_CONSTEXPR sha2_224( unsigned char const * p, std::size_t n )
0630     {
0631         init();
0632 
0633         if( n != 0 )
0634         {
0635             update( p, n );
0636             result();
0637         }
0638     }
0639 
0640 
0641     sha2_224( void const * p, std::size_t n ): sha2_224( static_cast<unsigned char const*>( p ), n )
0642     {
0643     }
0644 
0645     using detail::sha2_256_base::update;
0646 
0647     BOOST_CXX14_CONSTEXPR result_type result()
0648     {
0649         unsigned char bits[ 8 ] = {};
0650         detail::write64be( bits, n_ * 8 );
0651 
0652         std::size_t k = m_ < 56 ? 56 - m_ : 64 + 56 - m_;
0653         unsigned char padding[ 64 ] = { 0x80 };
0654 
0655         update( padding, k );
0656         update( bits, 8 );
0657         BOOST_ASSERT( m_ == 0 );
0658 
0659         result_type digest;
0660         for( int i = 0; i < 7; ++i ) {
0661             detail::write32be( &digest[ i * 4 ], state_[ i ] );
0662         }
0663 
0664         return digest;
0665     }
0666 };
0667 
0668 class sha2_512 : detail::sha2_512_base
0669 {
0670 private:
0671 
0672     BOOST_CXX14_CONSTEXPR void init()
0673     {
0674         state_[ 0 ] = 0x6a09e667f3bcc908;
0675         state_[ 1 ] = 0xbb67ae8584caa73b;
0676         state_[ 2 ] = 0x3c6ef372fe94f82b;
0677         state_[ 3 ] = 0xa54ff53a5f1d36f1;
0678         state_[ 4 ] = 0x510e527fade682d1;
0679         state_[ 5 ] = 0x9b05688c2b3e6c1f;
0680         state_[ 6 ] = 0x1f83d9abfb41bd6b;
0681         state_[ 7 ] = 0x5be0cd19137e2179;
0682     }
0683 
0684 public:
0685 
0686     using result_type = digest<64>;
0687 
0688     using detail::sha2_512_base::update;
0689 
0690     static constexpr std::size_t block_size = 128;
0691 
0692     BOOST_CXX14_CONSTEXPR sha2_512()
0693     {
0694         init();
0695     }
0696 
0697     BOOST_CXX14_CONSTEXPR explicit sha2_512( std::uint64_t seed )
0698     {
0699         init();
0700 
0701         if( seed != 0 )
0702         {
0703             unsigned char tmp[ 8 ] = {};
0704             detail::write64le( tmp, seed );
0705 
0706             update( tmp, 8 );
0707             result();
0708         }
0709     }
0710 
0711     BOOST_CXX14_CONSTEXPR sha2_512( unsigned char const * p, std::size_t n )
0712     {
0713         init();
0714 
0715         if( n != 0 )
0716         {
0717             update( p, n );
0718             result();
0719         }
0720     }
0721 
0722     sha2_512( void const * p, std::size_t n ): sha2_512( static_cast<unsigned char const*>( p ), n )
0723     {
0724     }
0725 
0726     BOOST_CXX14_CONSTEXPR result_type result()
0727     {
0728         unsigned char bits[ 16 ] = { 0 };
0729         detail::write64be( bits + 8, n_ * 8 );
0730 
0731         std::size_t k = m_ < 112 ? 112 - m_ : 128 + 112 - m_;
0732         unsigned char padding[ 128 ] = { 0x80 };
0733 
0734         update( padding, k );
0735         update( bits, 16 );
0736         BOOST_ASSERT( m_ == 0 );
0737 
0738         result_type digest;
0739         for( int i = 0; i < 8; ++i )
0740         {
0741             detail::write64be( &digest[ i * 8 ], state_[ i ] );
0742         }
0743 
0744         return digest;
0745     }
0746 };
0747 
0748 class sha2_384 : detail::sha2_512_base
0749 {
0750 private:
0751 
0752     BOOST_CXX14_CONSTEXPR void init()
0753     {
0754         state_[ 0 ] = 0xcbbb9d5dc1059ed8;
0755         state_[ 1 ] = 0x629a292a367cd507;
0756         state_[ 2 ] = 0x9159015a3070dd17;
0757         state_[ 3 ] = 0x152fecd8f70e5939;
0758         state_[ 4 ] = 0x67332667ffc00b31;
0759         state_[ 5 ] = 0x8eb44a8768581511;
0760         state_[ 6 ] = 0xdb0c2e0d64f98fa7;
0761         state_[ 7 ] = 0x47b5481dbefa4fa4;
0762     }
0763 
0764 public:
0765 
0766     using result_type = digest<48>;
0767 
0768     static constexpr std::size_t block_size = 128;
0769 
0770     using detail::sha2_512_base::update;
0771 
0772     BOOST_CXX14_CONSTEXPR sha2_384()
0773     {
0774         init();
0775     }
0776 
0777     BOOST_CXX14_CONSTEXPR explicit sha2_384( std::uint64_t seed )
0778     {
0779         init();
0780 
0781         if( seed != 0 )
0782         {
0783             unsigned char tmp[ 8 ] = {};
0784             detail::write64le( tmp, seed );
0785 
0786             update( tmp, 8 );
0787             result();
0788         }
0789     }
0790 
0791     BOOST_CXX14_CONSTEXPR sha2_384( unsigned char const * p, std::size_t n )
0792     {
0793         init();
0794 
0795         if( n != 0 )
0796         {
0797             update( p, n );
0798             result();
0799         }
0800     }
0801 
0802     sha2_384( void const * p, std::size_t n ): sha2_384( static_cast<unsigned char const*>( p ), n )
0803     {
0804     }
0805 
0806     BOOST_CXX14_CONSTEXPR result_type result()
0807     {
0808         unsigned char bits[ 16 ] = { 0 };
0809         detail::write64be( bits + 8, n_ * 8 );
0810 
0811         std::size_t k = m_ < 112 ? 112 - m_ : 128 + 112 - m_;
0812         unsigned char padding[ 128 ] = { 0x80 };
0813 
0814         update( padding, k );
0815         update( bits, 16 );
0816         BOOST_ASSERT( m_ == 0 );
0817 
0818         result_type digest;
0819         for( int i = 0; i < 6; ++i )
0820         {
0821             detail::write64be( &digest[ i * 8 ], state_[ i ] );
0822         }
0823 
0824         return digest;
0825     }
0826 };
0827 
0828 class sha2_512_224 : detail::sha2_512_base
0829 {
0830 private:
0831 
0832     BOOST_CXX14_CONSTEXPR void init()
0833     {
0834         state_[ 0 ] = 0x8c3d37c819544da2;
0835         state_[ 1 ] = 0x73e1996689dcd4d6;
0836         state_[ 2 ] = 0x1dfab7ae32ff9c82;
0837         state_[ 3 ] = 0x679dd514582f9fcf;
0838         state_[ 4 ] = 0x0f6d2b697bd44da8;
0839         state_[ 5 ] = 0x77e36f7304c48942;
0840         state_[ 6 ] = 0x3f9d85a86a1d36c8;
0841         state_[ 7 ] = 0x1112e6ad91d692a1;
0842     }
0843 
0844 public:
0845 
0846     using result_type = digest<28>;
0847 
0848     static constexpr std::size_t block_size = 128;
0849 
0850     using detail::sha2_512_base::update;
0851 
0852     BOOST_CXX14_CONSTEXPR sha2_512_224()
0853     {
0854         init();
0855     }
0856 
0857     BOOST_CXX14_CONSTEXPR explicit sha2_512_224( std::uint64_t seed )
0858     {
0859         init();
0860 
0861         if( seed != 0 )
0862         {
0863             unsigned char tmp[ 8 ] = {};
0864             detail::write64le( tmp, seed );
0865 
0866             update( tmp, 8 );
0867             result();
0868         }
0869     }
0870 
0871     BOOST_CXX14_CONSTEXPR sha2_512_224( unsigned char const * p, std::size_t n )
0872     {
0873         init();
0874 
0875         if( n != 0 )
0876         {
0877             update( p, n );
0878             result();
0879         }
0880     }
0881 
0882 
0883     sha2_512_224( void const * p, std::size_t n ): sha2_512_224( static_cast<unsigned char const*>( p ), n )
0884     {
0885     }
0886 
0887     BOOST_CXX14_CONSTEXPR result_type result()
0888     {
0889         unsigned char bits[ 16 ] = { 0 };
0890         detail::write64be( bits + 8, n_ * 8 );
0891 
0892         std::size_t k = m_ < 112 ? 112 - m_ : 128 + 112 - m_;
0893         unsigned char padding[ 128 ] = { 0x80 };
0894 
0895         update( padding, k );
0896         update( bits, 16 );
0897         BOOST_ASSERT( m_ == 0 );
0898 
0899         result_type digest;
0900         for( int i = 0; i < 3; ++i )
0901         {
0902             detail::write64be( &digest[ i * 8 ], state_[ i ] );
0903         }
0904         detail::write32be( &digest[ 3 * 8 ], state_[ 3 ] >> 32 );
0905 
0906         return digest;
0907     }
0908 };
0909 
0910 class sha2_512_256 : detail::sha2_512_base
0911 {
0912 private:
0913 
0914     BOOST_CXX14_CONSTEXPR void init()
0915     {
0916         state_[ 0 ] = 0x22312194fc2bf72c;
0917         state_[ 1 ] = 0x9f555fa3c84c64c2;
0918         state_[ 2 ] = 0x2393b86b6f53b151;
0919         state_[ 3 ] = 0x963877195940eabd;
0920         state_[ 4 ] = 0x96283ee2a88effe3;
0921         state_[ 5 ] = 0xbe5e1e2553863992;
0922         state_[ 6 ] = 0x2b0199fc2c85b8aa;
0923         state_[ 7 ] = 0x0eb72ddc81c52ca2;
0924     }
0925 
0926 public:
0927 
0928     using result_type = digest<32>;
0929 
0930     static constexpr std::size_t block_size = 128;
0931 
0932     using detail::sha2_512_base::update;
0933 
0934     BOOST_CXX14_CONSTEXPR sha2_512_256()
0935     {
0936         init();
0937     }
0938 
0939     BOOST_CXX14_CONSTEXPR explicit sha2_512_256( std::uint64_t seed )
0940     {
0941         init();
0942 
0943         if( seed != 0 )
0944         {
0945             unsigned char tmp[ 8 ] = {};
0946             detail::write64le( tmp, seed );
0947 
0948             update( tmp, 8 );
0949             result();
0950         }
0951     }
0952 
0953     BOOST_CXX14_CONSTEXPR sha2_512_256( unsigned char const * p, std::size_t n )
0954     {
0955         init();
0956 
0957         if( n != 0 )
0958         {
0959             update( p, n );
0960             result();
0961         }
0962     }
0963 
0964     sha2_512_256( void const * p, std::size_t n ): sha2_512_256( static_cast<unsigned char const*>( p ), n )
0965     {
0966     }
0967 
0968     BOOST_CXX14_CONSTEXPR result_type result()
0969     {
0970         unsigned char bits[ 16 ] = { 0 };
0971         detail::write64be( bits + 8, n_ * 8 );
0972 
0973         std::size_t k = m_ < 112 ? 112 - m_ : 128 + 112 - m_;
0974         unsigned char padding[ 128 ] = { 0x80 };
0975 
0976         update( padding, k );
0977         update( bits, 16 );
0978         BOOST_ASSERT( m_ == 0 );
0979 
0980         result_type digest;
0981         for( int i = 0; i < 4; ++i )
0982         {
0983             detail::write64be( &digest[ i * 8 ], state_[ i ] );
0984         }
0985 
0986         return digest;
0987     }
0988 };
0989 
0990 // hmac wrappers
0991 
0992 using hmac_sha2_256 = hmac<sha2_256>;
0993 using hmac_sha2_224 = hmac<sha2_224>;
0994 using hmac_sha2_512 = hmac<sha2_512>;
0995 using hmac_sha2_384 = hmac<sha2_384>;
0996 using hmac_sha2_512_224 = hmac<sha2_512_224>;
0997 using hmac_sha2_512_256 = hmac<sha2_512_256>;
0998 
0999 } // namespace hash2
1000 } // namespace boost
1001 
1002 #endif // #ifndef BOOST_HASH2_SHA2_HPP_INCLUDED