From 27a196b1268718dbc41e308c93b35c58f2da2eb4 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 5 Mar 2018 16:16:30 +0900 Subject: device: untangle cyclic depenency When #3303 was merged, a cyclic dependency chain was generated: libdevice <- libcncrypto <- libringct <- libdevice This was because libdevice needs access to a set of basic crypto operations implemented in libringct such as scalarmultBase(), while libringct also needs access to abstracted crypto operations implemented in libdevice such as ecdhEncode(). To untangle this cyclic dependency chain, this patch splits libringct into libringct_basic and libringct, where the basic crypto ops previously in libringct are moved into libringct_basic. The cyclic dependency is now resolved thanks to this separation: libcncrypto <- libringct_basic <- libdevice <- libcryptonote_basic <- libringct This eliminates the need for crypto_device.cpp and rctOps_device.cpp. Also, many abstracted interfaces of hw::device such as encrypt_payment_id() and get_subaddress_secret_key() were previously implemented in libcryptonote_basic (cryptonote_format_utils.cpp) and were then called from hw::core::device_default, which is odd because libdevice is supposed to be independent of libcryptonote_basic. Therefore, those functions were moved to device_default.cpp. --- tests/crypto/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) (limited to 'tests') diff --git a/tests/crypto/CMakeLists.txt b/tests/crypto/CMakeLists.txt index c89049d50..df96c57cc 100644 --- a/tests/crypto/CMakeLists.txt +++ b/tests/crypto/CMakeLists.txt @@ -42,10 +42,7 @@ add_executable(cncrypto-tests ${crypto_headers}) target_link_libraries(cncrypto-tests PRIVATE - wallet - cryptonote_core common - device ${Boost_SYSTEM_LIBRARY} ${EXTRA_LIBRARIES}) set_property(TARGET cncrypto-tests -- cgit v1.2.3 From 8705beaf51c12d7eab5f56f615ec529a2a8efc27 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 5 Mar 2018 17:02:17 +0900 Subject: keypair::generate: always require hw::device to avoid possible mistake --- src/cryptonote_basic/cryptonote_basic.h | 6 ------ src/cryptonote_core/cryptonote_tx_utils.cpp | 2 +- src/device/device_default.cpp | 2 +- tests/core_tests/chaingen.cpp | 2 +- tests/core_tests/tx_validation.cpp | 4 ++-- tests/performance_tests/generate_keypair.h | 2 +- 6 files changed, 6 insertions(+), 12 deletions(-) (limited to 'tests') diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 12124ebf5..d4558ef7b 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -429,12 +429,6 @@ namespace cryptonote crypto::public_key pub; crypto::secret_key sec; - static inline keypair generate() - { - keypair k; - generate_keys(k.pub, k.sec); - return k; - } static inline keypair generate(hw::device &hwdev) { keypair k; diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index cbacc7893..db4ab9e11 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -78,7 +78,7 @@ namespace cryptonote tx.vout.clear(); tx.extra.clear(); - keypair txkey = keypair::generate(); + keypair txkey = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(tx, txkey.pub); if(!extra_nonce.empty()) if(!add_extra_nonce_to_tx_extra(tx.extra, extra_nonce)) diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index 6d60c8cc1..d63dafe9e 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -251,7 +251,7 @@ namespace hw { /* ======================================================================= */ bool device_default::open_tx(crypto::secret_key &tx_key) { - cryptonote::keypair txkey = cryptonote::keypair::generate(); + cryptonote::keypair txkey = cryptonote::keypair::generate(*this); tx_key = txkey.sec; return true; } diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index 5e1525e3e..41256a4f1 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -521,7 +521,7 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins keypair* p_txkey/* = 0*/) { keypair txkey; - txkey = keypair::generate(); + txkey = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(tx, txkey.pub); if (0 != p_txkey) diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index d6d5236aa..f0a385ee5 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -49,7 +49,7 @@ namespace m_tx.version = version; m_tx.unlock_time = unlock_time; - m_tx_key = keypair::generate(); + m_tx_key = keypair::generate(hw::get_device("default")); add_tx_pub_key_to_extra(m_tx, m_tx_key.pub); } @@ -518,7 +518,7 @@ bool gen_tx_key_image_not_derive_from_tx_key::generate(std::vector(builder.m_tx.vin.front()); - keypair kp = keypair::generate(); + keypair kp = keypair::generate(hw::get_device("default")); key_image another_ki; crypto::generate_key_image(kp.pub, kp.sec, another_ki); in_to_key.k_image = another_ki; diff --git a/tests/performance_tests/generate_keypair.h b/tests/performance_tests/generate_keypair.h index f97f4c213..91c830166 100644 --- a/tests/performance_tests/generate_keypair.h +++ b/tests/performance_tests/generate_keypair.h @@ -45,7 +45,7 @@ public: bool test() { - cryptonote::keypair::generate(); + cryptonote::keypair::generate(hw::get_device("default")); return true; } }; -- cgit v1.2.3 From b2d23b189efaafe89082a9f14e376c2cbad42f40 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 5 Mar 2018 17:20:36 +0900 Subject: crypto: revert odd namespace changes made in #3303 --- src/crypto/crypto.cpp | 2 +- src/crypto/crypto.h | 9 --------- tests/crypto/crypto.cpp | 12 ++++++------ 3 files changed, 7 insertions(+), 16 deletions(-) (limited to 'tests') diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index 0c70b9eeb..494027560 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -436,7 +436,7 @@ namespace crypto { return sc_isnonzero(&c2) == 0; } - void crypto_ops::hash_to_ec(const public_key &key, ge_p3 &res) { + static void hash_to_ec(const public_key &key, ge_p3 &res) { hash h; ge_p2 point; ge_p1p1 point2; diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 9d0e5066b..81ebfb9e2 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -46,9 +46,6 @@ #include "hex.h" #include "span.h" #include "hash.h" -extern "C" { - #include "crypto-ops.h" -} namespace crypto { @@ -116,9 +113,6 @@ namespace crypto { void operator=(const crypto_ops &); ~crypto_ops(); - static void hash_to_ec(const public_key &key, ge_p3 &res) ; - friend void hash_to_ec(const public_key &key, ge_p3 &res) ; - static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false); friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover); static bool check_key(const public_key &); @@ -172,9 +166,6 @@ namespace crypto { return res; } - inline void hash_to_ec(const public_key &key, ge_p3 &res) { - crypto_ops::hash_to_ec(key,res); - } /* Generate a new key pair */ inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) { diff --git a/tests/crypto/crypto.cpp b/tests/crypto/crypto.cpp index 90212bd0b..6a1dd1b29 100644 --- a/tests/crypto/crypto.cpp +++ b/tests/crypto/crypto.cpp @@ -33,7 +33,7 @@ #include "crypto-tests.h" bool check_scalar(const crypto::ec_scalar &scalar) { - return sc_check(crypto::operator &(scalar)) == 0; + return crypto::sc_check(crypto::operator &(scalar)) == 0; } void random_scalar(crypto::ec_scalar &res) { @@ -45,13 +45,13 @@ void hash_to_scalar(const void *data, std::size_t length, crypto::ec_scalar &res } void hash_to_point(const crypto::hash &h, crypto::ec_point &res) { - ge_p2 point; - ge_fromfe_frombytes_vartime(&point, reinterpret_cast(&h)); - ge_tobytes(crypto::operator &(res), &point); + crypto::ge_p2 point; + crypto::ge_fromfe_frombytes_vartime(&point, reinterpret_cast(&h)); + crypto::ge_tobytes(crypto::operator &(res), &point); } void hash_to_ec(const crypto::public_key &key, crypto::ec_point &res) { - ge_p3 tmp; + crypto::ge_p3 tmp; crypto::hash_to_ec(key, tmp); - ge_p3_tobytes(crypto::operator &(res), &tmp); + crypto::ge_p3_tobytes(crypto::operator &(res), &tmp); } -- cgit v1.2.3 From 7dfa5e9e6e05fb2b8bb346d92f2a22229ef495c8 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 5 Mar 2018 18:24:11 +0900 Subject: chacha: call prehashed version explicitly as generate_chacha_key_prehashed hash: add prehashed version cn_slow_hash_prehashed slow-hash: let cn_slow_hash take 4th parameter for deciding prehashed or not slow-hash: add support for prehashed version for the other 3 platforms --- src/crypto/chacha.h | 11 +++++++++-- src/crypto/hash-ops.h | 3 +-- src/crypto/hash.h | 6 +++++- src/crypto/slow-hash.c | 30 +++++++++++++++++++----------- src/device/device_ledger.cpp | 4 ++-- tests/hash/main.cpp | 4 ++-- 6 files changed, 38 insertions(+), 20 deletions(-) (limited to 'tests') diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index 22da53bd0..7a120931a 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -69,10 +69,17 @@ 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, int cn_variant = 0, bool prehashed=false) { + inline void generate_chacha_key(const void *data, size_t size, chacha_key& key) { 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(), cn_variant, prehashed); + crypto::cn_slow_hash(data, size, pwd_hash.data(), 0/*variant*/, 0/*prehashed*/); + memcpy(&key, pwd_hash.data(), sizeof(key)); + } + + inline void generate_chacha_key_prehashed(const void *data, size_t size, chacha_key& key) { + 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(data, size, pwd_hash.data(), 0/*variant*/, 1/*prehashed*/); memcpy(&key, pwd_hash.data(), sizeof(key)); } diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 934d464de..d77d55cf3 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -79,8 +79,7 @@ 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, int variant); -void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool pre); +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed); 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 bf4f4c096..995e2294e 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -72,7 +72,11 @@ namespace crypto { } 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); + cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 0/*prehashed*/); + } + + inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0) { + cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 1/*prehashed*/); } 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 8c7dad8e0..d7dcbd274 100644 --- a/src/crypto/slow-hash.c +++ b/src/crypto/slow-hash.c @@ -564,11 +564,7 @@ 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, int variant) { - cn_slow_hash_pre(data,length,hash,variant,false); -} - -void cn_slow_hash_pre(const void *data, size_t length, char *hash, int variant, bool prehashed) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */ @@ -909,7 +905,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, int variant) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { RDATA_ALIGN16 uint8_t expandedKey[240]; RDATA_ALIGN16 uint8_t hp_state[MEMORY]; @@ -932,7 +928,11 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) /* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */ - hash_process(&state.hs, data, length); + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } memcpy(text, state.init, INIT_SIZE_BYTE); VARIANT1_INIT64(); @@ -1105,7 +1105,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, int variant) +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { uint8_t text[INIT_SIZE_BYTE]; uint8_t a[AES_BLOCK_SIZE]; @@ -1131,7 +1131,11 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant) long_state = (uint8_t *)malloc(MEMORY); #endif - hash_process(&state.hs, data, length); + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } memcpy(text, state.init, INIT_SIZE_BYTE); VARIANT1_INIT64(); @@ -1289,7 +1293,7 @@ union cn_slow_hash_state { }; #pragma pack(pop) -void cn_slow_hash(const void *data, size_t length, char *hash, int variant) { +void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { uint8_t long_state[MEMORY]; union cn_slow_hash_state state; uint8_t text[INIT_SIZE_BYTE]; @@ -1301,7 +1305,11 @@ 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; - hash_process(&state.hs, data, length); + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + 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(); diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index ccbc45b45..b3c0035a1 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -513,10 +513,10 @@ namespace hw { char prekey[200]; memmove(prekey, &this->buffer_recv[0], 200); - crypto::generate_chacha_key(&prekey[0], sizeof(prekey), key, 0, true); + crypto::generate_chacha_key_prehashed(&prekey[0], sizeof(prekey), key); #ifdef DEBUG_HWDEVICE - hw::ledger::check32("generate_chacha_key", "key", (char*)key_x.data(), (char*)key.data()); + hw::ledger::check32("generate_chacha_key_prehashed", "key", (char*)key_x.data(), (char*)key.data()); #endif unlock_device(); diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index 5a16284df..c7e1fe712 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -52,10 +52,10 @@ 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); + return cn_slow_hash(data, length, hash, 0/*variant*/, 0/*prehashed*/); } static void cn_slow_hash_1(const void *data, size_t length, char *hash) { - return cn_slow_hash(data, length, hash, 1); + return cn_slow_hash(data, length, hash, 1/*variant*/, 0/*prehashed*/); } } POP_WARNINGS -- cgit v1.2.3