File indexing completed on 2026-08-17 08:46:46
0001 #ifndef BOOST_HASH2_BLAKE2_HPP_INCLUDED
0002 #define BOOST_HASH2_BLAKE2_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/hash2/digest.hpp>
0010 #include <boost/hash2/hmac.hpp>
0011
0012 #include <boost/hash2/detail/is_constant_evaluated.hpp>
0013 #include <boost/hash2/detail/memcpy.hpp>
0014 #include <boost/hash2/detail/memset.hpp>
0015 #include <boost/hash2/detail/read.hpp>
0016 #include <boost/hash2/detail/rot.hpp>
0017 #include <boost/hash2/detail/write.hpp>
0018
0019 #include <boost/assert.hpp>
0020 #include <boost/config.hpp>
0021 #include <boost/config/workaround.hpp>
0022
0023 #include <cstdint>
0024
0025 #if !defined(BOOST_HASH2_BLAKE2_CONSTEXPR)
0026
0027 #if BOOST_WORKAROUND(BOOST_GCC, >= 50000 && BOOST_GCC < 60000)
0028 #define BOOST_HASH2_BLAKE2_CONSTEXPR
0029 #else
0030 #define BOOST_HASH2_BLAKE2_CONSTEXPR BOOST_CXX14_CONSTEXPR
0031 #endif
0032
0033 #endif
0034
0035 namespace boost
0036 {
0037 namespace hash2
0038 {
0039 namespace detail
0040 {
0041
0042 template<class = void>
0043 struct blake2b_constants
0044 {
0045 constexpr static const std::uint64_t iv[ 8 ] =
0046 {
0047 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
0048 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
0049 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
0050 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
0051 };
0052 };
0053
0054 template<class = void>
0055 struct blake2s_constants
0056 {
0057 constexpr static const std::uint32_t iv[ 8 ] =
0058 {
0059 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0060 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
0061 };
0062 };
0063
0064
0065 #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
0066
0067
0068
0069
0070
0071
0072 template<class T>
0073 constexpr std::uint64_t blake2b_constants<T>::iv[ 8 ];
0074
0075 template<class T>
0076 constexpr std::uint32_t blake2s_constants<T>::iv[ 8 ];
0077
0078 #endif
0079
0080 }
0081
0082 class blake2b_512
0083 {
0084 private:
0085
0086 unsigned char b_[ 128 ] = {};
0087 std::uint64_t h_[ 8 ] = {};
0088 std::uint64_t t_[ 2 ] = {};
0089 std::size_t m_ = 0;
0090
0091 BOOST_HASH2_BLAKE2_CONSTEXPR void init( std::uint64_t keylen = 0 )
0092 {
0093 for( int i = 0; i < 8; ++i )
0094 {
0095 h_[ i ] = detail::blake2b_constants<>::iv[ i ];
0096 }
0097
0098 std::uint64_t const outlen = 64;
0099 h_[ 0 ] ^= 0x01010000 ^ ( keylen << 8 ) ^ outlen;
0100 }
0101
0102 BOOST_HASH2_BLAKE2_CONSTEXPR BOOST_FORCEINLINE static void G( std::uint64_t v[ 16 ], int a, int b, int c, int d, std::uint64_t x, std::uint64_t y )
0103 {
0104 v[ a ] = v[ a ] + v[ b ] + x;
0105 v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 32 );
0106 v[ c ] = v[ c ] + v[ d ];
0107 v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 24 );
0108 v[ a ] = v[ a ] + v[ b ] + y;
0109 v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 16 );
0110 v[ c ] = v[ c ] + v[ d ];
0111 v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 63 );
0112 }
0113
0114 BOOST_HASH2_BLAKE2_CONSTEXPR void transform( unsigned char const block[ 128 ], bool is_final = false )
0115 {
0116 auto iv = detail::blake2b_constants<>::iv;
0117
0118 std::uint64_t v[ 16 ] = {};
0119 std::uint64_t m[ 16 ] = {};
0120
0121 v[ 0 ] = h_[ 0 ];
0122 v[ 1 ] = h_[ 1 ];
0123 v[ 2 ] = h_[ 2 ];
0124 v[ 3 ] = h_[ 3 ];
0125 v[ 4 ] = h_[ 4 ];
0126 v[ 5 ] = h_[ 5 ];
0127 v[ 6 ] = h_[ 6 ];
0128 v[ 7 ] = h_[ 7 ];
0129
0130 v[ 8 ] = iv[ 0 ];
0131 v[ 9 ] = iv[ 1 ];
0132 v[ 10 ] = iv[ 2 ];
0133 v[ 11 ] = iv[ 3 ];
0134 v[ 12 ] = iv[ 4 ];
0135 v[ 13 ] = iv[ 5 ];
0136 v[ 14 ] = iv[ 6 ];
0137 v[ 15 ] = iv[ 7 ];
0138
0139 v[ 12 ] ^= t_[ 0 ];
0140 v[ 13 ] ^= t_[ 1 ];
0141
0142 if( is_final )
0143 {
0144 v[ 14 ] = ~v[ 14 ];
0145 }
0146
0147 for( int i = 0; i < 16; ++i )
0148 {
0149 m[ i ] = detail::read64le( block + 8 * i );
0150 }
0151
0152
0153 G( v, 0, 4, 8, 12, m[ 0 ], m[ 1 ] );
0154 G( v, 1, 5, 9, 13, m[ 2 ], m[ 3 ] );
0155 G( v, 2, 6, 10, 14, m[ 4 ], m[ 5 ] );
0156 G( v, 3, 7, 11, 15, m[ 6 ], m[ 7 ] );
0157 G( v, 0, 5, 10, 15, m[ 8 ], m[ 9 ] );
0158 G( v, 1, 6, 11, 12, m[ 10 ], m[ 11 ] );
0159 G( v, 2, 7, 8, 13, m[ 12 ], m[ 13 ] );
0160 G( v, 3, 4, 9, 14, m[ 14 ], m[ 15 ] );
0161
0162
0163 G( v, 0, 4, 8, 12, m[ 14 ], m[ 10 ] );
0164 G( v, 1, 5, 9, 13, m[ 4 ], m[ 8 ] );
0165 G( v, 2, 6, 10, 14, m[ 9 ], m[ 15 ] );
0166 G( v, 3, 7, 11, 15, m[ 13 ], m[ 6 ] );
0167 G( v, 0, 5, 10, 15, m[ 1 ], m[ 12 ] );
0168 G( v, 1, 6, 11, 12, m[ 0 ], m[ 2 ] );
0169 G( v, 2, 7, 8, 13, m[ 11 ], m[ 7 ] );
0170 G( v, 3, 4, 9, 14, m[ 5 ], m[ 3 ] );
0171
0172
0173 G( v, 0, 4, 8, 12, m[ 11 ], m[ 8 ] );
0174 G( v, 1, 5, 9, 13, m[ 12 ], m[ 0 ] );
0175 G( v, 2, 6, 10, 14, m[ 5 ], m[ 2 ] );
0176 G( v, 3, 7, 11, 15, m[ 15 ], m[ 13 ] );
0177 G( v, 0, 5, 10, 15, m[ 10 ], m[ 14 ] );
0178 G( v, 1, 6, 11, 12, m[ 3 ], m[ 6 ] );
0179 G( v, 2, 7, 8, 13, m[ 7 ], m[ 1 ] );
0180 G( v, 3, 4, 9, 14, m[ 9 ], m[ 4 ] );
0181
0182
0183 G( v, 0, 4, 8, 12, m[ 7 ], m[ 9 ] );
0184 G( v, 1, 5, 9, 13, m[ 3 ], m[ 1 ] );
0185 G( v, 2, 6, 10, 14, m[ 13 ], m[ 12 ] );
0186 G( v, 3, 7, 11, 15, m[ 11 ], m[ 14 ] );
0187 G( v, 0, 5, 10, 15, m[ 2 ], m[ 6 ] );
0188 G( v, 1, 6, 11, 12, m[ 5 ], m[ 10 ] );
0189 G( v, 2, 7, 8, 13, m[ 4 ], m[ 0 ] );
0190 G( v, 3, 4, 9, 14, m[ 15 ], m[ 8 ] );
0191
0192
0193 G( v, 0, 4, 8, 12, m[ 9 ], m[ 0 ] );
0194 G( v, 1, 5, 9, 13, m[ 5 ], m[ 7 ] );
0195 G( v, 2, 6, 10, 14, m[ 2 ], m[ 4 ] );
0196 G( v, 3, 7, 11, 15, m[ 10 ], m[ 15 ] );
0197 G( v, 0, 5, 10, 15, m[ 14 ], m[ 1 ] );
0198 G( v, 1, 6, 11, 12, m[ 11 ], m[ 12 ] );
0199 G( v, 2, 7, 8, 13, m[ 6 ], m[ 8 ] );
0200 G( v, 3, 4, 9, 14, m[ 3 ], m[ 13 ] );
0201
0202
0203 G( v, 0, 4, 8, 12, m[ 2 ], m[ 12 ] );
0204 G( v, 1, 5, 9, 13, m[ 6 ], m[ 10 ] );
0205 G( v, 2, 6, 10, 14, m[ 0 ], m[ 11 ] );
0206 G( v, 3, 7, 11, 15, m[ 8 ], m[ 3 ] );
0207 G( v, 0, 5, 10, 15, m[ 4 ], m[ 13 ] );
0208 G( v, 1, 6, 11, 12, m[ 7 ], m[ 5 ] );
0209 G( v, 2, 7, 8, 13, m[ 15 ], m[ 14 ] );
0210 G( v, 3, 4, 9, 14, m[ 1 ], m[ 9 ] );
0211
0212
0213 G( v, 0, 4, 8, 12, m[ 12 ], m[ 5 ] );
0214 G( v, 1, 5, 9, 13, m[ 1 ], m[ 15 ] );
0215 G( v, 2, 6, 10, 14, m[ 14 ], m[ 13 ] );
0216 G( v, 3, 7, 11, 15, m[ 4 ], m[ 10 ] );
0217 G( v, 0, 5, 10, 15, m[ 0 ], m[ 7 ] );
0218 G( v, 1, 6, 11, 12, m[ 6 ], m[ 3 ] );
0219 G( v, 2, 7, 8, 13, m[ 9 ], m[ 2 ] );
0220 G( v, 3, 4, 9, 14, m[ 8 ], m[ 11 ] );
0221
0222
0223 G( v, 0, 4, 8, 12, m[ 13 ], m[ 11 ] );
0224 G( v, 1, 5, 9, 13, m[ 7 ], m[ 14 ] );
0225 G( v, 2, 6, 10, 14, m[ 12 ], m[ 1 ] );
0226 G( v, 3, 7, 11, 15, m[ 3 ], m[ 9 ] );
0227 G( v, 0, 5, 10, 15, m[ 5 ], m[ 0 ] );
0228 G( v, 1, 6, 11, 12, m[ 15 ], m[ 4 ] );
0229 G( v, 2, 7, 8, 13, m[ 8 ], m[ 6 ] );
0230 G( v, 3, 4, 9, 14, m[ 2 ], m[ 10 ] );
0231
0232
0233 G( v, 0, 4, 8, 12, m[ 6 ], m[ 15 ] );
0234 G( v, 1, 5, 9, 13, m[ 14 ], m[ 9 ] );
0235 G( v, 2, 6, 10, 14, m[ 11 ], m[ 3 ] );
0236 G( v, 3, 7, 11, 15, m[ 0 ], m[ 8 ] );
0237 G( v, 0, 5, 10, 15, m[ 12 ], m[ 2 ] );
0238 G( v, 1, 6, 11, 12, m[ 13 ], m[ 7 ] );
0239 G( v, 2, 7, 8, 13, m[ 1 ], m[ 4 ] );
0240 G( v, 3, 4, 9, 14, m[ 10 ], m[ 5 ] );
0241
0242
0243 G( v, 0, 4, 8, 12, m[ 10 ], m[ 2 ] );
0244 G( v, 1, 5, 9, 13, m[ 8 ], m[ 4 ] );
0245 G( v, 2, 6, 10, 14, m[ 7 ], m[ 6 ] );
0246 G( v, 3, 7, 11, 15, m[ 1 ], m[ 5 ] );
0247 G( v, 0, 5, 10, 15, m[ 15 ], m[ 11 ] );
0248 G( v, 1, 6, 11, 12, m[ 9 ], m[ 14 ] );
0249 G( v, 2, 7, 8, 13, m[ 3 ], m[ 12 ] );
0250 G( v, 3, 4, 9, 14, m[ 13 ], m[ 0 ] );
0251
0252
0253 G( v, 0, 4, 8, 12, m[ 0 ], m[ 1 ] );
0254 G( v, 1, 5, 9, 13, m[ 2 ], m[ 3 ] );
0255 G( v, 2, 6, 10, 14, m[ 4 ], m[ 5 ] );
0256 G( v, 3, 7, 11, 15, m[ 6 ], m[ 7 ] );
0257 G( v, 0, 5, 10, 15, m[ 8 ], m[ 9 ] );
0258 G( v, 1, 6, 11, 12, m[ 10 ], m[ 11 ] );
0259 G( v, 2, 7, 8, 13, m[ 12 ], m[ 13 ] );
0260 G( v, 3, 4, 9, 14, m[ 14 ], m[ 15 ] );
0261
0262
0263 G( v, 0, 4, 8, 12, m[ 14 ], m[ 10 ] );
0264 G( v, 1, 5, 9, 13, m[ 4 ], m[ 8 ] );
0265 G( v, 2, 6, 10, 14, m[ 9 ], m[ 15 ] );
0266 G( v, 3, 7, 11, 15, m[ 13 ], m[ 6 ] );
0267 G( v, 0, 5, 10, 15, m[ 1 ], m[ 12 ] );
0268 G( v, 1, 6, 11, 12, m[ 0 ], m[ 2 ] );
0269 G( v, 2, 7, 8, 13, m[ 11 ], m[ 7 ] );
0270 G( v, 3, 4, 9, 14, m[ 5 ], m[ 3 ] );
0271
0272 h_[ 0 ] ^= v[ 0 ] ^ v[ 0 + 8 ];
0273 h_[ 1 ] ^= v[ 1 ] ^ v[ 1 + 8 ];
0274 h_[ 2 ] ^= v[ 2 ] ^ v[ 2 + 8 ];
0275 h_[ 3 ] ^= v[ 3 ] ^ v[ 3 + 8 ];
0276 h_[ 4 ] ^= v[ 4 ] ^ v[ 4 + 8 ];
0277 h_[ 5 ] ^= v[ 5 ] ^ v[ 5 + 8 ];
0278 h_[ 6 ] ^= v[ 6 ] ^ v[ 6 + 8 ];
0279 h_[ 7 ] ^= v[ 7 ] ^ v[ 7 + 8 ];
0280 }
0281
0282 BOOST_HASH2_BLAKE2_CONSTEXPR BOOST_FORCEINLINE void incr_len( std::size_t n )
0283 {
0284 t_[ 0 ] += n;
0285 t_[ 1 ] += ( t_[ 0 ] < n );
0286 }
0287
0288 public:
0289
0290 using result_type = digest<64>;
0291
0292 static constexpr std::size_t block_size = 128;
0293
0294 BOOST_HASH2_BLAKE2_CONSTEXPR blake2b_512()
0295 {
0296 init();
0297 }
0298
0299 BOOST_HASH2_BLAKE2_CONSTEXPR explicit blake2b_512( std::uint64_t seed )
0300 {
0301 if( seed == 0 )
0302 {
0303 init();
0304 return;
0305 }
0306
0307 unsigned char tmp[ 8 ] = {};
0308 detail::write64le( tmp, seed );
0309
0310 init( 8 );
0311 update( tmp, 8 );
0312 m_ = block_size;
0313 }
0314
0315 blake2b_512( void const* p, std::size_t n ) : blake2b_512( static_cast<unsigned char const*>( p ), n )
0316 {
0317 }
0318
0319 BOOST_HASH2_BLAKE2_CONSTEXPR blake2b_512( unsigned char const* p, std::size_t n )
0320 {
0321 if( n == 0 )
0322 {
0323 init();
0324 return;
0325 }
0326
0327 auto k = n;
0328 if( k > block_size / 2 )
0329 {
0330 k = block_size / 2;
0331 }
0332
0333 init( k );
0334 update( p, k );
0335 m_ = block_size;
0336 p += k;
0337 n -= k;
0338
0339 if( n != 0 )
0340 {
0341 update( p, n );
0342 result();
0343 }
0344 }
0345
0346 void update( void const* pv, std::size_t n )
0347 {
0348 unsigned char const* p = reinterpret_cast<unsigned char const*>( pv );
0349 update( p, n );
0350 }
0351
0352 BOOST_HASH2_BLAKE2_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0353 {
0354 if( n > 0 )
0355 {
0356 std::size_t k = block_size - m_;
0357 if( n > k )
0358 {
0359 detail::memcpy( b_ + m_, p, k );
0360 incr_len( block_size );
0361 transform( b_ );
0362 detail::memset( b_ , 0, block_size );
0363 p += k;
0364 n -= k;
0365 m_ = 0;
0366
0367 while( n > block_size )
0368 {
0369 incr_len( block_size );
0370 transform( p );
0371 p += block_size;
0372 n -= block_size;
0373 }
0374 }
0375
0376 detail::memcpy( b_ + m_, p, n );
0377 m_ += n;
0378 }
0379 }
0380
0381 BOOST_HASH2_BLAKE2_CONSTEXPR result_type result()
0382 {
0383 result_type digest;
0384
0385 incr_len( m_ );
0386 for( auto i = m_; i < block_size; ++i )
0387 {
0388 b_[ i ] = 0;
0389 }
0390
0391 transform( b_, true );
0392 detail::memset( b_ , 0, block_size );
0393 m_ = 0;
0394
0395 for( int i = 0; i < 8; ++i )
0396 {
0397 detail::write64le( digest.data() + i * 8, h_[ i ] );
0398 }
0399 return digest;
0400 }
0401 };
0402
0403 class blake2s_256
0404 {
0405 private:
0406
0407 unsigned char b_[ 64 ] = {};
0408 std::uint32_t h_[ 8 ] = {};
0409 std::uint32_t t_[ 2 ] = {};
0410 std::size_t m_ = 0;
0411
0412 BOOST_HASH2_BLAKE2_CONSTEXPR void init( std::uint32_t keylen = 0 )
0413 {
0414 for( int i = 0; i < 8; ++i )
0415 {
0416 h_[ i ] = detail::blake2s_constants<>::iv[ i ];
0417 }
0418
0419 std::uint32_t const outlen = 32;
0420 h_[ 0 ] ^= 0x01010000 ^ ( keylen << 8 ) ^ outlen;
0421 }
0422
0423 BOOST_HASH2_BLAKE2_CONSTEXPR BOOST_FORCEINLINE static void G( std::uint32_t v[ 16 ], int a, int b, int c, int d, std::uint32_t x, std::uint32_t y )
0424 {
0425 v[ a ] = v[ a ] + v[ b ] + x;
0426 v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 16 );
0427 v[ c ] = v[ c ] + v[ d ];
0428 v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 12 );
0429 v[ a ] = v[ a ] + v[ b ] + y;
0430 v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 8 );
0431 v[ c ] = v[ c ] + v[ d ];
0432 v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 7 );
0433 }
0434
0435 BOOST_HASH2_BLAKE2_CONSTEXPR void transform( unsigned char const block[ 64 ], bool is_final = false )
0436 {
0437 auto iv = detail::blake2s_constants<>::iv;
0438
0439 std::uint32_t v[ 16 ] = {};
0440 std::uint32_t m[ 16 ] = {};
0441
0442 v[ 0 ] = h_[ 0 ];
0443 v[ 1 ] = h_[ 1 ];
0444 v[ 2 ] = h_[ 2 ];
0445 v[ 3 ] = h_[ 3 ];
0446 v[ 4 ] = h_[ 4 ];
0447 v[ 5 ] = h_[ 5 ];
0448 v[ 6 ] = h_[ 6 ];
0449 v[ 7 ] = h_[ 7 ];
0450
0451 v[ 8 ] = iv[ 0 ];
0452 v[ 9 ] = iv[ 1 ];
0453 v[ 10 ] = iv[ 2 ];
0454 v[ 11 ] = iv[ 3 ];
0455 v[ 12 ] = iv[ 4 ];
0456 v[ 13 ] = iv[ 5 ];
0457 v[ 14 ] = iv[ 6 ];
0458 v[ 15 ] = iv[ 7 ];
0459
0460 v[ 12 ] ^= t_[ 0 ];
0461 v[ 13 ] ^= t_[ 1 ];
0462
0463 if( is_final )
0464 {
0465 v[ 14 ] = ~v[ 14 ];
0466 }
0467
0468 for( int i = 0; i < 16; ++i )
0469 {
0470 m[ i ] = detail::read32le( block + 4 * i );
0471 }
0472
0473
0474 G( v, 0, 4, 8, 12, m[ 0 ], m[ 1 ] );
0475 G( v, 1, 5, 9, 13, m[ 2 ], m[ 3 ] );
0476 G( v, 2, 6, 10, 14, m[ 4 ], m[ 5 ] );
0477 G( v, 3, 7, 11, 15, m[ 6 ], m[ 7 ] );
0478 G( v, 0, 5, 10, 15, m[ 8 ], m[ 9 ] );
0479 G( v, 1, 6, 11, 12, m[ 10 ], m[ 11 ] );
0480 G( v, 2, 7, 8, 13, m[ 12 ], m[ 13 ] );
0481 G( v, 3, 4, 9, 14, m[ 14 ], m[ 15 ] );
0482
0483
0484 G( v, 0, 4, 8, 12, m[ 14 ], m[ 10 ] );
0485 G( v, 1, 5, 9, 13, m[ 4 ], m[ 8 ] );
0486 G( v, 2, 6, 10, 14, m[ 9 ], m[ 15 ] );
0487 G( v, 3, 7, 11, 15, m[ 13 ], m[ 6 ] );
0488 G( v, 0, 5, 10, 15, m[ 1 ], m[ 12 ] );
0489 G( v, 1, 6, 11, 12, m[ 0 ], m[ 2 ] );
0490 G( v, 2, 7, 8, 13, m[ 11 ], m[ 7 ] );
0491 G( v, 3, 4, 9, 14, m[ 5 ], m[ 3 ] );
0492
0493
0494 G( v, 0, 4, 8, 12, m[ 11 ], m[ 8 ] );
0495 G( v, 1, 5, 9, 13, m[ 12 ], m[ 0 ] );
0496 G( v, 2, 6, 10, 14, m[ 5 ], m[ 2 ] );
0497 G( v, 3, 7, 11, 15, m[ 15 ], m[ 13 ] );
0498 G( v, 0, 5, 10, 15, m[ 10 ], m[ 14 ] );
0499 G( v, 1, 6, 11, 12, m[ 3 ], m[ 6 ] );
0500 G( v, 2, 7, 8, 13, m[ 7 ], m[ 1 ] );
0501 G( v, 3, 4, 9, 14, m[ 9 ], m[ 4 ] );
0502
0503
0504 G( v, 0, 4, 8, 12, m[ 7 ], m[ 9 ] );
0505 G( v, 1, 5, 9, 13, m[ 3 ], m[ 1 ] );
0506 G( v, 2, 6, 10, 14, m[ 13 ], m[ 12 ] );
0507 G( v, 3, 7, 11, 15, m[ 11 ], m[ 14 ] );
0508 G( v, 0, 5, 10, 15, m[ 2 ], m[ 6 ] );
0509 G( v, 1, 6, 11, 12, m[ 5 ], m[ 10 ] );
0510 G( v, 2, 7, 8, 13, m[ 4 ], m[ 0 ] );
0511 G( v, 3, 4, 9, 14, m[ 15 ], m[ 8 ] );
0512
0513
0514 G( v, 0, 4, 8, 12, m[ 9 ], m[ 0 ] );
0515 G( v, 1, 5, 9, 13, m[ 5 ], m[ 7 ] );
0516 G( v, 2, 6, 10, 14, m[ 2 ], m[ 4 ] );
0517 G( v, 3, 7, 11, 15, m[ 10 ], m[ 15 ] );
0518 G( v, 0, 5, 10, 15, m[ 14 ], m[ 1 ] );
0519 G( v, 1, 6, 11, 12, m[ 11 ], m[ 12 ] );
0520 G( v, 2, 7, 8, 13, m[ 6 ], m[ 8 ] );
0521 G( v, 3, 4, 9, 14, m[ 3 ], m[ 13 ] );
0522
0523
0524 G( v, 0, 4, 8, 12, m[ 2 ], m[ 12 ] );
0525 G( v, 1, 5, 9, 13, m[ 6 ], m[ 10 ] );
0526 G( v, 2, 6, 10, 14, m[ 0 ], m[ 11 ] );
0527 G( v, 3, 7, 11, 15, m[ 8 ], m[ 3 ] );
0528 G( v, 0, 5, 10, 15, m[ 4 ], m[ 13 ] );
0529 G( v, 1, 6, 11, 12, m[ 7 ], m[ 5 ] );
0530 G( v, 2, 7, 8, 13, m[ 15 ], m[ 14 ] );
0531 G( v, 3, 4, 9, 14, m[ 1 ], m[ 9 ] );
0532
0533
0534 G( v, 0, 4, 8, 12, m[ 12 ], m[ 5 ] );
0535 G( v, 1, 5, 9, 13, m[ 1 ], m[ 15 ] );
0536 G( v, 2, 6, 10, 14, m[ 14 ], m[ 13 ] );
0537 G( v, 3, 7, 11, 15, m[ 4 ], m[ 10 ] );
0538 G( v, 0, 5, 10, 15, m[ 0 ], m[ 7 ] );
0539 G( v, 1, 6, 11, 12, m[ 6 ], m[ 3 ] );
0540 G( v, 2, 7, 8, 13, m[ 9 ], m[ 2 ] );
0541 G( v, 3, 4, 9, 14, m[ 8 ], m[ 11 ] );
0542
0543
0544 G( v, 0, 4, 8, 12, m[ 13 ], m[ 11 ] );
0545 G( v, 1, 5, 9, 13, m[ 7 ], m[ 14 ] );
0546 G( v, 2, 6, 10, 14, m[ 12 ], m[ 1 ] );
0547 G( v, 3, 7, 11, 15, m[ 3 ], m[ 9 ] );
0548 G( v, 0, 5, 10, 15, m[ 5 ], m[ 0 ] );
0549 G( v, 1, 6, 11, 12, m[ 15 ], m[ 4 ] );
0550 G( v, 2, 7, 8, 13, m[ 8 ], m[ 6 ] );
0551 G( v, 3, 4, 9, 14, m[ 2 ], m[ 10 ] );
0552
0553
0554 G( v, 0, 4, 8, 12, m[ 6 ], m[ 15 ] );
0555 G( v, 1, 5, 9, 13, m[ 14 ], m[ 9 ] );
0556 G( v, 2, 6, 10, 14, m[ 11 ], m[ 3 ] );
0557 G( v, 3, 7, 11, 15, m[ 0 ], m[ 8 ] );
0558 G( v, 0, 5, 10, 15, m[ 12 ], m[ 2 ] );
0559 G( v, 1, 6, 11, 12, m[ 13 ], m[ 7 ] );
0560 G( v, 2, 7, 8, 13, m[ 1 ], m[ 4 ] );
0561 G( v, 3, 4, 9, 14, m[ 10 ], m[ 5 ] );
0562
0563
0564 G( v, 0, 4, 8, 12, m[ 10 ], m[ 2 ] );
0565 G( v, 1, 5, 9, 13, m[ 8 ], m[ 4 ] );
0566 G( v, 2, 6, 10, 14, m[ 7 ], m[ 6 ] );
0567 G( v, 3, 7, 11, 15, m[ 1 ], m[ 5 ] );
0568 G( v, 0, 5, 10, 15, m[ 15 ], m[ 11 ] );
0569 G( v, 1, 6, 11, 12, m[ 9 ], m[ 14 ] );
0570 G( v, 2, 7, 8, 13, m[ 3 ], m[ 12 ] );
0571 G( v, 3, 4, 9, 14, m[ 13 ], m[ 0 ] );
0572
0573 h_[ 0 ] ^= v[ 0 ] ^ v[ 0 + 8 ];
0574 h_[ 1 ] ^= v[ 1 ] ^ v[ 1 + 8 ];
0575 h_[ 2 ] ^= v[ 2 ] ^ v[ 2 + 8 ];
0576 h_[ 3 ] ^= v[ 3 ] ^ v[ 3 + 8 ];
0577 h_[ 4 ] ^= v[ 4 ] ^ v[ 4 + 8 ];
0578 h_[ 5 ] ^= v[ 5 ] ^ v[ 5 + 8 ];
0579 h_[ 6 ] ^= v[ 6 ] ^ v[ 6 + 8 ];
0580 h_[ 7 ] ^= v[ 7 ] ^ v[ 7 + 8 ];
0581 }
0582
0583 BOOST_HASH2_BLAKE2_CONSTEXPR void incr_len( std::size_t n )
0584 {
0585 auto m = static_cast<std::uint32_t>( n );
0586 t_[ 0 ] += m;
0587 t_[ 1 ] += ( t_[ 0 ] < m );
0588 }
0589
0590 public:
0591
0592 using result_type = digest<32>;
0593
0594 static constexpr std::size_t block_size = 64;
0595
0596 BOOST_HASH2_BLAKE2_CONSTEXPR blake2s_256()
0597 {
0598 init();
0599 }
0600
0601 BOOST_HASH2_BLAKE2_CONSTEXPR explicit blake2s_256( std::uint64_t seed )
0602 {
0603 if( seed == 0 )
0604 {
0605 init();
0606 return;
0607 }
0608
0609 unsigned char tmp[ 8 ] = {};
0610 detail::write64le( tmp, seed );
0611
0612 init( 8 );
0613 update( tmp, 8 );
0614 m_ = block_size;
0615 }
0616
0617 blake2s_256( void const* p, std::size_t n ) : blake2s_256( static_cast<unsigned char const*>( p ), n )
0618 {
0619 }
0620
0621 BOOST_HASH2_BLAKE2_CONSTEXPR blake2s_256( unsigned char const* p, std::size_t n )
0622 {
0623 if( n == 0 )
0624 {
0625 init();
0626 return;
0627 }
0628
0629 auto k = n;
0630 if( k > block_size / 2 )
0631 {
0632 k = block_size / 2;
0633 }
0634
0635 init( static_cast<std::uint32_t>( k ) );
0636 update( p, k );
0637 m_ = block_size;
0638
0639 p += k;
0640 n -= k;
0641
0642 if( n != 0 )
0643 {
0644 update( p, n );
0645 result();
0646 }
0647 }
0648
0649 void update( void const* pv, std::size_t n )
0650 {
0651 unsigned char const* p = reinterpret_cast<unsigned char const*>( pv );
0652 update( p, n );
0653 }
0654
0655 BOOST_HASH2_BLAKE2_CONSTEXPR void update( unsigned char const* p, std::size_t n )
0656 {
0657 if( n > 0 )
0658 {
0659 std::size_t k = block_size - m_;
0660 if( n > k )
0661 {
0662 detail::memcpy( b_ + m_, p, k );
0663 incr_len( block_size );
0664 transform( b_ );
0665 detail::memset( b_ , 0, block_size );
0666 p += k;
0667 n -= k;
0668 m_ = 0;
0669
0670 while( n > block_size )
0671 {
0672 incr_len( block_size );
0673 transform( p );
0674 p += block_size;
0675 n -= block_size;
0676 }
0677 }
0678
0679 detail::memcpy( b_ + m_, p, n );
0680 m_ += n;
0681 }
0682 }
0683
0684 BOOST_HASH2_BLAKE2_CONSTEXPR result_type result()
0685 {
0686 result_type digest;
0687
0688 incr_len( m_ );
0689 for( auto i = m_; i < block_size; ++i )
0690 {
0691 b_[ i ] = 0;
0692 }
0693
0694 transform( b_, true );
0695 detail::memset( b_ , 0, block_size );
0696 m_ = 0;
0697 for( int i = 0; i < 8; ++i )
0698 {
0699 detail::write32le( digest.data() + i * 4, h_[ i ] );
0700 }
0701 return digest;
0702 }
0703 };
0704
0705 using hmac_blake2b_512 = hmac<blake2b_512>;
0706 using hmac_blake2s_256 = hmac<blake2s_256>;
0707
0708 }
0709 }
0710
0711 #endif