mirror of
https://github.com/JayDDee/cpuminer-opt.git
synced 2025-09-17 23:44:27 +00:00
1454 lines
65 KiB
C
1454 lines
65 KiB
C
#include "sha256-hash.h"
|
|
|
|
static const uint32_t SHA256_IV[8] =
|
|
{
|
|
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
|
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
|
|
};
|
|
|
|
#if defined(__SHA__)
|
|
|
|
void sha256_opt_transform_le( uint32_t *state_out, const void *input,
|
|
const uint32_t *state_in )
|
|
{
|
|
__m128i STATE0, STATE1;
|
|
__m128i MSG, TMP;
|
|
__m128i TMSG0, TMSG1, TMSG2, TMSG3;
|
|
__m128i ABEF_SAVE, CDGH_SAVE;
|
|
|
|
// Load initial values
|
|
TMP = _mm_load_si128((__m128i*) &state_in[0]);
|
|
STATE1 = _mm_load_si128((__m128i*) &state_in[4]);
|
|
|
|
TMP = _mm_shuffle_epi32(TMP, 0xB1); // CDAB
|
|
STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); // EFGH
|
|
STATE0 = _mm_alignr_epi8(TMP, STATE1, 8); // ABEF
|
|
STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0); // CDGH
|
|
|
|
// Save current hash
|
|
ABEF_SAVE = STATE0;
|
|
CDGH_SAVE = STATE1;
|
|
|
|
// Rounds 0-3
|
|
TMSG0 = _mm_load_si128((const __m128i*) (input+0));
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Rounds 4-7
|
|
TMSG1 = _mm_load_si128((const __m128i*) (input+16));
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1);
|
|
|
|
|
|
// Rounds 8-11
|
|
TMSG2 = _mm_load_si128((const __m128i*) (input+32));
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2);
|
|
|
|
// Rounds 12-15
|
|
TMSG3 = _mm_load_si128((const __m128i*) (input+48));
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4);
|
|
TMSG0 = _mm_add_epi32(TMSG0, TMP);
|
|
TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3);
|
|
|
|
// Rounds 16-19
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4);
|
|
TMSG1 = _mm_add_epi32(TMSG1, TMP);
|
|
TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0);
|
|
|
|
// Rounds 20-23
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4);
|
|
TMSG2 = _mm_add_epi32(TMSG2, TMP);
|
|
TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1);
|
|
|
|
// Rounds 24-27
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4);
|
|
TMSG3 = _mm_add_epi32(TMSG3, TMP);
|
|
TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2);
|
|
|
|
// Rounds 28-31
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4);
|
|
TMSG0 = _mm_add_epi32(TMSG0, TMP);
|
|
TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3);
|
|
|
|
// Rounds 32-35
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4);
|
|
TMSG1 = _mm_add_epi32(TMSG1, TMP);
|
|
TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0);
|
|
|
|
// Rounds 36-39
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4);
|
|
TMSG2 = _mm_add_epi32(TMSG2, TMP);
|
|
TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1);
|
|
|
|
// Rounds 40-43
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4);
|
|
TMSG3 = _mm_add_epi32(TMSG3, TMP);
|
|
TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2);
|
|
|
|
// Rounds 44-47
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4);
|
|
TMSG0 = _mm_add_epi32(TMSG0, TMP);
|
|
TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3);
|
|
|
|
// Rounds 48-51
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4);
|
|
TMSG1 = _mm_add_epi32(TMSG1, TMP);
|
|
TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0);
|
|
|
|
// Rounds 52-55
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4);
|
|
TMSG2 = _mm_add_epi32(TMSG2, TMP);
|
|
TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Rounds 56-59
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4);
|
|
TMSG3 = _mm_add_epi32(TMSG3, TMP);
|
|
TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Rounds 60-63
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Add values back to state
|
|
STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE);
|
|
STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE);
|
|
|
|
TMP = _mm_shuffle_epi32(STATE0, 0x1B); // FEBA
|
|
STATE1 = _mm_shuffle_epi32(STATE1, 0xB1); // DCHG
|
|
STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0); // DCBA
|
|
STATE1 = _mm_alignr_epi8(STATE1, TMP, 8); // ABEF
|
|
|
|
// Save state
|
|
_mm_store_si128((__m128i*) &state_out[0], STATE0);
|
|
_mm_store_si128((__m128i*) &state_out[4], STATE1);
|
|
}
|
|
|
|
|
|
void sha256_opt_transform_be( uint32_t *state_out, const void *input,
|
|
const uint32_t *state_in )
|
|
{
|
|
__m128i STATE0, STATE1;
|
|
__m128i MSG, TMP, MASK;
|
|
__m128i TMSG0, TMSG1, TMSG2, TMSG3;
|
|
__m128i ABEF_SAVE, CDGH_SAVE;
|
|
|
|
// Load initial values
|
|
TMP = _mm_load_si128((__m128i*) &state_in[0]);
|
|
STATE1 = _mm_load_si128((__m128i*) &state_in[4]);
|
|
MASK = _mm_set_epi64x(0x0c0d0e0f08090a0bULL, 0x0405060700010203ULL);
|
|
|
|
TMP = _mm_shuffle_epi32(TMP, 0xB1); // CDAB
|
|
STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); // EFGH
|
|
STATE0 = _mm_alignr_epi8(TMP, STATE1, 8); // ABEF
|
|
STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0); // CDGH
|
|
|
|
// Save current hash
|
|
ABEF_SAVE = STATE0;
|
|
CDGH_SAVE = STATE1;
|
|
|
|
// Rounds 0-3
|
|
TMSG0 = _mm_load_si128((const __m128i*) (input+0));
|
|
TMSG0 = _mm_shuffle_epi8( TMSG0, MASK );
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Rounds 4-7
|
|
TMSG1 = _mm_load_si128((const __m128i*) (input+16));
|
|
TMSG1 = _mm_shuffle_epi8(TMSG1, MASK);
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1);
|
|
// Rounds 8-11
|
|
TMSG2 = _mm_load_si128((const __m128i*) (input+32));
|
|
TMSG2 = _mm_shuffle_epi8(TMSG2, MASK);
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2);
|
|
|
|
// Rounds 12-15
|
|
TMSG3 = _mm_load_si128((const __m128i*) (input+48));
|
|
TMSG3 = _mm_shuffle_epi8(TMSG3, MASK);
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4);
|
|
TMSG0 = _mm_add_epi32(TMSG0, TMP);
|
|
TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3);
|
|
|
|
// Rounds 16-19
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4);
|
|
TMSG1 = _mm_add_epi32(TMSG1, TMP);
|
|
TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0);
|
|
|
|
// Rounds 20-23
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4);
|
|
TMSG2 = _mm_add_epi32(TMSG2, TMP);
|
|
TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1);
|
|
|
|
// Rounds 24-27
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4);
|
|
TMSG3 = _mm_add_epi32(TMSG3, TMP);
|
|
TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2);
|
|
|
|
// Rounds 28-31
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4);
|
|
TMSG0 = _mm_add_epi32(TMSG0, TMP);
|
|
TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3);
|
|
|
|
// Rounds 32-35
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4);
|
|
TMSG1 = _mm_add_epi32(TMSG1, TMP);
|
|
TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0);
|
|
|
|
// Rounds 36-39
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4);
|
|
TMSG2 = _mm_add_epi32(TMSG2, TMP);
|
|
TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG0 = _mm_sha256msg1_epu32(TMSG0, TMSG1);
|
|
|
|
// Rounds 40-43
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4);
|
|
TMSG3 = _mm_add_epi32(TMSG3, TMP);
|
|
TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG1 = _mm_sha256msg1_epu32(TMSG1, TMSG2);
|
|
|
|
// Rounds 44-47
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG3, TMSG2, 4);
|
|
TMSG0 = _mm_add_epi32(TMSG0, TMP);
|
|
TMSG0 = _mm_sha256msg2_epu32(TMSG0, TMSG3);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG2 = _mm_sha256msg1_epu32(TMSG2, TMSG3);
|
|
|
|
// Rounds 48-51
|
|
MSG = _mm_add_epi32(TMSG0, _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG0, TMSG3, 4);
|
|
TMSG1 = _mm_add_epi32(TMSG1, TMP);
|
|
TMSG1 = _mm_sha256msg2_epu32(TMSG1, TMSG0);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
TMSG3 = _mm_sha256msg1_epu32(TMSG3, TMSG0);
|
|
|
|
// Rounds 52-55
|
|
MSG = _mm_add_epi32(TMSG1, _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG1, TMSG0, 4);
|
|
TMSG2 = _mm_add_epi32(TMSG2, TMP);
|
|
TMSG2 = _mm_sha256msg2_epu32(TMSG2, TMSG1);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Rounds 56-59
|
|
MSG = _mm_add_epi32(TMSG2, _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
TMP = _mm_alignr_epi8(TMSG2, TMSG1, 4);
|
|
TMSG3 = _mm_add_epi32(TMSG3, TMP);
|
|
TMSG3 = _mm_sha256msg2_epu32(TMSG3, TMSG2);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Rounds 60-63
|
|
MSG = _mm_add_epi32(TMSG3, _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL));
|
|
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
|
|
MSG = _mm_shuffle_epi32(MSG, 0x0E);
|
|
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
|
|
|
|
// Add values back to state
|
|
STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE);
|
|
STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE);
|
|
|
|
TMP = _mm_shuffle_epi32(STATE0, 0x1B); // FEBA
|
|
STATE1 = _mm_shuffle_epi32(STATE1, 0xB1); // DCHG
|
|
STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0); // DCBA
|
|
STATE1 = _mm_alignr_epi8(STATE1, TMP, 8); // ABEF
|
|
|
|
// Save state
|
|
_mm_store_si128((__m128i*) &state_out[0], STATE0);
|
|
_mm_store_si128((__m128i*) &state_out[4], STATE1);
|
|
}
|
|
|
|
// 2 way double buffered
|
|
|
|
void sha256_ni2way_transform_le( uint32_t *out_X, uint32_t*out_Y,
|
|
const void *msg_X, const void *msg_Y,
|
|
const uint32_t *in_X, const uint32_t *in_Y )
|
|
{
|
|
__m128i STATE0_X, STATE1_X, STATE0_Y, STATE1_Y;
|
|
__m128i MSG_X, MSG_Y, TMP_X, TMP_Y;
|
|
__m128i TMSG0_X, TMSG1_X, TMSG2_X, TMSG3_X;
|
|
__m128i TMSG0_Y, TMSG1_Y, TMSG2_Y, TMSG3_Y;
|
|
__m128i ABEF_SAVE_X, CDGH_SAVE_X,ABEF_SAVE_Y, CDGH_SAVE_Y;
|
|
|
|
// Load initial values
|
|
TMP_X = _mm_load_si128((__m128i*) &in_X[0]);
|
|
STATE1_X = _mm_load_si128((__m128i*) &in_X[4]);
|
|
TMP_Y = _mm_load_si128((__m128i*) &in_Y[0]);
|
|
STATE1_Y = _mm_load_si128((__m128i*) &in_Y[4]);
|
|
|
|
TMP_X = _mm_shuffle_epi32(TMP_X, 0xB1); // CDAB
|
|
TMP_Y = _mm_shuffle_epi32(TMP_Y, 0xB1); // CDAB
|
|
STATE1_X = _mm_shuffle_epi32(STATE1_X, 0x1B); // EFGH
|
|
STATE1_Y = _mm_shuffle_epi32(STATE1_Y, 0x1B); // EFGH
|
|
STATE0_X = _mm_alignr_epi8(TMP_X, STATE1_X, 8); // ABEF
|
|
STATE0_Y = _mm_alignr_epi8(TMP_Y, STATE1_Y, 8); // ABEF
|
|
STATE1_X = _mm_blend_epi16(STATE1_X, TMP_X, 0xF0); // CDGH
|
|
STATE1_Y = _mm_blend_epi16(STATE1_Y, TMP_Y, 0xF0); // CDGH
|
|
|
|
// Save current hash
|
|
ABEF_SAVE_X = STATE0_X;
|
|
ABEF_SAVE_Y = STATE0_Y;
|
|
CDGH_SAVE_X = STATE1_X;
|
|
CDGH_SAVE_Y = STATE1_Y;
|
|
|
|
// Rounds 0-3
|
|
TMSG0_X = _mm_load_si128((const __m128i*) (msg_X));
|
|
TMSG0_Y = _mm_load_si128((const __m128i*) (msg_Y));
|
|
TMP_X = _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL);
|
|
MSG_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Rounds 4-7
|
|
TMSG1_X = _mm_load_si128((const __m128i*) (msg_X+16));
|
|
TMSG1_Y = _mm_load_si128((const __m128i*) (msg_Y+16));
|
|
TMP_X = _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG0_X = _mm_sha256msg1_epu32(TMSG0_X, TMSG1_X);
|
|
TMSG0_Y = _mm_sha256msg1_epu32(TMSG0_Y, TMSG1_Y);
|
|
|
|
// Rounds 8-11
|
|
TMSG2_X = _mm_load_si128((const __m128i*) (msg_X+32));
|
|
TMSG2_Y = _mm_load_si128((const __m128i*) (msg_Y+32));
|
|
TMP_X = _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG1_X = _mm_sha256msg1_epu32(TMSG1_X, TMSG2_X);
|
|
TMSG1_Y = _mm_sha256msg1_epu32(TMSG1_Y, TMSG2_Y);
|
|
|
|
// Rounds 12-15
|
|
TMSG3_X = _mm_load_si128((const __m128i*) (msg_X+48));
|
|
TMSG3_Y = _mm_load_si128((const __m128i*) (msg_Y+48));
|
|
TMP_X = _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG3_X, TMSG2_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG3_Y, TMSG2_Y, 4);
|
|
TMSG0_X = _mm_add_epi32(TMSG0_X, TMP_X);
|
|
TMSG0_Y = _mm_add_epi32(TMSG0_Y, TMP_Y);
|
|
TMSG0_X = _mm_sha256msg2_epu32(TMSG0_X, TMSG3_X);
|
|
TMSG0_Y = _mm_sha256msg2_epu32(TMSG0_Y, TMSG3_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG2_X = _mm_sha256msg1_epu32(TMSG2_X, TMSG3_X);
|
|
TMSG2_Y = _mm_sha256msg1_epu32(TMSG2_Y, TMSG3_Y);
|
|
|
|
// Rounds 16-19
|
|
TMP_X = _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL);
|
|
MSG_X = _mm_add_epi32(TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG0_X, TMSG3_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG0_Y, TMSG3_Y, 4);
|
|
TMSG1_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
TMSG1_Y = _mm_add_epi32(TMSG1_Y, TMP_Y);
|
|
TMSG1_X = _mm_sha256msg2_epu32(TMSG1_X, TMSG0_X);
|
|
TMSG1_Y = _mm_sha256msg2_epu32(TMSG1_Y, TMSG0_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG3_X = _mm_sha256msg1_epu32(TMSG3_X, TMSG0_X);
|
|
TMSG3_Y = _mm_sha256msg1_epu32(TMSG3_Y, TMSG0_Y);
|
|
|
|
// Rounds 20-23
|
|
TMP_X = _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG1_X, TMSG0_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG1_Y, TMSG0_Y, 4);
|
|
TMSG2_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
TMSG2_Y = _mm_add_epi32(TMSG2_Y, TMP_Y);
|
|
TMSG2_X = _mm_sha256msg2_epu32(TMSG2_X, TMSG1_X);
|
|
TMSG2_Y = _mm_sha256msg2_epu32(TMSG2_Y, TMSG1_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG0_X = _mm_sha256msg1_epu32(TMSG0_X, TMSG1_X);
|
|
TMSG0_Y = _mm_sha256msg1_epu32(TMSG0_Y, TMSG1_Y);
|
|
|
|
// Rounds 24-27
|
|
TMP_X = _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG2_X, TMSG1_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG2_Y, TMSG1_Y, 4);
|
|
TMSG3_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
TMSG3_Y = _mm_add_epi32(TMSG3_Y, TMP_Y);
|
|
TMSG3_X = _mm_sha256msg2_epu32(TMSG3_X, TMSG2_X);
|
|
TMSG3_Y = _mm_sha256msg2_epu32(TMSG3_Y, TMSG2_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG1_X = _mm_sha256msg1_epu32(TMSG1_X, TMSG2_X);
|
|
TMSG1_Y = _mm_sha256msg1_epu32(TMSG1_Y, TMSG2_Y);
|
|
|
|
// Rounds 28-31
|
|
TMP_X = _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG3_X, TMSG2_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG3_Y, TMSG2_Y, 4);
|
|
TMSG0_X = _mm_add_epi32(TMSG0_X, TMP_X);
|
|
TMSG0_Y = _mm_add_epi32(TMSG0_Y, TMP_Y);
|
|
TMSG0_X = _mm_sha256msg2_epu32(TMSG0_X, TMSG3_X);
|
|
TMSG0_Y = _mm_sha256msg2_epu32(TMSG0_Y, TMSG3_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG2_X = _mm_sha256msg1_epu32(TMSG2_X, TMSG3_X);
|
|
TMSG2_Y = _mm_sha256msg1_epu32(TMSG2_Y, TMSG3_Y);
|
|
|
|
// Rounds 32-35
|
|
TMP_X = _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL);
|
|
MSG_X = _mm_add_epi32(TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG0_X, TMSG3_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG0_Y, TMSG3_Y, 4);
|
|
TMSG1_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
TMSG1_Y = _mm_add_epi32(TMSG1_Y, TMP_Y);
|
|
TMSG1_X = _mm_sha256msg2_epu32(TMSG1_X, TMSG0_X);
|
|
TMSG1_Y = _mm_sha256msg2_epu32(TMSG1_Y, TMSG0_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG3_X = _mm_sha256msg1_epu32(TMSG3_X, TMSG0_X);
|
|
TMSG3_Y = _mm_sha256msg1_epu32(TMSG3_Y, TMSG0_Y);
|
|
|
|
// Rounds 36-39
|
|
TMP_X = _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG1_X, TMSG0_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG1_Y, TMSG0_Y, 4);
|
|
TMSG2_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
TMSG2_Y = _mm_add_epi32(TMSG2_Y, TMP_Y);
|
|
TMSG2_X = _mm_sha256msg2_epu32(TMSG2_X, TMSG1_X);
|
|
TMSG2_Y = _mm_sha256msg2_epu32(TMSG2_Y, TMSG1_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG0_X = _mm_sha256msg1_epu32(TMSG0_X, TMSG1_X);
|
|
TMSG0_Y = _mm_sha256msg1_epu32(TMSG0_Y, TMSG1_Y);
|
|
|
|
// Rounds 40-43
|
|
TMP_X = _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG2_X, TMSG1_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG2_Y, TMSG1_Y, 4);
|
|
TMSG3_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
TMSG3_Y = _mm_add_epi32(TMSG3_Y, TMP_Y);
|
|
TMSG3_X = _mm_sha256msg2_epu32(TMSG3_X, TMSG2_X);
|
|
TMSG3_Y = _mm_sha256msg2_epu32(TMSG3_Y, TMSG2_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG1_X = _mm_sha256msg1_epu32(TMSG1_X, TMSG2_X);
|
|
TMSG1_Y = _mm_sha256msg1_epu32(TMSG1_Y, TMSG2_Y);
|
|
|
|
// Rounds 44-47
|
|
TMP_X = _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG3_X, TMSG2_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG3_Y, TMSG2_Y, 4);
|
|
TMSG0_X = _mm_add_epi32(TMSG0_X, TMP_X);
|
|
TMSG0_Y = _mm_add_epi32(TMSG0_Y, TMP_Y);
|
|
TMSG0_X = _mm_sha256msg2_epu32(TMSG0_X, TMSG3_X);
|
|
TMSG0_Y = _mm_sha256msg2_epu32(TMSG0_Y, TMSG3_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG2_X = _mm_sha256msg1_epu32(TMSG2_X, TMSG3_X);
|
|
TMSG2_Y = _mm_sha256msg1_epu32(TMSG2_Y, TMSG3_Y);
|
|
|
|
// Rounds 48-51
|
|
TMP_X = _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL);
|
|
MSG_X = _mm_add_epi32(TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG0_X, TMSG3_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG0_Y, TMSG3_Y, 4);
|
|
TMSG1_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
TMSG1_Y = _mm_add_epi32(TMSG1_Y, TMP_Y);
|
|
TMSG1_X = _mm_sha256msg2_epu32(TMSG1_X, TMSG0_X);
|
|
TMSG1_Y = _mm_sha256msg2_epu32(TMSG1_Y, TMSG0_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG3_X = _mm_sha256msg1_epu32(TMSG3_X, TMSG0_X);
|
|
TMSG3_Y = _mm_sha256msg1_epu32(TMSG3_Y, TMSG0_Y);
|
|
|
|
// Rounds 52-55
|
|
TMP_X = _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG1_X, TMSG0_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG1_Y, TMSG0_Y, 4);
|
|
TMSG2_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
TMSG2_Y = _mm_add_epi32(TMSG2_Y, TMP_Y);
|
|
TMSG2_X = _mm_sha256msg2_epu32(TMSG2_X, TMSG1_X);
|
|
TMSG2_Y = _mm_sha256msg2_epu32(TMSG2_Y, TMSG1_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Rounds 56-59
|
|
TMP_X = _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG2_X, TMSG1_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG2_Y, TMSG1_Y, 4);
|
|
TMSG3_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
TMSG3_Y = _mm_add_epi32(TMSG3_Y, TMP_Y);
|
|
TMSG3_X = _mm_sha256msg2_epu32(TMSG3_X, TMSG2_X);
|
|
TMSG3_Y = _mm_sha256msg2_epu32(TMSG3_Y, TMSG2_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Rounds 60-63
|
|
TMP_X = _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Add values back to state
|
|
STATE0_X = _mm_add_epi32(STATE0_X, ABEF_SAVE_X);
|
|
STATE1_X = _mm_add_epi32(STATE1_X, CDGH_SAVE_X);
|
|
STATE0_Y = _mm_add_epi32(STATE0_Y, ABEF_SAVE_Y);
|
|
STATE1_Y = _mm_add_epi32(STATE1_Y, CDGH_SAVE_Y);
|
|
|
|
TMP_X = _mm_shuffle_epi32(STATE0_X, 0x1B); // FEBA
|
|
TMP_Y = _mm_shuffle_epi32(STATE0_Y, 0x1B); // FEBA
|
|
STATE1_X = _mm_shuffle_epi32(STATE1_X, 0xB1); // DCHG
|
|
STATE1_Y = _mm_shuffle_epi32(STATE1_Y, 0xB1); // DCHG
|
|
STATE0_X = _mm_blend_epi16(TMP_X, STATE1_X, 0xF0); // DCBA
|
|
STATE0_Y = _mm_blend_epi16(TMP_Y, STATE1_Y, 0xF0); // DCBA
|
|
STATE1_X = _mm_alignr_epi8(STATE1_X, TMP_X, 8); // ABEF
|
|
STATE1_Y = _mm_alignr_epi8(STATE1_Y, TMP_Y, 8); // ABEF
|
|
|
|
// Save state
|
|
_mm_store_si128((__m128i*) &out_X[0], STATE0_X);
|
|
_mm_store_si128((__m128i*) &out_X[4], STATE1_X);
|
|
_mm_store_si128((__m128i*) &out_Y[0], STATE0_Y);
|
|
_mm_store_si128((__m128i*) &out_Y[4], STATE1_Y);
|
|
}
|
|
|
|
void sha256_ni2way_transform_be( uint32_t *out_X, uint32_t*out_Y,
|
|
const void *msg_X, const void *msg_Y,
|
|
const uint32_t *in_X, const uint32_t *in_Y )
|
|
{
|
|
__m128i STATE0_X, STATE1_X, STATE0_Y, STATE1_Y;
|
|
__m128i MSG_X, MSG_Y, TMP_X, TMP_Y, MASK;
|
|
__m128i TMSG0_X, TMSG1_X, TMSG2_X, TMSG3_X;
|
|
__m128i TMSG0_Y, TMSG1_Y, TMSG2_Y, TMSG3_Y;
|
|
__m128i ABEF_SAVE_X, CDGH_SAVE_X, ABEF_SAVE_Y, CDGH_SAVE_Y;
|
|
|
|
// Load initial values
|
|
TMP_X = _mm_load_si128((__m128i*) &in_X[0]);
|
|
STATE1_X = _mm_load_si128((__m128i*) &in_X[4]);
|
|
TMP_Y = _mm_load_si128((__m128i*) &in_Y[0]);
|
|
STATE1_Y = _mm_load_si128((__m128i*) &in_Y[4]);
|
|
MASK = _mm_set_epi64x(0x0c0d0e0f08090a0bULL, 0x0405060700010203ULL);
|
|
|
|
TMP_X = _mm_shuffle_epi32(TMP_X, 0xB1); // CDAB
|
|
TMP_Y = _mm_shuffle_epi32(TMP_Y, 0xB1); // CDAB
|
|
STATE1_X = _mm_shuffle_epi32(STATE1_X, 0x1B); // EFGH
|
|
STATE1_Y = _mm_shuffle_epi32(STATE1_Y, 0x1B); // EFGH
|
|
STATE0_X = _mm_alignr_epi8(TMP_X, STATE1_X, 8); // ABEF
|
|
STATE0_Y = _mm_alignr_epi8(TMP_Y, STATE1_Y, 8); // ABEF
|
|
STATE1_X = _mm_blend_epi16(STATE1_X, TMP_X, 0xF0); // CDGH
|
|
STATE1_Y = _mm_blend_epi16(STATE1_Y, TMP_Y, 0xF0); // CDGH
|
|
|
|
// Save current hash
|
|
ABEF_SAVE_X = STATE0_X;
|
|
ABEF_SAVE_Y = STATE0_Y;
|
|
CDGH_SAVE_X = STATE1_X;
|
|
CDGH_SAVE_Y = STATE1_Y;
|
|
|
|
// Rounds 0-3
|
|
TMSG0_X = _mm_load_si128((const __m128i*) (msg_X));
|
|
TMSG0_Y = _mm_load_si128((const __m128i*) (msg_Y));
|
|
TMP_X = _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL);
|
|
TMSG0_X = _mm_shuffle_epi8( TMSG0_X, MASK );
|
|
TMSG0_Y = _mm_shuffle_epi8( TMSG0_Y, MASK );
|
|
MSG_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Rounds 4-7
|
|
TMSG1_X = _mm_load_si128((const __m128i*) (msg_X+16));
|
|
TMSG1_Y = _mm_load_si128((const __m128i*) (msg_Y+16));
|
|
TMP_X = _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL);
|
|
TMSG1_X = _mm_shuffle_epi8( TMSG1_X, MASK );
|
|
TMSG1_Y = _mm_shuffle_epi8( TMSG1_Y, MASK );
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG0_X = _mm_sha256msg1_epu32(TMSG0_X, TMSG1_X);
|
|
TMSG0_Y = _mm_sha256msg1_epu32(TMSG0_Y, TMSG1_Y);
|
|
|
|
// Rounds 8-11
|
|
TMSG2_X = _mm_load_si128((const __m128i*) (msg_X+32));
|
|
TMSG2_Y = _mm_load_si128((const __m128i*) (msg_Y+32));
|
|
TMP_X = _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL);
|
|
TMSG2_X = _mm_shuffle_epi8( TMSG2_X, MASK );
|
|
TMSG2_Y = _mm_shuffle_epi8( TMSG2_Y, MASK );
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG1_X = _mm_sha256msg1_epu32(TMSG1_X, TMSG2_X);
|
|
TMSG1_Y = _mm_sha256msg1_epu32(TMSG1_Y, TMSG2_Y);
|
|
|
|
// Rounds 12-15
|
|
TMSG3_X = _mm_load_si128((const __m128i*) (msg_X+48));
|
|
TMSG3_Y = _mm_load_si128((const __m128i*) (msg_Y+48));
|
|
TMP_X = _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL);
|
|
TMSG3_X = _mm_shuffle_epi8( TMSG3_X, MASK );
|
|
TMSG3_Y = _mm_shuffle_epi8( TMSG3_Y, MASK );
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG3_X, TMSG2_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG3_Y, TMSG2_Y, 4);
|
|
TMSG0_X = _mm_add_epi32(TMSG0_X, TMP_X);
|
|
TMSG0_Y = _mm_add_epi32(TMSG0_Y, TMP_Y);
|
|
TMSG0_X = _mm_sha256msg2_epu32(TMSG0_X, TMSG3_X);
|
|
TMSG0_Y = _mm_sha256msg2_epu32(TMSG0_Y, TMSG3_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG2_X = _mm_sha256msg1_epu32(TMSG2_X, TMSG3_X);
|
|
TMSG2_Y = _mm_sha256msg1_epu32(TMSG2_Y, TMSG3_Y);
|
|
|
|
// Rounds 16-19
|
|
TMP_X = _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL);
|
|
MSG_X = _mm_add_epi32(TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG0_X, TMSG3_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG0_Y, TMSG3_Y, 4);
|
|
TMSG1_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
TMSG1_Y = _mm_add_epi32(TMSG1_Y, TMP_Y);
|
|
TMSG1_X = _mm_sha256msg2_epu32(TMSG1_X, TMSG0_X);
|
|
TMSG1_Y = _mm_sha256msg2_epu32(TMSG1_Y, TMSG0_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG3_X = _mm_sha256msg1_epu32(TMSG3_X, TMSG0_X);
|
|
TMSG3_Y = _mm_sha256msg1_epu32(TMSG3_Y, TMSG0_Y);
|
|
|
|
// Rounds 20-23
|
|
TMP_X = _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG1_X, TMSG0_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG1_Y, TMSG0_Y, 4);
|
|
TMSG2_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
TMSG2_Y = _mm_add_epi32(TMSG2_Y, TMP_Y);
|
|
TMSG2_X = _mm_sha256msg2_epu32(TMSG2_X, TMSG1_X);
|
|
TMSG2_Y = _mm_sha256msg2_epu32(TMSG2_Y, TMSG1_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG0_X = _mm_sha256msg1_epu32(TMSG0_X, TMSG1_X);
|
|
TMSG0_Y = _mm_sha256msg1_epu32(TMSG0_Y, TMSG1_Y);
|
|
|
|
// Rounds 24-27
|
|
TMP_X = _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG2_X, TMSG1_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG2_Y, TMSG1_Y, 4);
|
|
TMSG3_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
TMSG3_Y = _mm_add_epi32(TMSG3_Y, TMP_Y);
|
|
TMSG3_X = _mm_sha256msg2_epu32(TMSG3_X, TMSG2_X);
|
|
TMSG3_Y = _mm_sha256msg2_epu32(TMSG3_Y, TMSG2_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG1_X = _mm_sha256msg1_epu32(TMSG1_X, TMSG2_X);
|
|
TMSG1_Y = _mm_sha256msg1_epu32(TMSG1_Y, TMSG2_Y);
|
|
|
|
// Rounds 28-31
|
|
TMP_X = _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG3_X, TMSG2_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG3_Y, TMSG2_Y, 4);
|
|
TMSG0_X = _mm_add_epi32(TMSG0_X, TMP_X);
|
|
TMSG0_Y = _mm_add_epi32(TMSG0_Y, TMP_Y);
|
|
TMSG0_X = _mm_sha256msg2_epu32(TMSG0_X, TMSG3_X);
|
|
TMSG0_Y = _mm_sha256msg2_epu32(TMSG0_Y, TMSG3_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG2_X = _mm_sha256msg1_epu32(TMSG2_X, TMSG3_X);
|
|
TMSG2_Y = _mm_sha256msg1_epu32(TMSG2_Y, TMSG3_Y);
|
|
|
|
// Rounds 32-35
|
|
TMP_X = _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL);
|
|
MSG_X = _mm_add_epi32(TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG0_X, TMSG3_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG0_Y, TMSG3_Y, 4);
|
|
TMSG1_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
TMSG1_Y = _mm_add_epi32(TMSG1_Y, TMP_Y);
|
|
TMSG1_X = _mm_sha256msg2_epu32(TMSG1_X, TMSG0_X);
|
|
TMSG1_Y = _mm_sha256msg2_epu32(TMSG1_Y, TMSG0_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG3_X = _mm_sha256msg1_epu32(TMSG3_X, TMSG0_X);
|
|
TMSG3_Y = _mm_sha256msg1_epu32(TMSG3_Y, TMSG0_Y);
|
|
|
|
// Rounds 36-39
|
|
TMP_X = _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG1_X, TMSG0_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG1_Y, TMSG0_Y, 4);
|
|
TMSG2_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
TMSG2_Y = _mm_add_epi32(TMSG2_Y, TMP_Y);
|
|
TMSG2_X = _mm_sha256msg2_epu32(TMSG2_X, TMSG1_X);
|
|
TMSG2_Y = _mm_sha256msg2_epu32(TMSG2_Y, TMSG1_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG0_X = _mm_sha256msg1_epu32(TMSG0_X, TMSG1_X);
|
|
TMSG0_Y = _mm_sha256msg1_epu32(TMSG0_Y, TMSG1_Y);
|
|
|
|
// Rounds 40-43
|
|
TMP_X = _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG2_X, TMSG1_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG2_Y, TMSG1_Y, 4);
|
|
TMSG3_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
TMSG3_Y = _mm_add_epi32(TMSG3_Y, TMP_Y);
|
|
TMSG3_X = _mm_sha256msg2_epu32(TMSG3_X, TMSG2_X);
|
|
TMSG3_Y = _mm_sha256msg2_epu32(TMSG3_Y, TMSG2_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG1_X = _mm_sha256msg1_epu32(TMSG1_X, TMSG2_X);
|
|
TMSG1_Y = _mm_sha256msg1_epu32(TMSG1_Y, TMSG2_Y);
|
|
|
|
// Rounds 44-47
|
|
TMP_X = _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG3_X, TMSG2_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG3_Y, TMSG2_Y, 4);
|
|
TMSG0_X = _mm_add_epi32(TMSG0_X, TMP_X);
|
|
TMSG0_Y = _mm_add_epi32(TMSG0_Y, TMP_Y);
|
|
TMSG0_X = _mm_sha256msg2_epu32(TMSG0_X, TMSG3_X);
|
|
TMSG0_Y = _mm_sha256msg2_epu32(TMSG0_Y, TMSG3_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG2_X = _mm_sha256msg1_epu32(TMSG2_X, TMSG3_X);
|
|
TMSG2_Y = _mm_sha256msg1_epu32(TMSG2_Y, TMSG3_Y);
|
|
|
|
// Rounds 48-51
|
|
TMP_X = _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL);
|
|
MSG_X = _mm_add_epi32(TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG0_X, TMSG3_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG0_Y, TMSG3_Y, 4);
|
|
TMSG1_X = _mm_add_epi32(TMSG1_X, TMP_X);
|
|
TMSG1_Y = _mm_add_epi32(TMSG1_Y, TMP_Y);
|
|
TMSG1_X = _mm_sha256msg2_epu32(TMSG1_X, TMSG0_X);
|
|
TMSG1_Y = _mm_sha256msg2_epu32(TMSG1_Y, TMSG0_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
TMSG3_X = _mm_sha256msg1_epu32(TMSG3_X, TMSG0_X);
|
|
TMSG3_Y = _mm_sha256msg1_epu32(TMSG3_Y, TMSG0_Y);
|
|
|
|
// Rounds 52-55
|
|
TMP_X = _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL);
|
|
MSG_X = _mm_add_epi32(TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32(TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG1_X, TMSG0_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG1_Y, TMSG0_Y, 4);
|
|
TMSG2_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
TMSG2_Y = _mm_add_epi32(TMSG2_Y, TMP_Y);
|
|
TMSG2_X = _mm_sha256msg2_epu32(TMSG2_X, TMSG1_X);
|
|
TMSG2_Y = _mm_sha256msg2_epu32(TMSG2_Y, TMSG1_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Rounds 56-59
|
|
TMP_X = _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL);
|
|
MSG_X = _mm_add_epi32(TMSG2_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG2_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
TMP_X = _mm_alignr_epi8(TMSG2_X, TMSG1_X, 4);
|
|
TMP_Y = _mm_alignr_epi8(TMSG2_Y, TMSG1_Y, 4);
|
|
TMSG3_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
TMSG3_Y = _mm_add_epi32(TMSG3_Y, TMP_Y);
|
|
TMSG3_X = _mm_sha256msg2_epu32(TMSG3_X, TMSG2_X);
|
|
TMSG3_Y = _mm_sha256msg2_epu32(TMSG3_Y, TMSG2_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Rounds 60-63
|
|
TMP_X = _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL);
|
|
MSG_X = _mm_add_epi32(TMSG3_X, TMP_X);
|
|
MSG_Y = _mm_add_epi32(TMSG3_Y, TMP_X);
|
|
STATE1_X = _mm_sha256rnds2_epu32(STATE1_X, STATE0_X, MSG_X);
|
|
STATE1_Y = _mm_sha256rnds2_epu32(STATE1_Y, STATE0_Y, MSG_Y);
|
|
MSG_X = _mm_shuffle_epi32(MSG_X, 0x0E);
|
|
MSG_Y = _mm_shuffle_epi32(MSG_Y, 0x0E);
|
|
STATE0_X = _mm_sha256rnds2_epu32(STATE0_X, STATE1_X, MSG_X);
|
|
STATE0_Y = _mm_sha256rnds2_epu32(STATE0_Y, STATE1_Y, MSG_Y);
|
|
|
|
// Add values back to state
|
|
STATE0_X = _mm_add_epi32(STATE0_X, ABEF_SAVE_X);
|
|
STATE1_X = _mm_add_epi32(STATE1_X, CDGH_SAVE_X);
|
|
STATE0_Y = _mm_add_epi32(STATE0_Y, ABEF_SAVE_Y);
|
|
STATE1_Y = _mm_add_epi32(STATE1_Y, CDGH_SAVE_Y);
|
|
|
|
TMP_X = _mm_shuffle_epi32(STATE0_X, 0x1B); // FEBA
|
|
TMP_Y = _mm_shuffle_epi32(STATE0_Y, 0x1B); // FEBA
|
|
STATE1_X = _mm_shuffle_epi32(STATE1_X, 0xB1); // DCHG
|
|
STATE1_Y = _mm_shuffle_epi32(STATE1_Y, 0xB1); // DCHG
|
|
STATE0_X = _mm_blend_epi16(TMP_X, STATE1_X, 0xF0); // DCBA
|
|
STATE0_Y = _mm_blend_epi16(TMP_Y, STATE1_Y, 0xF0); // DCBA
|
|
STATE1_X = _mm_alignr_epi8(STATE1_X, TMP_X, 8); // ABEF
|
|
STATE1_Y = _mm_alignr_epi8(STATE1_Y, TMP_Y, 8); // ABEF
|
|
|
|
// Save state
|
|
_mm_store_si128((__m128i*) &out_X[0], STATE0_X);
|
|
_mm_store_si128((__m128i*) &out_X[4], STATE1_X);
|
|
_mm_store_si128((__m128i*) &out_Y[0], STATE0_Y);
|
|
_mm_store_si128((__m128i*) &out_Y[4], STATE1_Y);
|
|
}
|
|
|
|
// The next 2 functions work together to seperate the low frequency data
|
|
// (outer loop) from the high frequency data containing the nonce (inner loop)
|
|
// when hashing the second block (tail) of the first sha256 hash.
|
|
// The goal is to avoid any redundant processing in final. Prehash is almost
|
|
// 4 rounds total, only missing the final addition of the nonce.
|
|
// Nonce must be set to zero for prehash.
|
|
void sha256_ni_prehash_3rounds( uint32_t *ostate, const void *msg,
|
|
uint32_t *sstate, const uint32_t *istate )
|
|
{
|
|
__m128i STATE0, STATE1, MSG, TMP;
|
|
|
|
// Load initial values
|
|
TMP = casti_m128i( istate, 0 );
|
|
STATE1 = casti_m128i( istate, 1 );
|
|
|
|
TMP = _mm_shuffle_epi32( TMP, 0xB1 ); // CDAB
|
|
STATE1 = _mm_shuffle_epi32( STATE1, 0x1B ); // EFGH
|
|
STATE0 = _mm_alignr_epi8( TMP, STATE1, 8 ); // ABEF
|
|
STATE1 = _mm_blend_epi16( STATE1, TMP, 0xF0 ); // CDGH
|
|
|
|
// Save current hash
|
|
casti_m128i( sstate, 0 ) = STATE0;
|
|
casti_m128i( sstate, 1 ) = STATE1;
|
|
|
|
// Rounds 0 to 3
|
|
MSG = casti_m128i( msg, 0 );
|
|
TMP = _mm_set_epi64x( 0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL );
|
|
MSG = _mm_add_epi32( MSG, TMP );
|
|
STATE1 = _mm_sha256rnds2_epu32( STATE1, STATE0, MSG );
|
|
MSG = _mm_shuffle_epi32( MSG, 0x0E );
|
|
casti_m128i( ostate, 0 ) = _mm_sha256rnds2_epu32( STATE0, STATE1, MSG );
|
|
casti_m128i( ostate, 1 ) = STATE1;
|
|
}
|
|
|
|
void sha256_ni2way_final_rounds( uint32_t *out_X, uint32_t *out_Y,
|
|
const void *msg_X, const void *msg_Y,
|
|
const uint32_t *state_mid_X, const uint32_t *state_mid_Y,
|
|
const uint32_t *state_save_X, const uint32_t *state_save_Y )
|
|
{
|
|
__m128i STATE0_X, STATE1_X, STATE0_Y, STATE1_Y;
|
|
__m128i MSG_X, MSG_Y, TMP_X, TMP_Y;
|
|
__m128i TMSG0_X, TMSG1_X, TMSG2_X, TMSG3_X;
|
|
__m128i TMSG0_Y, TMSG1_Y, TMSG2_Y, TMSG3_Y;
|
|
|
|
STATE0_X = casti_m128i( state_mid_X, 0 );
|
|
STATE1_X = casti_m128i( state_mid_X, 1 );
|
|
STATE0_Y = casti_m128i( state_mid_Y, 0 );
|
|
STATE1_Y = casti_m128i( state_mid_Y, 1 );
|
|
|
|
// Add the nonces (msg[0] lane 3) to A & E (STATE0 lanes 1 & 3)
|
|
TMSG0_X = casti_m128i( msg_X, 0 );
|
|
TMSG0_Y = casti_m128i( msg_Y, 0 );
|
|
TMP_X = mm128_xim_32( TMSG0_X, TMSG0_X, 0xd5 );
|
|
TMP_Y = mm128_xim_32( TMSG0_Y, TMSG0_Y, 0xd5 );
|
|
STATE0_X = _mm_add_epi32( STATE0_X, TMP_X );
|
|
STATE0_Y = _mm_add_epi32( STATE0_Y, TMP_Y );
|
|
|
|
// Rounds 4 to 7
|
|
TMSG1_X = casti_m128i( msg_X, 1 );
|
|
TMSG1_Y = casti_m128i( msg_Y, 1 );
|
|
TMP_X = _mm_set_epi64x( 0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL );
|
|
MSG_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG0_X = _mm_sha256msg1_epu32( TMSG0_X, TMSG1_X );
|
|
TMSG0_Y = _mm_sha256msg1_epu32( TMSG0_Y, TMSG1_Y );
|
|
|
|
// Rounds 8 to 11, skip TMSG2, it's zero until round 22
|
|
MSG_X = _mm_set_epi64x( 0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_X );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_X );
|
|
|
|
// Rounds 12 to 15
|
|
TMSG3_X = casti_m128i( msg_X, 3 );
|
|
TMSG3_Y = casti_m128i( msg_Y, 3 );
|
|
TMP_X = _mm_set_epi64x( 0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL );
|
|
MSG_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMSG0_X = _mm_sha256msg2_epu32( TMSG0_X, TMSG3_X );
|
|
TMSG0_Y = _mm_sha256msg2_epu32( TMSG0_Y, TMSG3_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
|
|
// Rounds 16 to 19
|
|
TMP_X = _mm_set_epi64x( 0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL );
|
|
MSG_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG0_X, TMSG3_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG0_Y, TMSG3_Y, 4 );
|
|
TMSG1_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
TMSG1_Y = _mm_add_epi32( TMSG1_Y, TMP_Y );
|
|
TMSG1_X = _mm_sha256msg2_epu32( TMSG1_X, TMSG0_X );
|
|
TMSG1_Y = _mm_sha256msg2_epu32( TMSG1_Y, TMSG0_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG3_X = _mm_sha256msg1_epu32( TMSG3_X, TMSG0_X );
|
|
TMSG3_Y = _mm_sha256msg1_epu32( TMSG3_Y, TMSG0_Y );
|
|
|
|
// Rounds 20 to 23
|
|
TMP_X = _mm_set_epi64x( 0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL );
|
|
MSG_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMSG2_X = _mm_alignr_epi8( TMSG1_X, TMSG0_X, 4 );
|
|
TMSG2_Y = _mm_alignr_epi8( TMSG1_Y, TMSG0_Y, 4 );
|
|
TMSG2_X = _mm_sha256msg2_epu32( TMSG2_X, TMSG1_X );
|
|
TMSG2_Y = _mm_sha256msg2_epu32( TMSG2_Y, TMSG1_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG0_X = _mm_sha256msg1_epu32( TMSG0_X, TMSG1_X );
|
|
TMSG0_Y = _mm_sha256msg1_epu32( TMSG0_Y, TMSG1_Y );
|
|
|
|
// Rounds 24 to 27
|
|
TMP_X = _mm_set_epi64x( 0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL );
|
|
MSG_X = _mm_add_epi32( TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG2_X, TMSG1_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG2_Y, TMSG1_Y, 4 );
|
|
TMSG3_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
TMSG3_Y = _mm_add_epi32( TMSG3_Y, TMP_Y );
|
|
TMSG3_X = _mm_sha256msg2_epu32( TMSG3_X, TMSG2_X );
|
|
TMSG3_Y = _mm_sha256msg2_epu32( TMSG3_Y, TMSG2_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG1_X = _mm_sha256msg1_epu32( TMSG1_X, TMSG2_X );
|
|
TMSG1_Y = _mm_sha256msg1_epu32( TMSG1_Y, TMSG2_Y );
|
|
|
|
// Rounds 28 to 31
|
|
TMP_X = _mm_set_epi64x( 0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL );
|
|
MSG_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG3_X, TMSG2_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG3_Y, TMSG2_Y, 4 );
|
|
TMSG0_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
TMSG0_Y = _mm_add_epi32( TMSG0_Y, TMP_Y );
|
|
TMSG0_X = _mm_sha256msg2_epu32( TMSG0_X, TMSG3_X );
|
|
TMSG0_Y = _mm_sha256msg2_epu32( TMSG0_Y, TMSG3_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG2_X = _mm_sha256msg1_epu32( TMSG2_X, TMSG3_X );
|
|
TMSG2_Y = _mm_sha256msg1_epu32( TMSG2_Y, TMSG3_Y );
|
|
|
|
// Rounds 32 to 35
|
|
TMP_X = _mm_set_epi64x( 0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL );
|
|
MSG_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG0_X, TMSG3_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG0_Y, TMSG3_Y, 4 );
|
|
TMSG1_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
TMSG1_Y = _mm_add_epi32( TMSG1_Y, TMP_Y );
|
|
TMSG1_X = _mm_sha256msg2_epu32( TMSG1_X, TMSG0_X );
|
|
TMSG1_Y = _mm_sha256msg2_epu32( TMSG1_Y, TMSG0_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG3_X = _mm_sha256msg1_epu32( TMSG3_X, TMSG0_X );
|
|
TMSG3_Y = _mm_sha256msg1_epu32( TMSG3_Y, TMSG0_Y );
|
|
|
|
// Rounds 36 to 39
|
|
TMP_X = _mm_set_epi64x( 0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL );
|
|
MSG_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG1_X, TMSG0_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG1_Y, TMSG0_Y, 4 );
|
|
TMSG2_X = _mm_add_epi32( TMSG2_X, TMP_X );
|
|
TMSG2_Y = _mm_add_epi32( TMSG2_Y, TMP_Y );
|
|
TMSG2_X = _mm_sha256msg2_epu32( TMSG2_X, TMSG1_X );
|
|
TMSG2_Y = _mm_sha256msg2_epu32( TMSG2_Y, TMSG1_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG0_X = _mm_sha256msg1_epu32( TMSG0_X, TMSG1_X );
|
|
TMSG0_Y = _mm_sha256msg1_epu32( TMSG0_Y, TMSG1_Y );
|
|
|
|
// Rounds 40 to 43
|
|
TMP_X = _mm_set_epi64x( 0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL );
|
|
MSG_X = _mm_add_epi32( TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG2_X, TMSG1_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG2_Y, TMSG1_Y, 4 );
|
|
TMSG3_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
TMSG3_Y = _mm_add_epi32( TMSG3_Y, TMP_Y );
|
|
TMSG3_X = _mm_sha256msg2_epu32( TMSG3_X, TMSG2_X );
|
|
TMSG3_Y = _mm_sha256msg2_epu32( TMSG3_Y, TMSG2_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG1_X = _mm_sha256msg1_epu32( TMSG1_X, TMSG2_X );
|
|
TMSG1_Y = _mm_sha256msg1_epu32( TMSG1_Y, TMSG2_Y );
|
|
|
|
// Rounds 44 to 47
|
|
TMP_X = _mm_set_epi64x( 0x106AA070F40E3585ULL, 0xD6990624D192E819ULL );
|
|
MSG_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG3_X, TMSG2_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG3_Y, TMSG2_Y, 4 );
|
|
TMSG0_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
TMSG0_Y = _mm_add_epi32( TMSG0_Y, TMP_Y );
|
|
TMSG0_X = _mm_sha256msg2_epu32( TMSG0_X, TMSG3_X );
|
|
TMSG0_Y = _mm_sha256msg2_epu32( TMSG0_Y, TMSG3_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG2_X = _mm_sha256msg1_epu32( TMSG2_X, TMSG3_X );
|
|
TMSG2_Y = _mm_sha256msg1_epu32( TMSG2_Y, TMSG3_Y );
|
|
|
|
// Rounds 48 to 51
|
|
TMP_X = _mm_set_epi64x( 0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL );
|
|
MSG_X = _mm_add_epi32( TMSG0_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG0_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG0_X, TMSG3_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG0_Y, TMSG3_Y, 4 );
|
|
TMSG1_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
TMSG1_Y = _mm_add_epi32( TMSG1_Y, TMP_Y );
|
|
TMSG1_X = _mm_sha256msg2_epu32( TMSG1_X, TMSG0_X );
|
|
TMSG1_Y = _mm_sha256msg2_epu32( TMSG1_Y, TMSG0_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
TMSG3_X = _mm_sha256msg1_epu32( TMSG3_X, TMSG0_X );
|
|
TMSG3_Y = _mm_sha256msg1_epu32( TMSG3_Y, TMSG0_Y );
|
|
|
|
// Rounds 52 to 55
|
|
TMP_X = _mm_set_epi64x( 0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL );
|
|
MSG_X = _mm_add_epi32( TMSG1_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG1_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG1_X, TMSG0_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG1_Y, TMSG0_Y, 4 );
|
|
TMSG2_X = _mm_add_epi32( TMSG2_X, TMP_X );
|
|
TMSG2_Y = _mm_add_epi32( TMSG2_Y, TMP_Y );
|
|
TMSG2_X = _mm_sha256msg2_epu32( TMSG2_X, TMSG1_X );
|
|
TMSG2_Y = _mm_sha256msg2_epu32( TMSG2_Y, TMSG1_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
|
|
// Rounds 56 to 59
|
|
TMP_X = _mm_set_epi64x( 0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL );
|
|
MSG_X = _mm_add_epi32( TMSG2_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG2_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
TMP_X = _mm_alignr_epi8( TMSG2_X, TMSG1_X, 4 );
|
|
TMP_Y = _mm_alignr_epi8( TMSG2_Y, TMSG1_Y, 4 );
|
|
TMSG3_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
TMSG3_Y = _mm_add_epi32( TMSG3_Y, TMP_Y );
|
|
TMSG3_X = _mm_sha256msg2_epu32( TMSG3_X, TMSG2_X );
|
|
TMSG3_Y = _mm_sha256msg2_epu32( TMSG3_Y, TMSG2_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
|
|
// Rounds 60 to 63
|
|
TMP_X = _mm_set_epi64x( 0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL );
|
|
MSG_X = _mm_add_epi32( TMSG3_X, TMP_X );
|
|
MSG_Y = _mm_add_epi32( TMSG3_Y, TMP_X );
|
|
STATE1_X = _mm_sha256rnds2_epu32( STATE1_X, STATE0_X, MSG_X );
|
|
STATE1_Y = _mm_sha256rnds2_epu32( STATE1_Y, STATE0_Y, MSG_Y );
|
|
MSG_X = _mm_shuffle_epi32( MSG_X, 0x0E );
|
|
MSG_Y = _mm_shuffle_epi32( MSG_Y, 0x0E );
|
|
STATE0_X = _mm_sha256rnds2_epu32( STATE0_X, STATE1_X, MSG_X );
|
|
STATE0_Y = _mm_sha256rnds2_epu32( STATE0_Y, STATE1_Y, MSG_Y );
|
|
|
|
// Add saved state to new state
|
|
STATE0_X = _mm_add_epi32( STATE0_X, casti_m128i( state_save_X, 0 ) );
|
|
STATE1_X = _mm_add_epi32( STATE1_X, casti_m128i( state_save_X, 1 ) );
|
|
STATE0_Y = _mm_add_epi32( STATE0_Y, casti_m128i( state_save_Y, 0 ) );
|
|
STATE1_Y = _mm_add_epi32( STATE1_Y, casti_m128i( state_save_Y, 1 ) );
|
|
|
|
// Unshuffle & save state
|
|
TMP_X = _mm_shuffle_epi32( STATE0_X, 0x1B ); // FEBA
|
|
TMP_Y = _mm_shuffle_epi32( STATE0_Y, 0x1B );
|
|
STATE1_X = _mm_shuffle_epi32( STATE1_X, 0xB1 ); // DCHG
|
|
STATE1_Y = _mm_shuffle_epi32( STATE1_Y, 0xB1 );
|
|
casti_m128i( out_X, 0 ) = _mm_blend_epi16( TMP_X, STATE1_X, 0xF0 ); // DCBA
|
|
casti_m128i( out_Y, 0 ) = _mm_blend_epi16( TMP_Y, STATE1_Y, 0xF0 );
|
|
casti_m128i( out_X, 1 ) = _mm_alignr_epi8( STATE1_X, TMP_X, 8 ); // ABEF
|
|
casti_m128i( out_Y, 1 ) = _mm_alignr_epi8( STATE1_Y, TMP_Y, 8 );
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
void sha256_ctx_init( sha256_context *ctx )
|
|
{
|
|
memcpy( ctx->state, SHA256_IV, sizeof SHA256_IV );
|
|
ctx->count = 0;
|
|
}
|
|
|
|
void sha256_update( sha256_context *ctx, const void *data, size_t len )
|
|
{
|
|
int ptr = ctx->count & 0x3f;
|
|
const uint8_t *src = data;
|
|
|
|
ctx->count += (uint64_t)len;
|
|
|
|
if ( len < 64 - ptr )
|
|
{
|
|
memcpy( ctx->buf + ptr, src, len );
|
|
return;
|
|
}
|
|
|
|
memcpy( ctx->buf + ptr, src, 64 - ptr );
|
|
sha256_transform_be( ctx->state, (uint32_t*)ctx->buf, ctx->state );
|
|
src += 64 - ptr;
|
|
len -= 64 - ptr;
|
|
|
|
while ( len >= 64 )
|
|
{
|
|
sha256_transform_be( ctx->state, (uint32_t*)src, ctx->state );
|
|
src += 64;
|
|
len -= 64;
|
|
}
|
|
|
|
memcpy( ctx->buf, src, len );
|
|
}
|
|
|
|
void sha256_final( sha256_context *ctx, void *hash )
|
|
{
|
|
int ptr = ctx->count & 0x3f;
|
|
|
|
ctx->buf[ ptr++ ] = 0x80;
|
|
|
|
if ( ptr > 56 )
|
|
{
|
|
memset( ctx->buf + ptr, 0, 64 - ptr );
|
|
sha256_transform_be( ctx->state, (uint32_t*)ctx->buf, ctx->state );
|
|
memset( ctx->buf, 0, 56 );
|
|
}
|
|
else
|
|
memset( ctx->buf + ptr, 0, 56 - ptr );
|
|
|
|
*(uint64_t*)(&ctx->buf[56]) = bswap_64( ctx->count << 3 );
|
|
|
|
sha256_transform_be( ctx->state, (uint32_t*)ctx->buf, ctx->state );
|
|
|
|
for ( int i = 0; i < 8; i++ )
|
|
( (uint32_t*)hash )[i] = bswap_32( ctx->state[i] );
|
|
}
|
|
|
|
void sha256_full( void *hash, const void *data, size_t len )
|
|
{
|
|
sha256_context ctx;
|
|
sha256_ctx_init( &ctx );
|
|
sha256_update( &ctx, data, len );
|
|
sha256_final( &ctx, hash );
|
|
}
|
|
|