blake2.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. #ifndef BOOST_HASH2_BLAKE2_HPP_INCLUDED
  2. #define BOOST_HASH2_BLAKE2_HPP_INCLUDED
  3. // Copyright 2025 Christian Mazakas.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // https://www.boost.org/LICENSE_1_0.txt
  6. //
  7. #include <boost/hash2/digest.hpp>
  8. #include <boost/hash2/hmac.hpp>
  9. #include <boost/hash2/detail/is_constant_evaluated.hpp>
  10. #include <boost/hash2/detail/memcpy.hpp>
  11. #include <boost/hash2/detail/memset.hpp>
  12. #include <boost/hash2/detail/read.hpp>
  13. #include <boost/hash2/detail/rot.hpp>
  14. #include <boost/hash2/detail/write.hpp>
  15. #include <boost/assert.hpp>
  16. #include <boost/config.hpp>
  17. #include <boost/config/workaround.hpp>
  18. #include <cstdint>
  19. #if !defined(BOOST_HASH2_BLAKE2_CONSTEXPR)
  20. #if BOOST_WORKAROUND(BOOST_GCC, >= 50000 && BOOST_GCC < 60000)
  21. #define BOOST_HASH2_BLAKE2_CONSTEXPR
  22. #else
  23. #define BOOST_HASH2_BLAKE2_CONSTEXPR BOOST_CXX14_CONSTEXPR
  24. #endif
  25. #endif
  26. namespace boost
  27. {
  28. namespace hash2
  29. {
  30. namespace detail
  31. {
  32. template<class = void>
  33. struct blake2b_constants
  34. {
  35. constexpr static const std::uint64_t iv[ 8 ] =
  36. {
  37. 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
  38. 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
  39. 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
  40. 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
  41. };
  42. };
  43. template<class = void>
  44. struct blake2s_constants
  45. {
  46. constexpr static const std::uint32_t iv[ 8 ] =
  47. {
  48. 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  49. 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
  50. };
  51. };
  52. // copy-paste from Boost.Unordered's prime_fmod approach
  53. #if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
  54. // https://en.cppreference.com/w/cpp/language/static#Constant_static_members
  55. // If a const non-inline (since C++17) static data member or a constexpr
  56. // static data member (since C++11)(until C++17) is odr-used, a definition
  57. // at namespace scope is still required, but it cannot have an
  58. // initializer.
  59. template<class T>
  60. constexpr std::uint64_t blake2b_constants<T>::iv[ 8 ];
  61. template<class T>
  62. constexpr std::uint32_t blake2s_constants<T>::iv[ 8 ];
  63. #endif
  64. } // namespace detail
  65. class blake2b_512
  66. {
  67. private:
  68. unsigned char b_[ 128 ] = {};
  69. std::uint64_t h_[ 8 ] = {};
  70. std::uint64_t t_[ 2 ] = {};
  71. std::size_t m_ = 0;
  72. BOOST_HASH2_BLAKE2_CONSTEXPR void init( std::uint64_t keylen = 0 )
  73. {
  74. for( int i = 0; i < 8; ++i )
  75. {
  76. h_[ i ] = detail::blake2b_constants<>::iv[ i ];
  77. }
  78. std::uint64_t const outlen = 64;
  79. h_[ 0 ] ^= 0x01010000 ^ ( keylen << 8 ) ^ outlen;
  80. }
  81. 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 )
  82. {
  83. v[ a ] = v[ a ] + v[ b ] + x;
  84. v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 32 );
  85. v[ c ] = v[ c ] + v[ d ];
  86. v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 24 );
  87. v[ a ] = v[ a ] + v[ b ] + y;
  88. v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 16 );
  89. v[ c ] = v[ c ] + v[ d ];
  90. v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 63 );
  91. }
  92. BOOST_HASH2_BLAKE2_CONSTEXPR void transform( unsigned char const block[ 128 ], bool is_final = false )
  93. {
  94. auto iv = detail::blake2b_constants<>::iv;
  95. std::uint64_t v[ 16 ] = {};
  96. std::uint64_t m[ 16 ] = {};
  97. v[ 0 ] = h_[ 0 ];
  98. v[ 1 ] = h_[ 1 ];
  99. v[ 2 ] = h_[ 2 ];
  100. v[ 3 ] = h_[ 3 ];
  101. v[ 4 ] = h_[ 4 ];
  102. v[ 5 ] = h_[ 5 ];
  103. v[ 6 ] = h_[ 6 ];
  104. v[ 7 ] = h_[ 7 ];
  105. v[ 8 ] = iv[ 0 ];
  106. v[ 9 ] = iv[ 1 ];
  107. v[ 10 ] = iv[ 2 ];
  108. v[ 11 ] = iv[ 3 ];
  109. v[ 12 ] = iv[ 4 ];
  110. v[ 13 ] = iv[ 5 ];
  111. v[ 14 ] = iv[ 6 ];
  112. v[ 15 ] = iv[ 7 ];
  113. v[ 12 ] ^= t_[ 0 ];
  114. v[ 13 ] ^= t_[ 1 ];
  115. if( is_final )
  116. {
  117. v[ 14 ] = ~v[ 14 ];
  118. }
  119. for( int i = 0; i < 16; ++i )
  120. {
  121. m[ i ] = detail::read64le( block + 8 * i );
  122. }
  123. // round 0
  124. G( v, 0, 4, 8, 12, m[ 0 ], m[ 1 ] );
  125. G( v, 1, 5, 9, 13, m[ 2 ], m[ 3 ] );
  126. G( v, 2, 6, 10, 14, m[ 4 ], m[ 5 ] );
  127. G( v, 3, 7, 11, 15, m[ 6 ], m[ 7 ] );
  128. G( v, 0, 5, 10, 15, m[ 8 ], m[ 9 ] );
  129. G( v, 1, 6, 11, 12, m[ 10 ], m[ 11 ] );
  130. G( v, 2, 7, 8, 13, m[ 12 ], m[ 13 ] );
  131. G( v, 3, 4, 9, 14, m[ 14 ], m[ 15 ] );
  132. // round 1
  133. G( v, 0, 4, 8, 12, m[ 14 ], m[ 10 ] );
  134. G( v, 1, 5, 9, 13, m[ 4 ], m[ 8 ] );
  135. G( v, 2, 6, 10, 14, m[ 9 ], m[ 15 ] );
  136. G( v, 3, 7, 11, 15, m[ 13 ], m[ 6 ] );
  137. G( v, 0, 5, 10, 15, m[ 1 ], m[ 12 ] );
  138. G( v, 1, 6, 11, 12, m[ 0 ], m[ 2 ] );
  139. G( v, 2, 7, 8, 13, m[ 11 ], m[ 7 ] );
  140. G( v, 3, 4, 9, 14, m[ 5 ], m[ 3 ] );
  141. // round 2
  142. G( v, 0, 4, 8, 12, m[ 11 ], m[ 8 ] );
  143. G( v, 1, 5, 9, 13, m[ 12 ], m[ 0 ] );
  144. G( v, 2, 6, 10, 14, m[ 5 ], m[ 2 ] );
  145. G( v, 3, 7, 11, 15, m[ 15 ], m[ 13 ] );
  146. G( v, 0, 5, 10, 15, m[ 10 ], m[ 14 ] );
  147. G( v, 1, 6, 11, 12, m[ 3 ], m[ 6 ] );
  148. G( v, 2, 7, 8, 13, m[ 7 ], m[ 1 ] );
  149. G( v, 3, 4, 9, 14, m[ 9 ], m[ 4 ] );
  150. // round 3
  151. G( v, 0, 4, 8, 12, m[ 7 ], m[ 9 ] );
  152. G( v, 1, 5, 9, 13, m[ 3 ], m[ 1 ] );
  153. G( v, 2, 6, 10, 14, m[ 13 ], m[ 12 ] );
  154. G( v, 3, 7, 11, 15, m[ 11 ], m[ 14 ] );
  155. G( v, 0, 5, 10, 15, m[ 2 ], m[ 6 ] );
  156. G( v, 1, 6, 11, 12, m[ 5 ], m[ 10 ] );
  157. G( v, 2, 7, 8, 13, m[ 4 ], m[ 0 ] );
  158. G( v, 3, 4, 9, 14, m[ 15 ], m[ 8 ] );
  159. // round 4
  160. G( v, 0, 4, 8, 12, m[ 9 ], m[ 0 ] );
  161. G( v, 1, 5, 9, 13, m[ 5 ], m[ 7 ] );
  162. G( v, 2, 6, 10, 14, m[ 2 ], m[ 4 ] );
  163. G( v, 3, 7, 11, 15, m[ 10 ], m[ 15 ] );
  164. G( v, 0, 5, 10, 15, m[ 14 ], m[ 1 ] );
  165. G( v, 1, 6, 11, 12, m[ 11 ], m[ 12 ] );
  166. G( v, 2, 7, 8, 13, m[ 6 ], m[ 8 ] );
  167. G( v, 3, 4, 9, 14, m[ 3 ], m[ 13 ] );
  168. // round 5
  169. G( v, 0, 4, 8, 12, m[ 2 ], m[ 12 ] );
  170. G( v, 1, 5, 9, 13, m[ 6 ], m[ 10 ] );
  171. G( v, 2, 6, 10, 14, m[ 0 ], m[ 11 ] );
  172. G( v, 3, 7, 11, 15, m[ 8 ], m[ 3 ] );
  173. G( v, 0, 5, 10, 15, m[ 4 ], m[ 13 ] );
  174. G( v, 1, 6, 11, 12, m[ 7 ], m[ 5 ] );
  175. G( v, 2, 7, 8, 13, m[ 15 ], m[ 14 ] );
  176. G( v, 3, 4, 9, 14, m[ 1 ], m[ 9 ] );
  177. // round 6
  178. G( v, 0, 4, 8, 12, m[ 12 ], m[ 5 ] );
  179. G( v, 1, 5, 9, 13, m[ 1 ], m[ 15 ] );
  180. G( v, 2, 6, 10, 14, m[ 14 ], m[ 13 ] );
  181. G( v, 3, 7, 11, 15, m[ 4 ], m[ 10 ] );
  182. G( v, 0, 5, 10, 15, m[ 0 ], m[ 7 ] );
  183. G( v, 1, 6, 11, 12, m[ 6 ], m[ 3 ] );
  184. G( v, 2, 7, 8, 13, m[ 9 ], m[ 2 ] );
  185. G( v, 3, 4, 9, 14, m[ 8 ], m[ 11 ] );
  186. // round 7
  187. G( v, 0, 4, 8, 12, m[ 13 ], m[ 11 ] );
  188. G( v, 1, 5, 9, 13, m[ 7 ], m[ 14 ] );
  189. G( v, 2, 6, 10, 14, m[ 12 ], m[ 1 ] );
  190. G( v, 3, 7, 11, 15, m[ 3 ], m[ 9 ] );
  191. G( v, 0, 5, 10, 15, m[ 5 ], m[ 0 ] );
  192. G( v, 1, 6, 11, 12, m[ 15 ], m[ 4 ] );
  193. G( v, 2, 7, 8, 13, m[ 8 ], m[ 6 ] );
  194. G( v, 3, 4, 9, 14, m[ 2 ], m[ 10 ] );
  195. // round 8
  196. G( v, 0, 4, 8, 12, m[ 6 ], m[ 15 ] );
  197. G( v, 1, 5, 9, 13, m[ 14 ], m[ 9 ] );
  198. G( v, 2, 6, 10, 14, m[ 11 ], m[ 3 ] );
  199. G( v, 3, 7, 11, 15, m[ 0 ], m[ 8 ] );
  200. G( v, 0, 5, 10, 15, m[ 12 ], m[ 2 ] );
  201. G( v, 1, 6, 11, 12, m[ 13 ], m[ 7 ] );
  202. G( v, 2, 7, 8, 13, m[ 1 ], m[ 4 ] );
  203. G( v, 3, 4, 9, 14, m[ 10 ], m[ 5 ] );
  204. // round 9
  205. G( v, 0, 4, 8, 12, m[ 10 ], m[ 2 ] );
  206. G( v, 1, 5, 9, 13, m[ 8 ], m[ 4 ] );
  207. G( v, 2, 6, 10, 14, m[ 7 ], m[ 6 ] );
  208. G( v, 3, 7, 11, 15, m[ 1 ], m[ 5 ] );
  209. G( v, 0, 5, 10, 15, m[ 15 ], m[ 11 ] );
  210. G( v, 1, 6, 11, 12, m[ 9 ], m[ 14 ] );
  211. G( v, 2, 7, 8, 13, m[ 3 ], m[ 12 ] );
  212. G( v, 3, 4, 9, 14, m[ 13 ], m[ 0 ] );
  213. // round 10
  214. G( v, 0, 4, 8, 12, m[ 0 ], m[ 1 ] );
  215. G( v, 1, 5, 9, 13, m[ 2 ], m[ 3 ] );
  216. G( v, 2, 6, 10, 14, m[ 4 ], m[ 5 ] );
  217. G( v, 3, 7, 11, 15, m[ 6 ], m[ 7 ] );
  218. G( v, 0, 5, 10, 15, m[ 8 ], m[ 9 ] );
  219. G( v, 1, 6, 11, 12, m[ 10 ], m[ 11 ] );
  220. G( v, 2, 7, 8, 13, m[ 12 ], m[ 13 ] );
  221. G( v, 3, 4, 9, 14, m[ 14 ], m[ 15 ] );
  222. // round 11
  223. G( v, 0, 4, 8, 12, m[ 14 ], m[ 10 ] );
  224. G( v, 1, 5, 9, 13, m[ 4 ], m[ 8 ] );
  225. G( v, 2, 6, 10, 14, m[ 9 ], m[ 15 ] );
  226. G( v, 3, 7, 11, 15, m[ 13 ], m[ 6 ] );
  227. G( v, 0, 5, 10, 15, m[ 1 ], m[ 12 ] );
  228. G( v, 1, 6, 11, 12, m[ 0 ], m[ 2 ] );
  229. G( v, 2, 7, 8, 13, m[ 11 ], m[ 7 ] );
  230. G( v, 3, 4, 9, 14, m[ 5 ], m[ 3 ] );
  231. h_[ 0 ] ^= v[ 0 ] ^ v[ 0 + 8 ];
  232. h_[ 1 ] ^= v[ 1 ] ^ v[ 1 + 8 ];
  233. h_[ 2 ] ^= v[ 2 ] ^ v[ 2 + 8 ];
  234. h_[ 3 ] ^= v[ 3 ] ^ v[ 3 + 8 ];
  235. h_[ 4 ] ^= v[ 4 ] ^ v[ 4 + 8 ];
  236. h_[ 5 ] ^= v[ 5 ] ^ v[ 5 + 8 ];
  237. h_[ 6 ] ^= v[ 6 ] ^ v[ 6 + 8 ];
  238. h_[ 7 ] ^= v[ 7 ] ^ v[ 7 + 8 ];
  239. }
  240. BOOST_HASH2_BLAKE2_CONSTEXPR BOOST_FORCEINLINE void incr_len( std::size_t n )
  241. {
  242. t_[ 0 ] += n;
  243. t_[ 1 ] += ( t_[ 0 ] < n ); // overflowed
  244. }
  245. public:
  246. using result_type = digest<64>;
  247. static constexpr std::size_t block_size = 128;
  248. BOOST_HASH2_BLAKE2_CONSTEXPR blake2b_512()
  249. {
  250. init();
  251. }
  252. BOOST_HASH2_BLAKE2_CONSTEXPR explicit blake2b_512( std::uint64_t seed )
  253. {
  254. if( seed == 0 )
  255. {
  256. init();
  257. return;
  258. }
  259. unsigned char tmp[ 8 ] = {};
  260. detail::write64le( tmp, seed );
  261. init( 8 );
  262. update( tmp, 8 );
  263. m_ = block_size;
  264. }
  265. blake2b_512( void const* p, std::size_t n ) : blake2b_512( static_cast<unsigned char const*>( p ), n )
  266. {
  267. }
  268. BOOST_HASH2_BLAKE2_CONSTEXPR blake2b_512( unsigned char const* p, std::size_t n )
  269. {
  270. if( n == 0 )
  271. {
  272. init();
  273. return;
  274. }
  275. auto k = n;
  276. if( k > block_size / 2 )
  277. {
  278. k = block_size / 2;
  279. }
  280. init( k );
  281. update( p, k );
  282. m_ = block_size;
  283. p += k;
  284. n -= k;
  285. if( n != 0 )
  286. {
  287. update( p, n );
  288. result();
  289. }
  290. }
  291. void update( void const* pv, std::size_t n )
  292. {
  293. unsigned char const* p = reinterpret_cast<unsigned char const*>( pv );
  294. update( p, n );
  295. }
  296. BOOST_HASH2_BLAKE2_CONSTEXPR void update( unsigned char const* p, std::size_t n )
  297. {
  298. if( n > 0 )
  299. {
  300. std::size_t k = block_size - m_;
  301. if( n > k )
  302. {
  303. detail::memcpy( b_ + m_, p, k );
  304. incr_len( block_size );
  305. transform( b_ );
  306. detail::memset( b_ , 0, block_size );
  307. p += k;
  308. n -= k;
  309. m_ = 0;
  310. while( n > block_size )
  311. {
  312. incr_len( block_size );
  313. transform( p );
  314. p += block_size;
  315. n -= block_size;
  316. }
  317. }
  318. detail::memcpy( b_ + m_, p, n );
  319. m_ += n;
  320. }
  321. }
  322. BOOST_HASH2_BLAKE2_CONSTEXPR result_type result()
  323. {
  324. result_type digest;
  325. incr_len( m_ );
  326. for( auto i = m_; i < block_size; ++i )
  327. {
  328. b_[ i ] = 0;
  329. }
  330. transform( b_, true );
  331. detail::memset( b_ , 0, block_size );
  332. m_ = 0;
  333. for( int i = 0; i < 8; ++i )
  334. {
  335. detail::write64le( digest.data() + i * 8, h_[ i ] );
  336. }
  337. return digest;
  338. }
  339. };
  340. class blake2s_256
  341. {
  342. private:
  343. unsigned char b_[ 64 ] = {};
  344. std::uint32_t h_[ 8 ] = {};
  345. std::uint32_t t_[ 2 ] = {};
  346. std::size_t m_ = 0;
  347. BOOST_HASH2_BLAKE2_CONSTEXPR void init( std::uint32_t keylen = 0 )
  348. {
  349. for( int i = 0; i < 8; ++i )
  350. {
  351. h_[ i ] = detail::blake2s_constants<>::iv[ i ];
  352. }
  353. std::uint32_t const outlen = 32;
  354. h_[ 0 ] ^= 0x01010000 ^ ( keylen << 8 ) ^ outlen;
  355. }
  356. 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 )
  357. {
  358. v[ a ] = v[ a ] + v[ b ] + x;
  359. v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 16 );
  360. v[ c ] = v[ c ] + v[ d ];
  361. v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 12 );
  362. v[ a ] = v[ a ] + v[ b ] + y;
  363. v[ d ] = detail::rotr( v[ d ] ^ v[ a ], 8 );
  364. v[ c ] = v[ c ] + v[ d ];
  365. v[ b ] = detail::rotr( v[ b ] ^ v[ c ], 7 );
  366. }
  367. BOOST_HASH2_BLAKE2_CONSTEXPR void transform( unsigned char const block[ 64 ], bool is_final = false )
  368. {
  369. auto iv = detail::blake2s_constants<>::iv;
  370. std::uint32_t v[ 16 ] = {};
  371. std::uint32_t m[ 16 ] = {};
  372. v[ 0 ] = h_[ 0 ];
  373. v[ 1 ] = h_[ 1 ];
  374. v[ 2 ] = h_[ 2 ];
  375. v[ 3 ] = h_[ 3 ];
  376. v[ 4 ] = h_[ 4 ];
  377. v[ 5 ] = h_[ 5 ];
  378. v[ 6 ] = h_[ 6 ];
  379. v[ 7 ] = h_[ 7 ];
  380. v[ 8 ] = iv[ 0 ];
  381. v[ 9 ] = iv[ 1 ];
  382. v[ 10 ] = iv[ 2 ];
  383. v[ 11 ] = iv[ 3 ];
  384. v[ 12 ] = iv[ 4 ];
  385. v[ 13 ] = iv[ 5 ];
  386. v[ 14 ] = iv[ 6 ];
  387. v[ 15 ] = iv[ 7 ];
  388. v[ 12 ] ^= t_[ 0 ];
  389. v[ 13 ] ^= t_[ 1 ];
  390. if( is_final )
  391. {
  392. v[ 14 ] = ~v[ 14 ];
  393. }
  394. for( int i = 0; i < 16; ++i )
  395. {
  396. m[ i ] = detail::read32le( block + 4 * i );
  397. }
  398. // round 0
  399. G( v, 0, 4, 8, 12, m[ 0 ], m[ 1 ] );
  400. G( v, 1, 5, 9, 13, m[ 2 ], m[ 3 ] );
  401. G( v, 2, 6, 10, 14, m[ 4 ], m[ 5 ] );
  402. G( v, 3, 7, 11, 15, m[ 6 ], m[ 7 ] );
  403. G( v, 0, 5, 10, 15, m[ 8 ], m[ 9 ] );
  404. G( v, 1, 6, 11, 12, m[ 10 ], m[ 11 ] );
  405. G( v, 2, 7, 8, 13, m[ 12 ], m[ 13 ] );
  406. G( v, 3, 4, 9, 14, m[ 14 ], m[ 15 ] );
  407. // round 1
  408. G( v, 0, 4, 8, 12, m[ 14 ], m[ 10 ] );
  409. G( v, 1, 5, 9, 13, m[ 4 ], m[ 8 ] );
  410. G( v, 2, 6, 10, 14, m[ 9 ], m[ 15 ] );
  411. G( v, 3, 7, 11, 15, m[ 13 ], m[ 6 ] );
  412. G( v, 0, 5, 10, 15, m[ 1 ], m[ 12 ] );
  413. G( v, 1, 6, 11, 12, m[ 0 ], m[ 2 ] );
  414. G( v, 2, 7, 8, 13, m[ 11 ], m[ 7 ] );
  415. G( v, 3, 4, 9, 14, m[ 5 ], m[ 3 ] );
  416. // round 2
  417. G( v, 0, 4, 8, 12, m[ 11 ], m[ 8 ] );
  418. G( v, 1, 5, 9, 13, m[ 12 ], m[ 0 ] );
  419. G( v, 2, 6, 10, 14, m[ 5 ], m[ 2 ] );
  420. G( v, 3, 7, 11, 15, m[ 15 ], m[ 13 ] );
  421. G( v, 0, 5, 10, 15, m[ 10 ], m[ 14 ] );
  422. G( v, 1, 6, 11, 12, m[ 3 ], m[ 6 ] );
  423. G( v, 2, 7, 8, 13, m[ 7 ], m[ 1 ] );
  424. G( v, 3, 4, 9, 14, m[ 9 ], m[ 4 ] );
  425. // round 3
  426. G( v, 0, 4, 8, 12, m[ 7 ], m[ 9 ] );
  427. G( v, 1, 5, 9, 13, m[ 3 ], m[ 1 ] );
  428. G( v, 2, 6, 10, 14, m[ 13 ], m[ 12 ] );
  429. G( v, 3, 7, 11, 15, m[ 11 ], m[ 14 ] );
  430. G( v, 0, 5, 10, 15, m[ 2 ], m[ 6 ] );
  431. G( v, 1, 6, 11, 12, m[ 5 ], m[ 10 ] );
  432. G( v, 2, 7, 8, 13, m[ 4 ], m[ 0 ] );
  433. G( v, 3, 4, 9, 14, m[ 15 ], m[ 8 ] );
  434. // round 4
  435. G( v, 0, 4, 8, 12, m[ 9 ], m[ 0 ] );
  436. G( v, 1, 5, 9, 13, m[ 5 ], m[ 7 ] );
  437. G( v, 2, 6, 10, 14, m[ 2 ], m[ 4 ] );
  438. G( v, 3, 7, 11, 15, m[ 10 ], m[ 15 ] );
  439. G( v, 0, 5, 10, 15, m[ 14 ], m[ 1 ] );
  440. G( v, 1, 6, 11, 12, m[ 11 ], m[ 12 ] );
  441. G( v, 2, 7, 8, 13, m[ 6 ], m[ 8 ] );
  442. G( v, 3, 4, 9, 14, m[ 3 ], m[ 13 ] );
  443. // round 5
  444. G( v, 0, 4, 8, 12, m[ 2 ], m[ 12 ] );
  445. G( v, 1, 5, 9, 13, m[ 6 ], m[ 10 ] );
  446. G( v, 2, 6, 10, 14, m[ 0 ], m[ 11 ] );
  447. G( v, 3, 7, 11, 15, m[ 8 ], m[ 3 ] );
  448. G( v, 0, 5, 10, 15, m[ 4 ], m[ 13 ] );
  449. G( v, 1, 6, 11, 12, m[ 7 ], m[ 5 ] );
  450. G( v, 2, 7, 8, 13, m[ 15 ], m[ 14 ] );
  451. G( v, 3, 4, 9, 14, m[ 1 ], m[ 9 ] );
  452. // round 6
  453. G( v, 0, 4, 8, 12, m[ 12 ], m[ 5 ] );
  454. G( v, 1, 5, 9, 13, m[ 1 ], m[ 15 ] );
  455. G( v, 2, 6, 10, 14, m[ 14 ], m[ 13 ] );
  456. G( v, 3, 7, 11, 15, m[ 4 ], m[ 10 ] );
  457. G( v, 0, 5, 10, 15, m[ 0 ], m[ 7 ] );
  458. G( v, 1, 6, 11, 12, m[ 6 ], m[ 3 ] );
  459. G( v, 2, 7, 8, 13, m[ 9 ], m[ 2 ] );
  460. G( v, 3, 4, 9, 14, m[ 8 ], m[ 11 ] );
  461. // round 7
  462. G( v, 0, 4, 8, 12, m[ 13 ], m[ 11 ] );
  463. G( v, 1, 5, 9, 13, m[ 7 ], m[ 14 ] );
  464. G( v, 2, 6, 10, 14, m[ 12 ], m[ 1 ] );
  465. G( v, 3, 7, 11, 15, m[ 3 ], m[ 9 ] );
  466. G( v, 0, 5, 10, 15, m[ 5 ], m[ 0 ] );
  467. G( v, 1, 6, 11, 12, m[ 15 ], m[ 4 ] );
  468. G( v, 2, 7, 8, 13, m[ 8 ], m[ 6 ] );
  469. G( v, 3, 4, 9, 14, m[ 2 ], m[ 10 ] );
  470. // round 8
  471. G( v, 0, 4, 8, 12, m[ 6 ], m[ 15 ] );
  472. G( v, 1, 5, 9, 13, m[ 14 ], m[ 9 ] );
  473. G( v, 2, 6, 10, 14, m[ 11 ], m[ 3 ] );
  474. G( v, 3, 7, 11, 15, m[ 0 ], m[ 8 ] );
  475. G( v, 0, 5, 10, 15, m[ 12 ], m[ 2 ] );
  476. G( v, 1, 6, 11, 12, m[ 13 ], m[ 7 ] );
  477. G( v, 2, 7, 8, 13, m[ 1 ], m[ 4 ] );
  478. G( v, 3, 4, 9, 14, m[ 10 ], m[ 5 ] );
  479. // round 9
  480. G( v, 0, 4, 8, 12, m[ 10 ], m[ 2 ] );
  481. G( v, 1, 5, 9, 13, m[ 8 ], m[ 4 ] );
  482. G( v, 2, 6, 10, 14, m[ 7 ], m[ 6 ] );
  483. G( v, 3, 7, 11, 15, m[ 1 ], m[ 5 ] );
  484. G( v, 0, 5, 10, 15, m[ 15 ], m[ 11 ] );
  485. G( v, 1, 6, 11, 12, m[ 9 ], m[ 14 ] );
  486. G( v, 2, 7, 8, 13, m[ 3 ], m[ 12 ] );
  487. G( v, 3, 4, 9, 14, m[ 13 ], m[ 0 ] );
  488. h_[ 0 ] ^= v[ 0 ] ^ v[ 0 + 8 ];
  489. h_[ 1 ] ^= v[ 1 ] ^ v[ 1 + 8 ];
  490. h_[ 2 ] ^= v[ 2 ] ^ v[ 2 + 8 ];
  491. h_[ 3 ] ^= v[ 3 ] ^ v[ 3 + 8 ];
  492. h_[ 4 ] ^= v[ 4 ] ^ v[ 4 + 8 ];
  493. h_[ 5 ] ^= v[ 5 ] ^ v[ 5 + 8 ];
  494. h_[ 6 ] ^= v[ 6 ] ^ v[ 6 + 8 ];
  495. h_[ 7 ] ^= v[ 7 ] ^ v[ 7 + 8 ];
  496. }
  497. BOOST_HASH2_BLAKE2_CONSTEXPR void incr_len( std::size_t n )
  498. {
  499. auto m = static_cast<std::uint32_t>( n );
  500. t_[ 0 ] += m;
  501. t_[ 1 ] += ( t_[ 0 ] < m ); // overflowed
  502. }
  503. public:
  504. using result_type = digest<32>;
  505. static constexpr std::size_t block_size = 64;
  506. BOOST_HASH2_BLAKE2_CONSTEXPR blake2s_256()
  507. {
  508. init();
  509. }
  510. BOOST_HASH2_BLAKE2_CONSTEXPR explicit blake2s_256( std::uint64_t seed )
  511. {
  512. if( seed == 0 )
  513. {
  514. init();
  515. return;
  516. }
  517. unsigned char tmp[ 8 ] = {};
  518. detail::write64le( tmp, seed );
  519. init( 8 );
  520. update( tmp, 8 );
  521. m_ = block_size;
  522. }
  523. blake2s_256( void const* p, std::size_t n ) : blake2s_256( static_cast<unsigned char const*>( p ), n )
  524. {
  525. }
  526. BOOST_HASH2_BLAKE2_CONSTEXPR blake2s_256( unsigned char const* p, std::size_t n )
  527. {
  528. if( n == 0 )
  529. {
  530. init();
  531. return;
  532. }
  533. auto k = n;
  534. if( k > block_size / 2 )
  535. {
  536. k = block_size / 2;
  537. }
  538. init( static_cast<std::uint32_t>( k ) );
  539. update( p, k );
  540. m_ = block_size;
  541. p += k;
  542. n -= k;
  543. if( n != 0 )
  544. {
  545. update( p, n );
  546. result();
  547. }
  548. }
  549. void update( void const* pv, std::size_t n )
  550. {
  551. unsigned char const* p = reinterpret_cast<unsigned char const*>( pv );
  552. update( p, n );
  553. }
  554. BOOST_HASH2_BLAKE2_CONSTEXPR void update( unsigned char const* p, std::size_t n )
  555. {
  556. if( n > 0 )
  557. {
  558. std::size_t k = block_size - m_;
  559. if( n > k )
  560. {
  561. detail::memcpy( b_ + m_, p, k );
  562. incr_len( block_size );
  563. transform( b_ );
  564. detail::memset( b_ , 0, block_size );
  565. p += k;
  566. n -= k;
  567. m_ = 0;
  568. while( n > block_size )
  569. {
  570. incr_len( block_size );
  571. transform( p );
  572. p += block_size;
  573. n -= block_size;
  574. }
  575. }
  576. detail::memcpy( b_ + m_, p, n );
  577. m_ += n;
  578. }
  579. }
  580. BOOST_HASH2_BLAKE2_CONSTEXPR result_type result()
  581. {
  582. result_type digest;
  583. incr_len( m_ );
  584. for( auto i = m_; i < block_size; ++i )
  585. {
  586. b_[ i ] = 0;
  587. }
  588. transform( b_, true );
  589. detail::memset( b_ , 0, block_size );
  590. m_ = 0;
  591. for( int i = 0; i < 8; ++i )
  592. {
  593. detail::write32le( digest.data() + i * 4, h_[ i ] );
  594. }
  595. return digest;
  596. }
  597. };
  598. using hmac_blake2b_512 = hmac<blake2b_512>;
  599. using hmac_blake2s_256 = hmac<blake2s_256>;
  600. } // namespace hash2
  601. } // namespace boost
  602. #endif // BOOST_HASH2_BLAKE2_HPP_INCLUDED