@@ -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,23 +337,38 @@ 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));
343342 native_transform<true >(state, block);
344343 return native_finalize<one>(state);
345344}
346345
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);
355+ return native_finalize (state, block);
356+ }
357+
347358TEMPLATE
348359typename CLASS::digest_t CLASS::
349360native_hash (uint8_t byte) NOEXCEPT
350361{
351362 constexpr auto pad = bit_hi<uint8_t >;
352363
364+ auto state = H::get;
353365 block_t block{};
354- block.at (0 ) = byte;
355- block.at (1 ) = pad;
356- block.at (63 ) = byte_bits;
357- return native_hash (block);
366+
367+ // Order is based on array of little-endian uint32_t.
368+ block.at (3 ) = byte;
369+ block.at (2 ) = pad;
370+ block.at (60 ) = byte_bits;
371+ return native_finalize (state, array_cast<word_t >(block));
358372}
359373
360374// Double hash functions start with BE data and end with BE digest_t.
@@ -370,7 +384,7 @@ native_double_hash(const block_t& block) NOEXCEPT
370384
371385 // Second hash
372386 words_t block2{};
373- inject_left (block2, state);
387+ inject_left_half (block2, state);
374388 pad_half (block2);
375389 state = H::get;
376390 return native_finalize (state, block2);
@@ -388,7 +402,7 @@ native_double_hash(const half_t& half) NOEXCEPT
388402 native_transform<false >(state, block);
389403
390404 // Second hash
391- inject_left (block, state);
405+ inject_left_half (block, state);
392406 pad_half (block);
393407 state = H::get;
394408 return native_finalize (state, block);
@@ -400,13 +414,13 @@ native_double_hash(const half_t& left, const half_t& right) NOEXCEPT
400414{
401415 auto state = H::get;
402416 words_t block{};
403- inject_left (block, array_cast<word_t >(left));
404- inject_right (block, array_cast<word_t >(right));
417+ inject_left_half (block, array_cast<word_t >(left));
418+ inject_right_half (block, array_cast<word_t >(right));
405419 native_transform<true >(state, block);
406420 native_transform<false >(state, pad_block ());
407421
408422 // Second hash
409- inject_left (block, state);
423+ inject_left_half (block, state);
410424 pad_half (block);
411425 state = H::get;
412426 return native_finalize (state, block);
0 commit comments