Back to home page

EIC code displayed by LXR

 
 

    


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

0001 #ifndef BOOST_HASH2_RIPEMD_HPP_INCLUDED
0002 #define BOOST_HASH2_RIPEMD_HPP_INCLUDED
0003 
0004 // Copyright 2017, 2018 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 // RIPEMD-160 message digest algorithm, https://www.esat.kuleuven.be/cosic/publications/article-317.pdf
0010 //                                      https://homes.esat.kuleuven.be/~bosselae/ripemd/rmd160.c
0011 //                                      https://homes.esat.kuleuven.be/~bosselae/ripemd/rmd160.h
0012 // RIPEMD-128 message digest algorithm, https://homes.esat.kuleuven.be/~bosselae/ripemd/rmd128.txt
0013 //                                      https://homes.esat.kuleuven.be/~bosselae/ripemd/rmd128.c
0014 //                                      https://homes.esat.kuleuven.be/~bosselae/ripemd/rmd128.h
0015 
0016 #include <boost/hash2/hmac.hpp>
0017 #include <boost/hash2/digest.hpp>
0018 #include <boost/hash2/detail/read.hpp>
0019 #include <boost/hash2/detail/write.hpp>
0020 #include <boost/hash2/detail/rot.hpp>
0021 #include <boost/hash2/detail/memset.hpp>
0022 #include <boost/assert.hpp>
0023 #include <boost/config.hpp>
0024 #include <cstdint>
0025 #include <cstring>
0026 #include <cstddef>
0027 
0028 namespace boost
0029 {
0030 namespace hash2
0031 {
0032 
0033 class ripemd_128
0034 {
0035 private:
0036 
0037     std::uint32_t state_[ 4 ] = { 0x67452301u, 0xEFCDAB89u, 0x98BADCFEu, 0x10325476u };
0038 
0039     static constexpr int N = 64;
0040 
0041     unsigned char buffer_[ N ] = {};
0042     std::size_t m_ = 0; // == n_ % N
0043 
0044     std::uint64_t n_ = 0;
0045 
0046 private:
0047 
0048     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F1( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ y ^ z; }
0049     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F2( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & y) | (~x & z); }
0050     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F3( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x | ~y) ^ z; }
0051     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F4( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & z) | (y & ~z); }
0052 
0053     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 x, std::uint32_t s )
0054     {
0055         a += F1(b, c, d) + x;
0056         a = detail::rotl(a, s);
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 x, std::uint32_t s )
0060     {
0061         a += F2(b, c, d) + x + 0x5a827999u;
0062         a = detail::rotl(a, s);
0063     }
0064 
0065     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 x, std::uint32_t s )
0066     {
0067         a += F3(b, c, d) + x + 0x6ed9eba1u;
0068         a = detail::rotl(a, s);
0069     }
0070 
0071     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 x, std::uint32_t s )
0072     {
0073         a += F4(b, c, d) + x + 0x8f1bbcdcu;
0074         a = detail::rotl(a, s);
0075     }
0076 
0077     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR1( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t x, std::uint32_t s )
0078     {
0079         a += F4(b, c, d) + x + 0x50a28be6u;
0080         a = detail::rotl(a, s);
0081     }
0082 
0083     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR2( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t x, std::uint32_t s )
0084     {
0085         a += F3(b, c, d) + x + 0x5c4dd124u;
0086         a = detail::rotl(a, s);
0087     }
0088 
0089     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR3( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t x, std::uint32_t s )
0090     {
0091         a += F2(b, c, d) + x + 0x6d703ef3u;
0092         a = detail::rotl(a, s);
0093     }
0094 
0095     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR4( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t x, std::uint32_t s )
0096     {
0097         a += F1(b, c, d) + x;
0098         a = detail::rotl(a, s);
0099     }
0100 
0101     BOOST_CXX14_CONSTEXPR void transform( unsigned char const block[ 64 ] )
0102     {
0103         std::uint32_t aa = state_[ 0 ];
0104         std::uint32_t bb = state_[ 1 ];
0105         std::uint32_t cc = state_[ 2 ];
0106         std::uint32_t dd = state_[ 3 ];
0107 
0108         std::uint32_t aaa = state_[ 0 ];
0109         std::uint32_t bbb = state_[ 1 ];
0110         std::uint32_t ccc = state_[ 2 ];
0111         std::uint32_t ddd = state_[ 3 ];
0112 
0113         std::uint32_t X[ 16 ] = {};
0114 
0115         for( int i = 0; i < 16; ++i )
0116         {
0117             X[ i ] = detail::read32le( block + i * 4 );
0118         }
0119 
0120         //  A   B   C   D
0121         R1(aa, bb, cc, dd, X[ 0], 11);
0122         R1(dd, aa, bb, cc, X[ 1], 14);
0123         R1(cc, dd, aa, bb, X[ 2], 15);
0124         R1(bb, cc, dd, aa, X[ 3], 12);
0125         R1(aa, bb, cc, dd, X[ 4],  5);
0126         R1(dd, aa, bb, cc, X[ 5],  8);
0127         R1(cc, dd, aa, bb, X[ 6],  7);
0128         R1(bb, cc, dd, aa, X[ 7],  9);
0129         R1(aa, bb, cc, dd, X[ 8], 11);
0130         R1(dd, aa, bb, cc, X[ 9], 13);
0131         R1(cc, dd, aa, bb, X[10], 14);
0132         R1(bb, cc, dd, aa, X[11], 15);
0133         R1(aa, bb, cc, dd, X[12],  6);
0134         R1(dd, aa, bb, cc, X[13],  7);
0135         R1(cc, dd, aa, bb, X[14],  9);
0136         R1(bb, cc, dd, aa, X[15],  8);
0137 
0138         RR1(aaa, bbb, ccc, ddd, X[ 5],  8);
0139         RR1(ddd, aaa, bbb, ccc, X[14],  9);
0140         RR1(ccc, ddd, aaa, bbb, X[ 7],  9);
0141         RR1(bbb, ccc, ddd, aaa, X[ 0], 11);
0142         RR1(aaa, bbb, ccc, ddd, X[ 9], 13);
0143         RR1(ddd, aaa, bbb, ccc, X[ 2], 15);
0144         RR1(ccc, ddd, aaa, bbb, X[11], 15);
0145         RR1(bbb, ccc, ddd, aaa, X[ 4],  5);
0146         RR1(aaa, bbb, ccc, ddd, X[13],  7);
0147         RR1(ddd, aaa, bbb, ccc, X[ 6],  7);
0148         RR1(ccc, ddd, aaa, bbb, X[15],  8);
0149         RR1(bbb, ccc, ddd, aaa, X[ 8], 11);
0150         RR1(aaa, bbb, ccc, ddd, X[ 1], 14);
0151         RR1(ddd, aaa, bbb, ccc, X[10], 14);
0152         RR1(ccc, ddd, aaa, bbb, X[ 3], 12);
0153         RR1(bbb, ccc, ddd, aaa, X[12],  6);
0154 
0155         R2(aa, bb, cc, dd, X[ 7],  7);
0156         R2(dd, aa, bb, cc, X[ 4],  6);
0157         R2(cc, dd, aa, bb, X[13],  8);
0158         R2(bb, cc, dd, aa, X[ 1], 13);
0159         R2(aa, bb, cc, dd, X[10], 11);
0160         R2(dd, aa, bb, cc, X[ 6],  9);
0161         R2(cc, dd, aa, bb, X[15],  7);
0162         R2(bb, cc, dd, aa, X[ 3], 15);
0163         R2(aa, bb, cc, dd, X[12],  7);
0164         R2(dd, aa, bb, cc, X[ 0], 12);
0165         R2(cc, dd, aa, bb, X[ 9], 15);
0166         R2(bb, cc, dd, aa, X[ 5],  9);
0167         R2(aa, bb, cc, dd, X[ 2], 11);
0168         R2(dd, aa, bb, cc, X[14],  7);
0169         R2(cc, dd, aa, bb, X[11], 13);
0170         R2(bb, cc, dd, aa, X[ 8], 12);
0171 
0172         RR2(aaa, bbb, ccc, ddd, X[ 6],  9);
0173         RR2(ddd, aaa, bbb, ccc, X[11], 13);
0174         RR2(ccc, ddd, aaa, bbb, X[ 3], 15);
0175         RR2(bbb, ccc, ddd, aaa, X[ 7],  7);
0176         RR2(aaa, bbb, ccc, ddd, X[ 0], 12);
0177         RR2(ddd, aaa, bbb, ccc, X[13],  8);
0178         RR2(ccc, ddd, aaa, bbb, X[ 5],  9);
0179         RR2(bbb, ccc, ddd, aaa, X[10], 11);
0180         RR2(aaa, bbb, ccc, ddd, X[14],  7);
0181         RR2(ddd, aaa, bbb, ccc, X[15],  7);
0182         RR2(ccc, ddd, aaa, bbb, X[ 8], 12);
0183         RR2(bbb, ccc, ddd, aaa, X[12],  7);
0184         RR2(aaa, bbb, ccc, ddd, X[ 4],  6);
0185         RR2(ddd, aaa, bbb, ccc, X[ 9], 15);
0186         RR2(ccc, ddd, aaa, bbb, X[ 1], 13);
0187         RR2(bbb, ccc, ddd, aaa, X[ 2], 11);
0188 
0189         R3(aa, bb, cc, dd, X[ 3], 11);
0190         R3(dd, aa, bb, cc, X[10], 13);
0191         R3(cc, dd, aa, bb, X[14],  6);
0192         R3(bb, cc, dd, aa, X[ 4],  7);
0193         R3(aa, bb, cc, dd, X[ 9], 14);
0194         R3(dd, aa, bb, cc, X[15],  9);
0195         R3(cc, dd, aa, bb, X[ 8], 13);
0196         R3(bb, cc, dd, aa, X[ 1], 15);
0197         R3(aa, bb, cc, dd, X[ 2], 14);
0198         R3(dd, aa, bb, cc, X[ 7],  8);
0199         R3(cc, dd, aa, bb, X[ 0], 13);
0200         R3(bb, cc, dd, aa, X[ 6],  6);
0201         R3(aa, bb, cc, dd, X[13],  5);
0202         R3(dd, aa, bb, cc, X[11], 12);
0203         R3(cc, dd, aa, bb, X[ 5],  7);
0204         R3(bb, cc, dd, aa, X[12],  5);
0205 
0206         RR3(aaa, bbb, ccc, ddd, X[15],  9);
0207         RR3(ddd, aaa, bbb, ccc, X[ 5],  7);
0208         RR3(ccc, ddd, aaa, bbb, X[ 1], 15);
0209         RR3(bbb, ccc, ddd, aaa, X[ 3], 11);
0210         RR3(aaa, bbb, ccc, ddd, X[ 7],  8);
0211         RR3(ddd, aaa, bbb, ccc, X[14],  6);
0212         RR3(ccc, ddd, aaa, bbb, X[ 6],  6);
0213         RR3(bbb, ccc, ddd, aaa, X[ 9], 14);
0214         RR3(aaa, bbb, ccc, ddd, X[11], 12);
0215         RR3(ddd, aaa, bbb, ccc, X[ 8], 13);
0216         RR3(ccc, ddd, aaa, bbb, X[12],  5);
0217         RR3(bbb, ccc, ddd, aaa, X[ 2], 14);
0218         RR3(aaa, bbb, ccc, ddd, X[10], 13);
0219         RR3(ddd, aaa, bbb, ccc, X[ 0], 13);
0220         RR3(ccc, ddd, aaa, bbb, X[ 4],  7);
0221         RR3(bbb, ccc, ddd, aaa, X[13],  5);
0222 
0223         R4(aa, bb, cc, dd, X[ 1], 11);
0224         R4(dd, aa, bb, cc, X[ 9], 12);
0225         R4(cc, dd, aa, bb, X[11], 14);
0226         R4(bb, cc, dd, aa, X[10], 15);
0227         R4(aa, bb, cc, dd, X[ 0], 14);
0228         R4(dd, aa, bb, cc, X[ 8], 15);
0229         R4(cc, dd, aa, bb, X[12],  9);
0230         R4(bb, cc, dd, aa, X[ 4],  8);
0231         R4(aa, bb, cc, dd, X[13],  9);
0232         R4(dd, aa, bb, cc, X[ 3], 14);
0233         R4(cc, dd, aa, bb, X[ 7],  5);
0234         R4(bb, cc, dd, aa, X[15],  6);
0235         R4(aa, bb, cc, dd, X[14],  8);
0236         R4(dd, aa, bb, cc, X[ 5],  6);
0237         R4(cc, dd, aa, bb, X[ 6],  5);
0238         R4(bb, cc, dd, aa, X[ 2], 12);
0239 
0240         RR4(aaa, bbb, ccc, ddd, X[ 8], 15);
0241         RR4(ddd, aaa, bbb, ccc, X[ 6],  5);
0242         RR4(ccc, ddd, aaa, bbb, X[ 4],  8);
0243         RR4(bbb, ccc, ddd, aaa, X[ 1], 11);
0244         RR4(aaa, bbb, ccc, ddd, X[ 3], 14);
0245         RR4(ddd, aaa, bbb, ccc, X[11], 14);
0246         RR4(ccc, ddd, aaa, bbb, X[15],  6);
0247         RR4(bbb, ccc, ddd, aaa, X[ 0], 14);
0248         RR4(aaa, bbb, ccc, ddd, X[ 5],  6);
0249         RR4(ddd, aaa, bbb, ccc, X[12],  9);
0250         RR4(ccc, ddd, aaa, bbb, X[ 2], 12);
0251         RR4(bbb, ccc, ddd, aaa, X[13],  9);
0252         RR4(aaa, bbb, ccc, ddd, X[ 9], 12);
0253         RR4(ddd, aaa, bbb, ccc, X[ 7],  5);
0254         RR4(ccc, ddd, aaa, bbb, X[10], 15);
0255         RR4(bbb, ccc, ddd, aaa, X[14],  8);
0256 
0257         ddd += cc + state_[ 1 ];
0258         state_[ 1 ] = state_[ 2 ] + dd + aaa;
0259         state_[ 2 ] = state_[ 3 ] + aa + bbb;
0260         state_[ 3 ] = state_[ 0 ] + bb + ccc;
0261         state_[ 0 ] = ddd;
0262     }
0263 
0264 public:
0265 
0266     typedef digest<16> result_type;
0267 
0268     static constexpr std::size_t block_size = 64;
0269 
0270     ripemd_128() = default;
0271 
0272     explicit BOOST_CXX14_CONSTEXPR ripemd_128( std::uint64_t seed )
0273     {
0274         if( seed != 0 )
0275         {
0276             unsigned char tmp[ 8 ] = {};
0277             detail::write64le( tmp, seed );
0278 
0279             update( tmp, 8 );
0280             result();
0281         }
0282     }
0283 
0284     BOOST_CXX14_CONSTEXPR ripemd_128( unsigned char const * p, std::size_t n )
0285     {
0286         if( n != 0 )
0287         {
0288             update( p, n );
0289             result();
0290         }
0291     }
0292 
0293     ripemd_128( void const * p, std::size_t n ): ripemd_128( static_cast<unsigned char const*>( p ), n )
0294     {
0295     }
0296 
0297     BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0298     {
0299         BOOST_ASSERT( m_ == n_ % N );
0300 
0301         if( n == 0 ) return;
0302 
0303         n_ += n;
0304 
0305         if( m_ > 0 )
0306         {
0307             std::size_t k = N - m_;
0308 
0309             if( n < k )
0310             {
0311                 k = n;
0312             }
0313 
0314             detail::memcpy( buffer_ + m_, p, k );
0315 
0316             p += k;
0317             n -= k;
0318             m_ += k;
0319 
0320             if( m_ < N ) return;
0321 
0322             BOOST_ASSERT( m_ == N );
0323 
0324             transform( buffer_ );
0325             m_ = 0;
0326 
0327             detail::memset( buffer_, 0, N );
0328         }
0329 
0330         BOOST_ASSERT( m_ == 0 );
0331 
0332         while( n >= N )
0333         {
0334             transform( p );
0335 
0336             p += N;
0337             n -= N;
0338         }
0339 
0340         BOOST_ASSERT( n < N );
0341 
0342         if( n > 0 )
0343         {
0344             detail::memcpy( buffer_, p, n );
0345             m_ = n;
0346         }
0347 
0348         BOOST_ASSERT( m_ == n_ % N );
0349     }
0350 
0351     void update( void const * pv, std::size_t n )
0352     {
0353         unsigned char const* p = static_cast<unsigned char const*>( pv );
0354         update( p, n );
0355     }
0356 
0357     BOOST_CXX14_CONSTEXPR result_type result()
0358     {
0359         BOOST_ASSERT( m_ == n_ % N );
0360 
0361         unsigned char bits[ 8 ] = {};
0362 
0363         detail::write64le( bits, n_ * 8 );
0364 
0365         std::size_t k = m_ < 56? 56 - m_: 120 - m_;
0366 
0367         unsigned char padding[ 64 ] = { 0x80 };
0368 
0369         update( padding, k );
0370 
0371         update( bits, 8 );
0372 
0373         BOOST_ASSERT( m_ == 0 );
0374 
0375         result_type digest;
0376 
0377         for( int i = 0; i < 4; ++i )
0378         {
0379             detail::write32le( &digest[ i * 4 ], state_[ i ] );
0380         }
0381 
0382         return digest;
0383     }
0384 };
0385 
0386 class ripemd_160
0387 {
0388 private:
0389 
0390     std::uint32_t state_[ 5 ] = { 0x67452301u, 0xefcdab89u, 0x98badcfeu, 0x10325476u, 0xc3d2e1f0u };
0391 
0392     static constexpr int N = 64;
0393 
0394     unsigned char buffer_[ N ] = {};
0395     std::size_t m_ = 0; // == n_ % N
0396 
0397     std::uint64_t n_ = 0;
0398 
0399 private:
0400 
0401     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F1( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ y ^ z; }
0402     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F2( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & y) | (~x & z); }
0403     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F3( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x | ~y) ^ z; }
0404     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F4( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return (x & z) | (y & ~z); }
0405     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR std::uint32_t F5( std::uint32_t x, std::uint32_t y, std::uint32_t z) { return x ^ (y | ~z); }
0406 
0407     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 x, std::uint32_t s )
0408     {
0409         a += F1(b, c, d) + x;
0410         a = detail::rotl(a, s) + e;
0411         c = detail::rotl(c, 10);
0412     }
0413 
0414     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 x, std::uint32_t s )
0415     {
0416         a += F2(b, c, d) + x + 0x5a827999u;
0417         a = detail::rotl(a, s) + e;
0418         c = detail::rotl(c, 10);
0419     }
0420 
0421     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 x, std::uint32_t s )
0422     {
0423         a += F3(b, c, d) + x + 0x6ed9eba1u;
0424         a = detail::rotl(a, s) + e;
0425         c = detail::rotl(c, 10);
0426     }
0427 
0428     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 x, std::uint32_t s )
0429     {
0430         a += F4(b, c, d) + x + 0x8f1bbcdcu;
0431         a = detail::rotl(a, s) + e;
0432         c = detail::rotl(c, 10);
0433     }
0434 
0435     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 x, std::uint32_t s )
0436     {
0437         a += F5(b, c, d) + x + 0xa953fd4eu;
0438         a = detail::rotl(a, s) + e;
0439         c = detail::rotl(c, 10);
0440     }
0441 
0442     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR1( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s )
0443     {
0444         a += F5(b, c, d) + x + 0x50a28be6u;
0445         a = detail::rotl(a, s) + e;
0446         c = detail::rotl(c, 10);
0447     }
0448 
0449     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR2( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s )
0450     {
0451         a += F4(b, c, d) + x + 0x5c4dd124u;
0452         a = detail::rotl(a, s) + e;
0453         c = detail::rotl(c, 10);
0454     }
0455 
0456     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR3( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s )
0457     {
0458         a += F3(b, c, d) + x + 0x6d703ef3u;
0459         a = detail::rotl(a, s) + e;
0460         c = detail::rotl(c, 10);
0461     }
0462 
0463     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR4( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s )
0464     {
0465         a += F2(b, c, d) + x + 0x7a6d76e9u;
0466         a = detail::rotl(a, s) + e;
0467         c = detail::rotl(c, 10);
0468     }
0469 
0470     static BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void RR5( std::uint32_t & a, std::uint32_t b, std::uint32_t & c, std::uint32_t d, std::uint32_t e, std::uint32_t x, std::uint32_t s )
0471     {
0472         a += F1(b, c, d) + x;
0473         a = detail::rotl(a, s) + e;
0474         c = detail::rotl(c, 10);
0475     }
0476 
0477     BOOST_CXX14_CONSTEXPR void transform( unsigned char const block[ 64 ] )
0478     {
0479         std::uint32_t aa = state_[ 0 ];
0480         std::uint32_t bb = state_[ 1 ];
0481         std::uint32_t cc = state_[ 2 ];
0482         std::uint32_t dd = state_[ 3 ];
0483         std::uint32_t ee = state_[ 4 ];
0484 
0485         std::uint32_t aaa = state_[ 0 ];
0486         std::uint32_t bbb = state_[ 1 ];
0487         std::uint32_t ccc = state_[ 2 ];
0488         std::uint32_t ddd = state_[ 3 ];
0489         std::uint32_t eee = state_[ 4 ];
0490 
0491         std::uint32_t X[ 16 ] = {};
0492 
0493         for( int i = 0; i < 16; ++i )
0494         {
0495             X[ i ] = detail::read32le( block + i * 4 );
0496         }
0497 
0498         // each function mutates a and c inputs so that we can easily rotate the arguments when expanding the evaluation
0499         // of the core algorithm in the paper:
0500         // T = rotl(A + f(j, B, C, D) + X[i][r[j]] + K[j], s)
0501         // A = E
0502         // E = D
0503         // D = rotl(C, 10)
0504         // C = B
0505         // B = T
0506         // mutating A in-place as T permits us to use it as B in the next call and so on and so forth
0507         // mutating C in-place permits us to use it as D in later calls as well and so on and so forth
0508 
0509         //  A   B   C   D   E
0510         R1(aa, bb, cc, dd, ee, X[ 0], 11);
0511         R1(ee, aa, bb, cc, dd, X[ 1], 14);
0512         R1(dd, ee, aa, bb, cc, X[ 2], 15);
0513         R1(cc, dd, ee, aa, bb, X[ 3], 12);
0514         R1(bb, cc, dd, ee, aa, X[ 4],  5);
0515         R1(aa, bb, cc, dd, ee, X[ 5],  8);
0516         R1(ee, aa, bb, cc, dd, X[ 6],  7);
0517         R1(dd, ee, aa, bb, cc, X[ 7],  9);
0518         R1(cc, dd, ee, aa, bb, X[ 8], 11);
0519         R1(bb, cc, dd, ee, aa, X[ 9], 13);
0520         R1(aa, bb, cc, dd, ee, X[10], 14);
0521         R1(ee, aa, bb, cc, dd, X[11], 15);
0522         R1(dd, ee, aa, bb, cc, X[12],  6);
0523         R1(cc, dd, ee, aa, bb, X[13],  7);
0524         R1(bb, cc, dd, ee, aa, X[14],  9);
0525         R1(aa, bb, cc, dd, ee, X[15],  8);
0526 
0527         RR1(aaa, bbb, ccc, ddd, eee, X[ 5],  8);
0528         RR1(eee, aaa, bbb, ccc, ddd, X[14],  9);
0529         RR1(ddd, eee, aaa, bbb, ccc, X[ 7],  9);
0530         RR1(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
0531         RR1(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
0532         RR1(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
0533         RR1(eee, aaa, bbb, ccc, ddd, X[11], 15);
0534         RR1(ddd, eee, aaa, bbb, ccc, X[ 4],  5);
0535         RR1(ccc, ddd, eee, aaa, bbb, X[13],  7);
0536         RR1(bbb, ccc, ddd, eee, aaa, X[ 6],  7);
0537         RR1(aaa, bbb, ccc, ddd, eee, X[15],  8);
0538         RR1(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
0539         RR1(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
0540         RR1(ccc, ddd, eee, aaa, bbb, X[10], 14);
0541         RR1(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
0542         RR1(aaa, bbb, ccc, ddd, eee, X[12],  6);
0543 
0544         R2(ee, aa, bb, cc, dd, X[ 7],  7);
0545         R2(dd, ee, aa, bb, cc, X[ 4],  6);
0546         R2(cc, dd, ee, aa, bb, X[13],  8);
0547         R2(bb, cc, dd, ee, aa, X[ 1], 13);
0548         R2(aa, bb, cc, dd, ee, X[10], 11);
0549         R2(ee, aa, bb, cc, dd, X[ 6],  9);
0550         R2(dd, ee, aa, bb, cc, X[15],  7);
0551         R2(cc, dd, ee, aa, bb, X[ 3], 15);
0552         R2(bb, cc, dd, ee, aa, X[12],  7);
0553         R2(aa, bb, cc, dd, ee, X[ 0], 12);
0554         R2(ee, aa, bb, cc, dd, X[ 9], 15);
0555         R2(dd, ee, aa, bb, cc, X[ 5],  9);
0556         R2(cc, dd, ee, aa, bb, X[ 2], 11);
0557         R2(bb, cc, dd, ee, aa, X[14],  7);
0558         R2(aa, bb, cc, dd, ee, X[11], 13);
0559         R2(ee, aa, bb, cc, dd, X[ 8], 12);
0560 
0561         RR2(eee, aaa, bbb, ccc, ddd, X[ 6],  9);
0562         RR2(ddd, eee, aaa, bbb, ccc, X[11], 13);
0563         RR2(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
0564         RR2(bbb, ccc, ddd, eee, aaa, X[ 7],  7);
0565         RR2(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
0566         RR2(eee, aaa, bbb, ccc, ddd, X[13],  8);
0567         RR2(ddd, eee, aaa, bbb, ccc, X[ 5],  9);
0568         RR2(ccc, ddd, eee, aaa, bbb, X[10], 11);
0569         RR2(bbb, ccc, ddd, eee, aaa, X[14],  7);
0570         RR2(aaa, bbb, ccc, ddd, eee, X[15],  7);
0571         RR2(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
0572         RR2(ddd, eee, aaa, bbb, ccc, X[12],  7);
0573         RR2(ccc, ddd, eee, aaa, bbb, X[ 4],  6);
0574         RR2(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
0575         RR2(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
0576         RR2(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
0577 
0578         R3(dd, ee, aa, bb, cc, X[ 3], 11);
0579         R3(cc, dd, ee, aa, bb, X[10], 13);
0580         R3(bb, cc, dd, ee, aa, X[14],  6);
0581         R3(aa, bb, cc, dd, ee, X[ 4],  7);
0582         R3(ee, aa, bb, cc, dd, X[ 9], 14);
0583         R3(dd, ee, aa, bb, cc, X[15],  9);
0584         R3(cc, dd, ee, aa, bb, X[ 8], 13);
0585         R3(bb, cc, dd, ee, aa, X[ 1], 15);
0586         R3(aa, bb, cc, dd, ee, X[ 2], 14);
0587         R3(ee, aa, bb, cc, dd, X[ 7],  8);
0588         R3(dd, ee, aa, bb, cc, X[ 0], 13);
0589         R3(cc, dd, ee, aa, bb, X[ 6],  6);
0590         R3(bb, cc, dd, ee, aa, X[13],  5);
0591         R3(aa, bb, cc, dd, ee, X[11], 12);
0592         R3(ee, aa, bb, cc, dd, X[ 5],  7);
0593         R3(dd, ee, aa, bb, cc, X[12],  5);
0594 
0595         RR3(ddd, eee, aaa, bbb, ccc, X[15],  9);
0596         RR3(ccc, ddd, eee, aaa, bbb, X[ 5],  7);
0597         RR3(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
0598         RR3(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
0599         RR3(eee, aaa, bbb, ccc, ddd, X[ 7],  8);
0600         RR3(ddd, eee, aaa, bbb, ccc, X[14],  6);
0601         RR3(ccc, ddd, eee, aaa, bbb, X[ 6],  6);
0602         RR3(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
0603         RR3(aaa, bbb, ccc, ddd, eee, X[11], 12);
0604         RR3(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
0605         RR3(ddd, eee, aaa, bbb, ccc, X[12],  5);
0606         RR3(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
0607         RR3(bbb, ccc, ddd, eee, aaa, X[10], 13);
0608         RR3(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
0609         RR3(eee, aaa, bbb, ccc, ddd, X[ 4],  7);
0610         RR3(ddd, eee, aaa, bbb, ccc, X[13],  5);
0611 
0612         R4(cc, dd, ee, aa, bb, X[ 1], 11);
0613         R4(bb, cc, dd, ee, aa, X[ 9], 12);
0614         R4(aa, bb, cc, dd, ee, X[11], 14);
0615         R4(ee, aa, bb, cc, dd, X[10], 15);
0616         R4(dd, ee, aa, bb, cc, X[ 0], 14);
0617         R4(cc, dd, ee, aa, bb, X[ 8], 15);
0618         R4(bb, cc, dd, ee, aa, X[12],  9);
0619         R4(aa, bb, cc, dd, ee, X[ 4],  8);
0620         R4(ee, aa, bb, cc, dd, X[13],  9);
0621         R4(dd, ee, aa, bb, cc, X[ 3], 14);
0622         R4(cc, dd, ee, aa, bb, X[ 7],  5);
0623         R4(bb, cc, dd, ee, aa, X[15],  6);
0624         R4(aa, bb, cc, dd, ee, X[14],  8);
0625         R4(ee, aa, bb, cc, dd, X[ 5],  6);
0626         R4(dd, ee, aa, bb, cc, X[ 6],  5);
0627         R4(cc, dd, ee, aa, bb, X[ 2], 12);
0628 
0629         RR4(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
0630         RR4(bbb, ccc, ddd, eee, aaa, X[ 6],  5);
0631         RR4(aaa, bbb, ccc, ddd, eee, X[ 4],  8);
0632         RR4(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
0633         RR4(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
0634         RR4(ccc, ddd, eee, aaa, bbb, X[11], 14);
0635         RR4(bbb, ccc, ddd, eee, aaa, X[15],  6);
0636         RR4(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
0637         RR4(eee, aaa, bbb, ccc, ddd, X[ 5],  6);
0638         RR4(ddd, eee, aaa, bbb, ccc, X[12],  9);
0639         RR4(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
0640         RR4(bbb, ccc, ddd, eee, aaa, X[13],  9);
0641         RR4(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
0642         RR4(eee, aaa, bbb, ccc, ddd, X[ 7],  5);
0643         RR4(ddd, eee, aaa, bbb, ccc, X[10], 15);
0644         RR4(ccc, ddd, eee, aaa, bbb, X[14],  8);
0645 
0646         R5(bb, cc, dd, ee, aa, X[ 4],  9);
0647         R5(aa, bb, cc, dd, ee, X[ 0], 15);
0648         R5(ee, aa, bb, cc, dd, X[ 5],  5);
0649         R5(dd, ee, aa, bb, cc, X[ 9], 11);
0650         R5(cc, dd, ee, aa, bb, X[ 7],  6);
0651         R5(bb, cc, dd, ee, aa, X[12],  8);
0652         R5(aa, bb, cc, dd, ee, X[ 2], 13);
0653         R5(ee, aa, bb, cc, dd, X[10], 12);
0654         R5(dd, ee, aa, bb, cc, X[14],  5);
0655         R5(cc, dd, ee, aa, bb, X[ 1], 12);
0656         R5(bb, cc, dd, ee, aa, X[ 3], 13);
0657         R5(aa, bb, cc, dd, ee, X[ 8], 14);
0658         R5(ee, aa, bb, cc, dd, X[11], 11);
0659         R5(dd, ee, aa, bb, cc, X[ 6],  8);
0660         R5(cc, dd, ee, aa, bb, X[15],  5);
0661         R5(bb, cc, dd, ee, aa, X[13],  6);
0662 
0663         RR5(bbb, ccc, ddd, eee, aaa, X[12] ,  8);
0664         RR5(aaa, bbb, ccc, ddd, eee, X[15] ,  5);
0665         RR5(eee, aaa, bbb, ccc, ddd, X[10] , 12);
0666         RR5(ddd, eee, aaa, bbb, ccc, X[ 4] ,  9);
0667         RR5(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
0668         RR5(bbb, ccc, ddd, eee, aaa, X[ 5] ,  5);
0669         RR5(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
0670         RR5(eee, aaa, bbb, ccc, ddd, X[ 7] ,  6);
0671         RR5(ddd, eee, aaa, bbb, ccc, X[ 6] ,  8);
0672         RR5(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
0673         RR5(bbb, ccc, ddd, eee, aaa, X[13] ,  6);
0674         RR5(aaa, bbb, ccc, ddd, eee, X[14] ,  5);
0675         RR5(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
0676         RR5(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
0677         RR5(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
0678         RR5(bbb, ccc, ddd, eee, aaa, X[11] , 11);
0679 
0680         ddd += cc + state_[ 1 ];
0681         state_[ 1 ] = state_[ 2 ] + dd + eee;
0682         state_[ 2 ] = state_[ 3 ] + ee + aaa;
0683         state_[ 3 ] = state_[ 4 ] + aa + bbb;
0684         state_[ 4 ] = state_[ 0 ] + bb + ccc;
0685         state_[ 0 ] = ddd;
0686     }
0687 
0688 public:
0689 
0690     typedef digest<20> result_type;
0691 
0692     static constexpr std::size_t block_size = 64;
0693 
0694     ripemd_160() = default;
0695 
0696     explicit BOOST_CXX14_CONSTEXPR ripemd_160( std::uint64_t seed )
0697     {
0698         if( seed != 0 )
0699         {
0700             unsigned char tmp[ 8 ] = {};
0701             detail::write64le( tmp, seed );
0702 
0703             update( tmp, 8 );
0704             result();
0705         }
0706     }
0707 
0708     BOOST_CXX14_CONSTEXPR ripemd_160( unsigned char const * p, std::size_t n )
0709     {
0710         if( n != 0 )
0711         {
0712             update( p, n );
0713             result();
0714         }
0715     }
0716 
0717     ripemd_160( void const * p, std::size_t n ): ripemd_160( static_cast<unsigned char const*>( p ), n )
0718     {
0719     }
0720 
0721     BOOST_CXX14_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0722     {
0723         BOOST_ASSERT( m_ == n_ % N );
0724 
0725         if( n == 0 ) return;
0726 
0727         n_ += n;
0728 
0729         if( m_ > 0 )
0730         {
0731             std::size_t k = N - m_;
0732 
0733             if( n < k )
0734             {
0735                 k = n;
0736             }
0737 
0738             detail::memcpy( buffer_ + m_, p, k );
0739 
0740             p += k;
0741             n -= k;
0742             m_ += k;
0743 
0744             if( m_ < N ) return;
0745 
0746             BOOST_ASSERT( m_ == N );
0747 
0748             transform( buffer_ );
0749             m_ = 0;
0750 
0751             detail::memset( buffer_, 0, N );
0752         }
0753 
0754         BOOST_ASSERT( m_ == 0 );
0755 
0756         while( n >= N )
0757         {
0758             transform( p );
0759 
0760             p += N;
0761             n -= N;
0762         }
0763 
0764         BOOST_ASSERT( n < N );
0765 
0766         if( n > 0 )
0767         {
0768             detail::memcpy( buffer_, p, n );
0769             m_ = n;
0770         }
0771 
0772         BOOST_ASSERT( m_ == n_ % N );
0773     }
0774 
0775     void update( void const * pv, std::size_t n )
0776     {
0777         unsigned char const* p = static_cast<unsigned char const*>( pv );
0778         update( p, n );
0779     }
0780 
0781     BOOST_CXX14_CONSTEXPR result_type result()
0782     {
0783         BOOST_ASSERT( m_ == n_ % N );
0784 
0785         unsigned char bits[ 8 ] = {};
0786 
0787         detail::write64le( bits, n_ * 8 );
0788 
0789         std::size_t k = m_ < 56? 56 - m_: 120 - m_;
0790 
0791         unsigned char padding[ 64 ] = { 0x80 };
0792 
0793         update( padding, k );
0794 
0795         update( bits, 8 );
0796 
0797         BOOST_ASSERT( m_ == 0 );
0798 
0799         result_type digest;
0800 
0801         for( int i = 0; i < 5; ++i )
0802         {
0803             detail::write32le( &digest[ i * 4 ], state_[ i ] );
0804         }
0805 
0806         return digest;
0807     }
0808 };
0809 
0810 using hmac_ripemd_160 = hmac<ripemd_160>;
0811 using hmac_ripemd_128 = hmac<ripemd_128>;
0812 
0813 } // namespace hash2
0814 } // namespace boost
0815 
0816 #endif // #ifndef BOOST_HASH2_RIPEMD_HPP_INCLUDED