2121
2222// Native (SHA-NI or NEON)
2323// ============================================================================
24- // The iterative method is used for sha native as it is an order of magnitude
25- // more efficient and cannot benefit from vectorization.
24+ // The rotating variables method is used for sha native. Tha native
25+ // instructions rely on register locality to achieve performance benefits.
26+ // Implementation of native sha using buffer expansion is horribly slow.
27+ // This split creates bifurcations (additional complexities) in this template.
2628
2729namespace libbitcoin {
2830namespace system {
@@ -98,9 +100,6 @@ round_4(xint128_t& state0, xint128_t& state1, xint128_t message) NOEXCEPT
98100
99101// Platform agnostic.
100102// ----------------------------------------------------------------------------
101- // Individual state vars are used vs. array to ensure register persistence.
102- // This creates bifurcations in this template because of the lack of a buffer
103- // and the differing optimal locations for applying endianness conversions.
104103
105104TEMPLATE
106105template <bool Swap>
@@ -223,6 +222,9 @@ native_transform(state_t& state, const auto& block) NOEXCEPT
223222// accumulation and performs big-endian conversion from state_t to digest_t.
224223// As padding blocks are generated and therefore do not require endianness
225224// conversion, those calls are not applied when transforming the pad block.
225+ // This lack of conversion also applies to double hashing. In both cases
226+ // the "inject" functions are using in place of the "input" functions.
227+ // There is no benefit to caching pading because it is not prescheduled.
226228// ----------------------------------------------------------------------------
227229
228230TEMPLATE
@@ -251,8 +253,6 @@ template <size_t Blocks>
251253typename CLASS::digest_t CLASS::
252254native_finalize (state_t & state) NOEXCEPT
253255{
254- // We could use Blocks to cache padding but given the padding blocks are
255- // unscheduled when performing native transformations there's no benefit.
256256 return native_finalize (state, Blocks);
257257}
258258
@@ -273,7 +273,7 @@ native_finalize_second(const state_t& state) NOEXCEPT
273273 // Hash a state value and finalize it.
274274 auto state2 = H::get;
275275 words_t block{};
276- reinput_left (block, state); // swapped
276+ inject_left (block, state); // swapped
277277 pad_half (block); // swapped
278278 return native_finalize (state2, block); // no block swap (swaps state)
279279}
@@ -288,7 +288,7 @@ native_finalize_double(state_t& state, size_t blocks) NOEXCEPT
288288
289289 // This is native_finalize_second() but reuses the initial block.
290290 auto state2 = H::get;
291- reinput_left (block, state); // swapped
291+ inject_left (block, state); // swapped
292292 pad_half (block); // swapped
293293 return native_finalize (state2, block); // no block swap (swaps state)
294294}
@@ -316,8 +316,8 @@ native_hash(const half_t& left, const half_t& right) NOEXCEPT
316316{
317317 auto state = H::get;
318318 words_t block{};
319- reinput_left (block, array_cast<word_t >(left)); // unswapped
320- reinput_right (block, array_cast<word_t >(right)); // unswapped
319+ inject_left (block, array_cast<word_t >(left)); // unswapped
320+ inject_right (block, array_cast<word_t >(right)); // unswapped
321321 native_transform<true >(state, block); // swap
322322 return native_finalize<one>(state); // no block swap (swaps state)
323323}
@@ -335,7 +335,7 @@ native_double_hash(const block_t& block) NOEXCEPT
335335
336336 // Second hash
337337 words_t block2{};
338- reinput_left (block2, state); // swapped
338+ inject_left (block2, state); // swapped
339339 pad_half (block2); // swapped
340340 state = H::get; // [reuse state var]
341341 return native_finalize (state, block2); // no block swap (swaps state)
@@ -352,7 +352,7 @@ native_double_hash(const half_t& half) NOEXCEPT
352352 native_transform<false >(state, block); // no block swap
353353
354354 // Second hash
355- reinput_left (block, state); // swapped
355+ inject_left (block, state); // swapped
356356 pad_half (block); // swapped
357357 state = H::get; // [reuse state var]
358358 return native_finalize (state, block); // no block swap (swaps state)
@@ -364,13 +364,13 @@ native_double_hash(const half_t& left, const half_t& right) NOEXCEPT
364364{
365365 auto state = H::get;
366366 words_t block{};
367- reinput_left (block, array_cast<word_t >(left)); // unswapped
368- reinput_right (block, array_cast<word_t >(right)); // unswapped
369- native_transform<true >(state, block); // swap
370- native_transform<false >(state, pad_block ()); // swapped
367+ inject_left (block, array_cast<word_t >(left)); // unswapped
368+ inject_right (block, array_cast<word_t >(right)); // unswapped
369+ native_transform<true >(state, block); // swap
370+ native_transform<false >(state, pad_block ()); // swapped
371371
372372 // Second hash
373- reinput_left (block, state); // swapped
373+ inject_left (block, state); // swapped
374374 pad_half (block); // swapped
375375 state = H::get; // [reuse state var]
376376 return native_finalize (state, block); // no block swap (swaps state)
0 commit comments