From 608fd6f14a6b9c0eeba2843fb14cbb235be0034f Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 7 Feb 2018 19:07:36 +0000 Subject: [PATCH 1/3] Monero Cryptonight variants, and add one for v7 This is the first variant of many, with the intent to improve Monero's resistance to ASICs and encourage mining decentralization. --- src/crypto/chacha.h | 4 +- src/crypto/hash-ops.h | 4 +- src/crypto/hash.h | 4 +- src/crypto/slow-hash.c | 53 ++++++++++++++++--- .../cryptonote_format_utils.cpp | 3 +- src/device/device_ledger.cpp | 2 +- tests/hash/CMakeLists.txt | 2 +- tests/hash/main.cpp | 11 +++- tests/hash/tests-slow-1.txt | 5 ++ 9 files changed, 71 insertions(+), 17 deletions(-) create mode 100644 tests/hash/tests-slow-1.txt diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index b45c3d7c7..22da53bd0 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -69,10 +69,10 @@ namespace crypto { chacha20(data, length, key.data(), reinterpret_cast(&iv), cipher); } - inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, bool prehashed=false) { + inline void generate_chacha_key(const void *data, size_t size, chacha_key& key, int cn_variant = 0, bool prehashed=false) { static_assert(sizeof(chacha_key) <= sizeof(hash), "Size of hash must be at least that of chacha_key"); tools::scrubbed_arr pwd_hash; - crypto::cn_slow_hash_pre(data, size, pwd_hash.data(), prehashed); + crypto::cn_slow_hash_pre(data, size, pwd_hash.data(), cn_variant, prehashed); memcpy(&key, pwd_hash.data(), sizeof(key)); } diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 130bf02db..934d464de 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -79,8 +79,8 @@ enum { }; void cn_fast_hash(const void *data, size_t length, char *hash); -void cn_slow_hash(const void *data, size_t length, char *hash); -void cn_slow_hash_pre(const void *data, size_t length, char *hash, bool pre); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant); +void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool pre); void hash_extra_blake(const void *data, size_t length, char *hash); void hash_extra_groestl(const void *data, size_t length, char *hash); diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 14104699b..bf4f4c096 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -71,8 +71,8 @@ namespace crypto { return h; } - inline void cn_slow_hash(const void *data, std::size_t length, hash &hash) { - cn_slow_hash(data, length, reinterpret_cast(&hash)); + inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0) { + cn_slow_hash(data, length, reinterpret_cast(&hash), variant); } inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 36bfba9fd..5bfc93021 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #include "common/int-util.h" #include "hash-ops.h" @@ -47,6 +49,29 @@ extern int aesb_single_round(const uint8_t *in, uint8_t*out, const uint8_t *expandedKey); extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey); +#define VARIANT1_1(p) \ + do if (variant > 0) \ + { \ + uint8_t tmp = ((const uint8_t*)p)[11]; \ + uint8_t tmp1 = (tmp>>4)&1, tmp2 = (tmp>>5)&1, tmp3 = tmp1^tmp2; \ + uint8_t tmp0 = (((const uint8_t*)p)[11] & 1) ? tmp3 : ((((tmp2<<1)|tmp1) + 1)&3); \ + ((uint8_t*)p)[11] = (((const uint8_t*)p)[11] & 1) ? ((tmp & 0xef) | (tmp0<<4)):((tmp & 0xcf) | (tmp0<<4)); \ + } while(0) + +#define VARIANT1_2(p) \ + do if (variant > 0) \ + { \ + ((uint32_t*)p)[2] ^= nonce; \ + } while(0) + +#define VARIANT1_INIT() \ + if (variant > 0 && length < 43) \ + { \ + fprintf(stderr, "Cryptonight variants need at least 43 bytes of data"); \ + _exit(1); \ + } \ + const uint32_t nonce = variant > 0 ? *(const uint32_t*)(((const uint8_t*)data)+39) : 0 + #if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))) // Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI // Fall back to more portable code is down at the bottom @@ -125,6 +150,7 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp _mm_store_si128(R128(c), _c); \ _b = _mm_xor_si128(_b, _c); \ _mm_store_si128(R128(&hp_state[j]), _b); \ + VARIANT1_1(&hp_state[j]); \ j = state_index(c); \ p = U64(&hp_state[j]); \ b[0] = p[0]; b[1] = p[1]; \ @@ -134,6 +160,7 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp p[0] = a[0]; p[1] = a[1]; \ a[0] ^= b[0]; a[1] ^= b[1]; \ _b = _c; \ + VARIANT1_2(&hp_state[j]); \ #if defined(_MSC_VER) #define THREADV __declspec(thread) @@ -515,11 +542,11 @@ void slow_hash_free_state(void) * @param length the length in bytes of the data * @param hash a pointer to a buffer in which the final 256 bit hash will be stored */ -void cn_slow_hash(const void *data, size_t length, char *hash) { - cn_slow_hash_pre(data,length,hash,false); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { + cn_slow_hash_pre(data,length,hash,variant,false); } -void cn_slow_hash_pre(const void *data, size_t length, char *hash, bool prehashed) +void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */ @@ -541,6 +568,8 @@ void cn_slow_hash_pre(const void *data, size_t length, char *hash, bool prehashe hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; + VARIANT1_INIT(); + // this isn't supposed to happen, but guard against it for now. if(hp_state == NULL) slow_hash_allocate_state(); @@ -712,6 +741,7 @@ union cn_slow_hash_state vst1q_u8((uint8_t *)c, _c); \ _b = veorq_u8(_b, _c); \ vst1q_u8(&hp_state[j], _b); \ + VARIANT1_1(&hp_state[j]); \ j = state_index(c); \ p = U64(&hp_state[j]); \ b[0] = p[0]; b[1] = p[1]; \ @@ -720,6 +750,7 @@ union cn_slow_hash_state p = U64(&hp_state[j]); \ p[0] = a[0]; p[1] = a[1]; \ a[0] ^= b[0]; a[1] ^= b[1]; \ + VARIANT1_2(p); \ _b = _c; \ @@ -851,7 +882,7 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, const u } } -void cn_slow_hash(const void *data, size_t length, char *hash) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { RDATA_ALIGN16 uint8_t expandedKey[240]; RDATA_ALIGN16 uint8_t hp_state[MEMORY]; @@ -872,6 +903,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash) hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; + VARIANT1_INIT(); + /* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */ hash_process(&state.hs, data, length); @@ -1045,7 +1078,7 @@ STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b) U64(a)[1] ^= U64(b)[1]; } -void cn_slow_hash(const void *data, size_t length, char *hash) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; @@ -1064,6 +1097,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash) hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; + VARIANT1_INIT(); + #ifndef FORCE_USE_HEAP uint8_t long_state[MEMORY]; #else @@ -1103,6 +1138,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) xor_blocks(b, p); swap_blocks(b, p); swap_blocks(a, b); + VARIANT1_1(p); // Iteration 2 p = &long_state[state_index(a)]; @@ -1112,6 +1148,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) swap_blocks(b, p); xor_blocks(b, p); swap_blocks(a, b); + VARIANT1_2(p); } memcpy(text, state.init, INIT_SIZE_BYTE); @@ -1216,7 +1253,7 @@ union cn_slow_hash_state { }; #pragma pack(pop) -void cn_slow_hash(const void *data, size_t length, char *hash) { +void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { uint8_t long_state[MEMORY]; union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; @@ -1228,6 +1265,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash) { uint8_t aes_key[AES_KEY_SIZE]; oaes_ctx *aes_ctx; + VARIANT1_INIT(); + hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); memcpy(aes_key, state.hs.b, AES_KEY_SIZE); @@ -1260,6 +1299,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) { copy_block(&long_state[j * AES_BLOCK_SIZE], c); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); + VARIANT1_1(&long_state[j * AES_BLOCK_SIZE]); /* Iteration 2 */ j = e2i(a, MEMORY / AES_BLOCK_SIZE); copy_block(c, &long_state[j * AES_BLOCK_SIZE]); @@ -1270,6 +1310,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash) { copy_block(&long_state[j * AES_BLOCK_SIZE], c); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); + VARIANT1_2(&long_state[j * AES_BLOCK_SIZE]); } memcpy(text, state.init, INIT_SIZE_BYTE); diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index f462d1ca9..a10772424 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -1022,7 +1022,8 @@ namespace cryptonote return true; } blobdata bd = get_block_hashing_blob(b); - crypto::cn_slow_hash(bd.data(), bd.size(), res); + const int cn_variant = b.major_version >= 7 ? b.major_version - 6 : 0; + crypto::cn_slow_hash(bd.data(), bd.size(), res, cn_variant); return true; } //--------------------------------------------------------------- diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index cede834a1..571d42724 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -511,7 +511,7 @@ namespace hw { char prekey[200]; memmove(prekey, &this->buffer_recv[0], 200); - crypto::generate_chacha_key(&prekey[0], sizeof(prekey), key, true); + crypto::generate_chacha_key(&prekey[0], sizeof(prekey), key, 0, true); #ifdef DEBUG_HWDEVICE hw::ledger::check32("generate_chacha_key", "key", (char*)key_x.data(), (char*)key.data()); diff --git a/tests/hash/CMakeLists.txt b/tests/hash/CMakeLists.txt index e2aca8517..92abeca20 100644 --- a/tests/hash/CMakeLists.txt +++ b/tests/hash/CMakeLists.txt @@ -43,7 +43,7 @@ set_property(TARGET hash-tests PROPERTY FOLDER "tests") -foreach (hash IN ITEMS fast slow tree extra-blake extra-groestl extra-jh extra-skein) +foreach (hash IN ITEMS fast slow slow-1 tree extra-blake extra-groestl extra-jh extra-skein) add_test( NAME "hash-${hash}" COMMAND hash-tests "${hash}" "${CMAKE_CURRENT_SOURCE_DIR}/tests-${hash}.txt") diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index aa928856a..5a16284df 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -51,6 +51,12 @@ extern "C" { } tree_hash((const char (*)[32]) data, length >> 5, hash); } + static void cn_slow_hash_0(const void *data, size_t length, char *hash) { + return cn_slow_hash(data, length, hash, 0); + } + static void cn_slow_hash_1(const void *data, size_t length, char *hash) { + return cn_slow_hash(data, length, hash, 1); + } } POP_WARNINGS @@ -58,9 +64,10 @@ extern "C" typedef void hash_f(const void *, size_t, char *); struct hash_func { const string name; hash_f &f; -} hashes[] = {{"fast", cn_fast_hash}, {"slow", cn_slow_hash}, {"tree", hash_tree}, +} hashes[] = {{"fast", cn_fast_hash}, {"slow", cn_slow_hash_0}, {"tree", hash_tree}, {"extra-blake", hash_extra_blake}, {"extra-groestl", hash_extra_groestl}, - {"extra-jh", hash_extra_jh}, {"extra-skein", hash_extra_skein}}; + {"extra-jh", hash_extra_jh}, {"extra-skein", hash_extra_skein}, + {"slow-1", cn_slow_hash_1}}; int main(int argc, char *argv[]) { hash_f *f; diff --git a/tests/hash/tests-slow-1.txt b/tests/hash/tests-slow-1.txt new file mode 100644 index 000000000..0c571f86f --- /dev/null +++ b/tests/hash/tests-slow-1.txt @@ -0,0 +1,5 @@ +b46aab7facce3eb4b4679d1d526f2d500d43736988b7881853c4c0c4af04ac0e 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +f0f0ab8a50a809ccd82c76996e494b20a1e01e90ed4814a27db2558511559091 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +13310922971e1112b382357aeaa8b0bf0cd941dc6f5e398979f3fa77d13749bd 8519e039172b0d70e5ca7b3383d6b3167315a422747b73f019cf9528f0fde341fd0f2a63030ba6450525cf6de31837669af6f1df8131faf50aaab8d3a7405589 +0d9f641d14a782748ed5548f72a20c83c4a2cfe606015ad9eda5b36a00947d72 37a636d7dafdf259b7287eddca2f58099e98619d2f99bdb8969d7b14498102cc065201c8be90bd777323f449848b215d2977c92c4c1c2da36ab46b2e389689ed97c18fec08cd3b03235c5e4c62a37ad88c7b67932495a71090e85dd4020a9300 +d74a0c9b603aa9f9af0bfec0c36d3d383c14930a0ee2f08dab44536fccda5bee 38274c97c45a172cfc97679870422e3a1ab0784960c60514d816271415c306ee3a3ed1a77e31f6a885c3cb From d58c9ec99c3187ea41b594e9e5ae885f456f00fc Mon Sep 17 00:00:00 2001 From: SChernykh Date: Fri, 16 Feb 2018 09:11:54 +0000 Subject: [PATCH 2/3] slow-hash: optimized version --- src/crypto/slow-hash.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index 5bfc93021..f81aadfab 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -52,10 +52,10 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp #define VARIANT1_1(p) \ do if (variant > 0) \ { \ - uint8_t tmp = ((const uint8_t*)p)[11]; \ - uint8_t tmp1 = (tmp>>4)&1, tmp2 = (tmp>>5)&1, tmp3 = tmp1^tmp2; \ - uint8_t tmp0 = (((const uint8_t*)p)[11] & 1) ? tmp3 : ((((tmp2<<1)|tmp1) + 1)&3); \ - ((uint8_t*)p)[11] = (((const uint8_t*)p)[11] & 1) ? ((tmp & 0xef) | (tmp0<<4)):((tmp & 0xcf) | (tmp0<<4)); \ + const uint8_t tmp = ((const uint8_t*)(p))[11]; \ + static const uint32_t table = 0x75310; \ + const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ + ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ } while(0) #define VARIANT1_2(p) \ From e136bc6b8a480426f7565b721ca2ccf75547af62 Mon Sep 17 00:00:00 2001 From: Lee Clagett Date: Tue, 27 Feb 2018 18:45:32 -0500 Subject: [PATCH 3/3] tweaks to the monerov1 cryptonight algorithm --- src/crypto/slow-hash.c | 68 ++++++++++++++++++++++++++++--------- tests/hash/tests-slow-1.txt | 10 +++--- 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c index f81aadfab..c733d7b39 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -61,16 +61,33 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp #define VARIANT1_2(p) \ do if (variant > 0) \ { \ - ((uint32_t*)p)[2] ^= nonce; \ + xor64(p, tweak1_2); \ } while(0) -#define VARIANT1_INIT() \ - if (variant > 0 && length < 43) \ +#define VARIANT1_CHECK() \ + do if (length < 43) \ { \ fprintf(stderr, "Cryptonight variants need at least 43 bytes of data"); \ _exit(1); \ + } while(0) + +#define NONCE_POINTER (((const uint8_t*)data)+35) + +#define VARIANT1_PORTABLE_INIT() \ + uint8_t tweak1_2[8]; \ + do if (variant > 0) \ + { \ + VARIANT1_CHECK(); \ + memcpy(&tweak1_2, &state.hs.b[192], sizeof(tweak1_2)); \ + xor64(tweak1_2, NONCE_POINTER); \ + } while(0) + +#define VARIANT1_INIT64() \ + if (variant > 0) \ + { \ + VARIANT1_CHECK(); \ } \ - const uint32_t nonce = variant > 0 ? *(const uint32_t*)(((const uint8_t*)data)+39) : 0 + const uint64_t tweak1_2 = variant > 0 ? (state.hs.w[24] ^ (*((const uint64_t*)NONCE_POINTER))) : 0 #if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))) // Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI @@ -159,8 +176,8 @@ extern int aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *exp p = U64(&hp_state[j]); \ p[0] = a[0]; p[1] = a[1]; \ a[0] ^= b[0]; a[1] ^= b[1]; \ + VARIANT1_2(p + 1); \ _b = _c; \ - VARIANT1_2(&hp_state[j]); \ #if defined(_MSC_VER) #define THREADV __declspec(thread) @@ -210,6 +227,11 @@ STATIC INLINE void xor_blocks(uint8_t *a, const uint8_t *b) U64(a)[1] ^= U64(b)[1]; } +STATIC INLINE void xor64(uint64_t *a, const uint64_t b) +{ + *a ^= b; +} + /** * @brief uses cpuid to determine if the CPU supports the AES instructions * @return true if the CPU supports AES, false otherwise @@ -568,8 +590,6 @@ void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; - VARIANT1_INIT(); - // this isn't supposed to happen, but guard against it for now. if(hp_state == NULL) slow_hash_allocate_state(); @@ -582,6 +602,8 @@ void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, } memcpy(text, state.init, INIT_SIZE_BYTE); + VARIANT1_INIT64(); + /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill * the 2MB large random access buffer. */ @@ -705,6 +727,11 @@ void slow_hash_free_state(void) #define U64(x) ((uint64_t *) (x)) +STATIC INLINE void xor64(uint64 *a, const uint64 b) +{ + *a ^= b; +} + #pragma pack(push, 1) union cn_slow_hash_state { @@ -750,7 +777,7 @@ union cn_slow_hash_state p = U64(&hp_state[j]); \ p[0] = a[0]; p[1] = a[1]; \ a[0] ^= b[0]; a[1] ^= b[1]; \ - VARIANT1_2(p); \ + VARIANT1_2(p + 1); \ _b = _c; \ @@ -903,13 +930,13 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; - VARIANT1_INIT(); - /* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */ hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); + VARIANT1_INIT64(); + /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill * the 2MB large random access buffer. */ @@ -1097,8 +1124,6 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein }; - VARIANT1_INIT(); - #ifndef FORCE_USE_HEAP uint8_t long_state[MEMORY]; #else @@ -1109,6 +1134,8 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); + VARIANT1_INIT64(); + aes_ctx = (oaes_ctx *) oaes_alloc(); oaes_key_import_data(aes_ctx, state.hs.b, AES_KEY_SIZE); @@ -1148,7 +1175,7 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) swap_blocks(b, p); xor_blocks(b, p); swap_blocks(a, b); - VARIANT1_2(p); + VARIANT1_2(U64(p) + 1); } memcpy(text, state.init, INIT_SIZE_BYTE); @@ -1243,6 +1270,15 @@ static void xor_blocks(uint8_t* a, const uint8_t* b) { } } +static void xor64(uint8_t* left, const uint8_t* right) +{ + size_t i; + for (i = 0; i < 8; ++i) + { + left[i] ^= right[i]; + } +} + #pragma pack(push, 1) union cn_slow_hash_state { union hash_state hs; @@ -1265,13 +1301,13 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { uint8_t aes_key[AES_KEY_SIZE]; oaes_ctx *aes_ctx; - VARIANT1_INIT(); - hash_process(&state.hs, data, length); memcpy(text, state.init, INIT_SIZE_BYTE); memcpy(aes_key, state.hs.b, AES_KEY_SIZE); aes_ctx = (oaes_ctx *) oaes_alloc(); + VARIANT1_PORTABLE_INIT(); + oaes_key_import_data(aes_ctx, aes_key, AES_KEY_SIZE); for (i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) { for (j = 0; j < INIT_SIZE_BLK; j++) { @@ -1307,10 +1343,10 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { sum_half_blocks(b, d); swap_blocks(b, c); xor_blocks(b, c); + VARIANT1_2(c + 8); copy_block(&long_state[j * AES_BLOCK_SIZE], c); assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE)); swap_blocks(a, b); - VARIANT1_2(&long_state[j * AES_BLOCK_SIZE]); } memcpy(text, state.init, INIT_SIZE_BYTE); diff --git a/tests/hash/tests-slow-1.txt b/tests/hash/tests-slow-1.txt index 0c571f86f..ed8eccc22 100644 --- a/tests/hash/tests-slow-1.txt +++ b/tests/hash/tests-slow-1.txt @@ -1,5 +1,5 @@ -b46aab7facce3eb4b4679d1d526f2d500d43736988b7881853c4c0c4af04ac0e 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -f0f0ab8a50a809ccd82c76996e494b20a1e01e90ed4814a27db2558511559091 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -13310922971e1112b382357aeaa8b0bf0cd941dc6f5e398979f3fa77d13749bd 8519e039172b0d70e5ca7b3383d6b3167315a422747b73f019cf9528f0fde341fd0f2a63030ba6450525cf6de31837669af6f1df8131faf50aaab8d3a7405589 -0d9f641d14a782748ed5548f72a20c83c4a2cfe606015ad9eda5b36a00947d72 37a636d7dafdf259b7287eddca2f58099e98619d2f99bdb8969d7b14498102cc065201c8be90bd777323f449848b215d2977c92c4c1c2da36ab46b2e389689ed97c18fec08cd3b03235c5e4c62a37ad88c7b67932495a71090e85dd4020a9300 -d74a0c9b603aa9f9af0bfec0c36d3d383c14930a0ee2f08dab44536fccda5bee 38274c97c45a172cfc97679870422e3a1ab0784960c60514d816271415c306ee3a3ed1a77e31f6a885c3cb +b5a7f63abb94d07d1a6445c36c07c7e8327fe61b1647e391b4c7edae5de57a3d 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +80563c40ed46575a9e44820d93ee095e2851aa22483fd67837118c6cd951ba61 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +5bb40c5880cef2f739bdb6aaaf16161eaae55530e7b10d7ea996b751a299e949 8519e039172b0d70e5ca7b3383d6b3167315a422747b73f019cf9528f0fde341fd0f2a63030ba6450525cf6de31837669af6f1df8131faf50aaab8d3a7405589 +613e638505ba1fd05f428d5c9f8e08f8165614342dac419adc6a47dce257eb3e 37a636d7dafdf259b7287eddca2f58099e98619d2f99bdb8969d7b14498102cc065201c8be90bd777323f449848b215d2977c92c4c1c2da36ab46b2e389689ed97c18fec08cd3b03235c5e4c62a37ad88c7b67932495a71090e85dd4020a9300 +ed082e49dbd5bbe34a3726a0d1dad981146062b39d36d62c71eb1ed8ab49459b 38274c97c45a172cfc97679870422e3a1ab0784960c60514d816271415c306ee3a3ed1a77e31f6a885c3cb