@@ -268,11 +268,10 @@ native_finalize(state_t& state, const words_t& pad) NOEXCEPT
268268 unshuffle (lo, hi);
269269
270270 // digest is copied so that state remains valid (LE).
271- digest_t digest{};
272- auto & wdigest = array_cast<xint128_t >(digest);
271+ std::array<xint128_t , 2 > wdigest{};
273272 store (wdigest[0 ], byteswap<uint32_t >(lo));
274273 store (wdigest[1 ], byteswap<uint32_t >(hi));
275- return digest ;
274+ return array_cast< byte_t , sizeof ( digest_t )>(wdigest) ;
276275}
277276
278277TEMPLATE
@@ -285,7 +284,7 @@ native_finalize_second(const state_t& state) NOEXCEPT
285284 // Hash a state value and finalize it.
286285 auto state2 = H::get;
287286 words_t block{};
288- inject_left (block, state);
287+ inject_left_half (block, state);
289288 pad_half (block);
290289 return native_finalize (state2, block);
291290}
@@ -300,7 +299,7 @@ native_finalize_double(state_t& state, size_t blocks) NOEXCEPT
300299
301300 // This is native_finalize_second() but reuses the initial block.
302301 auto state2 = H::get;
303- inject_left (block, state);
302+ inject_left_half (block, state);
304303 pad_half (block);
305304 return native_finalize (state2, block);
306305}
@@ -338,8 +337,21 @@ native_hash(const half_t& left, const half_t& right) NOEXCEPT
338337{
339338 auto state = H::get;
340339 words_t block{};
341- inject_left (block, array_cast<word_t >(left));
342- inject_right (block, array_cast<word_t >(right));
340+ inject_left_half (block, array_cast<word_t >(left));
341+ inject_right_half (block, array_cast<word_t >(right));
342+ native_transform<true >(state, block);
343+ return native_finalize<one>(state);
344+ }
345+
346+ TEMPLATE
347+ typename CLASS::digest_t CLASS::
348+ native_hash (const quart_t & left, const quart_t & right) NOEXCEPT
349+ {
350+ auto state = H::get;
351+ words_t block{};
352+ inject_left_quarter (block, array_cast<word_t >(left));
353+ inject_right_quarter (block, array_cast<word_t >(right));
354+ pad_half (block);
343355 native_transform<true >(state, block);
344356 return native_finalize<one>(state);
345357}
@@ -350,11 +362,14 @@ native_hash(uint8_t byte) NOEXCEPT
350362{
351363 constexpr auto pad = bit_hi<uint8_t >;
352364
365+ auto state = H::get;
353366 block_t block{};
354- block.at (0 ) = byte;
355- block.at (1 ) = pad;
356- block.at (63 ) = byte_bits;
357- return native_hash (block);
367+
368+ // Order is based on array of little-endian uint32_t.
369+ block.at (3 ) = byte;
370+ block.at (2 ) = pad;
371+ block.at (60 ) = byte_bits;
372+ return native_finalize (state, array_cast<word_t >(block));
358373}
359374
360375// Double hash functions start with BE data and end with BE digest_t.
@@ -370,7 +385,7 @@ native_double_hash(const block_t& block) NOEXCEPT
370385
371386 // Second hash
372387 words_t block2{};
373- inject_left (block2, state);
388+ inject_left_half (block2, state);
374389 pad_half (block2);
375390 state = H::get;
376391 return native_finalize (state, block2);
@@ -388,7 +403,7 @@ native_double_hash(const half_t& half) NOEXCEPT
388403 native_transform<false >(state, block);
389404
390405 // Second hash
391- inject_left (block, state);
406+ inject_left_half (block, state);
392407 pad_half (block);
393408 state = H::get;
394409 return native_finalize (state, block);
@@ -400,13 +415,13 @@ native_double_hash(const half_t& left, const half_t& right) NOEXCEPT
400415{
401416 auto state = H::get;
402417 words_t block{};
403- inject_left (block, array_cast<word_t >(left));
404- inject_right (block, array_cast<word_t >(right));
418+ inject_left_half (block, array_cast<word_t >(left));
419+ inject_right_half (block, array_cast<word_t >(right));
405420 native_transform<true >(state, block);
406421 native_transform<false >(state, pad_block ());
407422
408423 // Second hash
409- inject_left (block, state);
424+ inject_left_half (block, state);
410425 pad_half (block);
411426 state = H::get;
412427 return native_finalize (state, block);
0 commit comments