From 27a196b1268718dbc41e308c93b35c58f2da2eb4 Mon Sep 17 00:00:00 2001 From: stoffu Date: Mon, 5 Mar 2018 16:16:30 +0900 Subject: [PATCH] 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. --- src/crypto/CMakeLists.txt | 2 - src/crypto/crypto.h | 12 -- src/crypto/crypto_device.cpp | 75 ------- src/cryptonote_basic/account.cpp | 1 - src/cryptonote_basic/account.h | 1 - src/cryptonote_basic/cryptonote_basic.h | 3 +- .../cryptonote_format_utils.cpp | 195 ++---------------- .../cryptonote_format_utils.h | 15 -- src/cryptonote_core/cryptonote_tx_utils.cpp | 19 +- src/device/CMakeLists.txt | 3 +- src/device/device.hpp | 14 +- src/device/device_declare.hpp | 37 ---- src/device/device_default.cpp | 109 +++++++++- src/device/device_ledger.cpp | 2 + src/multisig/multisig.cpp | 1 - src/ringct/CMakeLists.txt | 30 ++- src/ringct/rctOps.h | 6 - src/ringct/rctOps_device.cpp | 66 ------ src/ringct/rctSigs.cpp | 11 +- src/ringct/rctSigs.h | 5 +- src/simplewallet/simplewallet.cpp | 1 - src/wallet/CMakeLists.txt | 1 + src/wallet/api/wallet_manager.cpp | 1 - src/wallet/wallet2.cpp | 39 ++-- tests/crypto/CMakeLists.txt | 3 - 25 files changed, 189 insertions(+), 463 deletions(-) delete mode 100644 src/crypto/crypto_device.cpp delete mode 100644 src/device/device_declare.hpp delete mode 100644 src/ringct/rctOps_device.cpp diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 35c099697..71dcedcab 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -33,7 +33,6 @@ set(crypto_sources crypto-ops-data.c crypto-ops.c crypto.cpp - crypto_device.cpp groestl.c hash-extra-blake.c hash-extra-groestl.c @@ -78,7 +77,6 @@ monero_add_library(cncrypto target_link_libraries(cncrypto PUBLIC epee - device ${Boost_SYSTEM_LIBRARY} PRIVATE ${EXTRA_LIBRARIES}) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 75b333473..9d0e5066b 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -46,7 +46,6 @@ #include "hex.h" #include "span.h" #include "hash.h" -#include "device/device_declare.hpp" extern "C" { #include "crypto-ops.h" } @@ -156,17 +155,6 @@ namespace crypto { const public_key *const *, std::size_t, const signature *); }; - secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover, hw::device &hwdev); - secret_key generate_keys(public_key &pub, secret_key &sec, hw::device &hwdev); - bool secret_key_to_public_key(const secret_key &sec, public_key &pub, hw::device &hwdev); - bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation, hw::device &hwdev); - void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res, hw::device &hwdev) ; - bool derive_public_key(const key_derivation &derivation, size_t output_index, const public_key &base, public_key &derived_key, hw::device &hwdev); - void derive_secret_key(const key_derivation &derivation, size_t output_index, const secret_key &base, secret_key &derived_key, hw::device &hwdev); - bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key, hw::device &hwdev); - void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image, hw::device &hwdev); - - /* Generate N random bytes */ inline void rand(size_t N, uint8_t *bytes) { diff --git a/src/crypto/crypto_device.cpp b/src/crypto/crypto_device.cpp deleted file mode 100644 index 30831dced..000000000 --- a/src/crypto/crypto_device.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - - -#include "crypto.h" -#include "device/device.hpp" -#include "device/log.hpp" - -namespace crypto { - - secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover, hw::device &hwdev) { - return hwdev.generate_keys(pub, sec, recovery_key, recover); - } - - secret_key generate_keys(public_key &pub, secret_key &sec, hw::device &hwdev) { - return hwdev.generate_keys(pub, sec, secret_key(), false); - } - - - bool secret_key_to_public_key(const secret_key &sec, public_key &pub, hw::device &hwdev) { - return hwdev.secret_key_to_public_key(sec, pub); - } - - bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation, hw::device &hwdev) { - return hwdev.generate_key_derivation(key1, key2, derivation); - } - - void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res, hw::device &hwdev) { - hwdev.derivation_to_scalar(derivation, output_index, res); - } - - bool derive_public_key(const key_derivation &derivation, size_t output_index, - const public_key &base, public_key &derived_key, hw::device &hwdev) { - return hwdev.derive_public_key(derivation, output_index, base, derived_key); - } - - void derive_secret_key(const key_derivation &derivation, size_t output_index, - const secret_key &base, secret_key &derived_key, hw::device &hwdev) { - hwdev.derive_secret_key(derivation, output_index, base, derived_key); - } - - bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key, hw::device &hwdev) { - return hwdev.derive_subaddress_public_key(out_key, derivation, output_index, derived_key); - } - - void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image, hw::device &hwdev) { - hwdev.generate_key_image(pub,sec,image); - } -} \ No newline at end of file diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index 70f7533ea..bab991d19 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -40,7 +40,6 @@ extern "C" } #include "cryptonote_basic_impl.h" #include "cryptonote_format_utils.h" -#include "device/device.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "account" diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h index b5d6ed85d..b5d119c46 100644 --- a/src/cryptonote_basic/account.h +++ b/src/cryptonote_basic/account.h @@ -33,7 +33,6 @@ #include "cryptonote_basic.h" #include "crypto/crypto.h" #include "serialization/keyvalue_serialization.h" -#include "device/device_declare.hpp" namespace cryptonote { diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 4c5f32a09..12124ebf5 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -49,6 +49,7 @@ #include "misc_language.h" #include "tx_extra.h" #include "ringct/rctTypes.h" +#include "device/device.hpp" namespace cryptonote { @@ -437,7 +438,7 @@ namespace cryptonote static inline keypair generate(hw::device &hwdev) { keypair k; - generate_keys(k.pub, k.sec, hwdev); + hwdev.generate_keys(k.pub, k.sec); return k; } }; diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 1c10423fa..ae7c1c0ae 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -41,8 +41,6 @@ using namespace epee; #include "crypto/crypto.h" #include "crypto/hash.h" #include "ringct/rctSigs.h" -#include "device/device.hpp" -#include "device/log.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "cn" @@ -106,16 +104,6 @@ namespace cryptonote ge_p1p1_to_p3(&A2, &tmp3); ge_p3_tobytes(&AB, &A2); } - - // a copy of rct::scalarmultKey, since we can't link to libringct to avoid circular dependencies - static void secret_key_mult_public_key(crypto::public_key & aP, const crypto::public_key &P, const crypto::secret_key &a) { - ge_p3 A; - ge_p2 R; - //CHECK_AND_ASSERT_THROW_MES_L1(ge_frombytes_vartime(&A, P.bytes) == 0, "ge_frombytes_vartime failed at "+boost::lexical_cast(__LINE__)); - ge_frombytes_vartime(&A, (const unsigned char*)P.data); - ge_scalarmult(&R, (const unsigned char*)a.data, &A); - ge_tobytes((unsigned char*)aP.data, &R); - } } namespace cryptonote @@ -171,80 +159,18 @@ namespace cryptonote get_transaction_prefix_hash(tx, tx_prefix_hash); return true; } - //--------------------------------------------------------------- - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index) - { - const char prefix[] = "SubAddr"; - char data[sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(subaddress_index)]; - memcpy(data, prefix, sizeof(prefix)); - memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); - memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &index, sizeof(subaddress_index)); - crypto::secret_key m; - crypto::hash_to_scalar(data, sizeof(data), m); - return m; - } - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index, hw::device &hwdev) - { - return hwdev.get_subaddress_secret_key(a, index); - } - - //--------------------------------------------------------------- - std::vector get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) - { - CHECK_AND_ASSERT_THROW_MES(begin <= end, "begin > end"); - - std::vector pkeys; - pkeys.reserve(end - begin); - cryptonote::subaddress_index index = {account, begin}; - - ge_p3 p3; - ge_cached cached; - CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, (const unsigned char*)keys.m_account_address.m_spend_public_key.data) == 0, - "ge_frombytes_vartime failed to convert spend public key"); - ge_p3_to_cached(&cached, &p3); - - for (uint32_t idx = begin; idx < end; ++idx) - { - index.minor = idx; - if (index.is_zero()) - { - pkeys.push_back(keys.m_account_address.m_spend_public_key); - continue; - } - const crypto::secret_key m = cryptonote::get_subaddress_secret_key(keys.m_view_secret_key, index); - - // M = m*G - ge_scalarmult_base(&p3, (const unsigned char*)m.data); - - // D = B + M - crypto::public_key D; - ge_p1p1 p1p1; - ge_add(&p1p1, &p3, &cached); - ge_p1p1_to_p3(&p3, &p1p1); - ge_p3_tobytes((unsigned char*)D.data, &p3); - - pkeys.push_back(D); - } - return pkeys; - } - - std::vector get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, hw::device &hwdev) - { - return hwdev.get_subaddress_spend_public_keys(keys, account, begin, end); - } - //--------------------------------------------------------------- bool generate_key_image_helper(const account_keys& ack, const std::unordered_map& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev) { crypto::key_derivation recv_derivation = AUTO_VAL_INIT(recv_derivation); - bool r = crypto::generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation, hwdev); + bool r = hwdev.generate_key_derivation(tx_public_key, ack.m_view_secret_key, recv_derivation); CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << tx_public_key << ", " << ack.m_view_secret_key << ")"); std::vector additional_recv_derivations; for (size_t i = 0; i < additional_tx_public_keys.size(); ++i) { crypto::key_derivation additional_recv_derivation = AUTO_VAL_INIT(additional_recv_derivation); - r = crypto::generate_key_derivation(additional_tx_public_keys[i], ack.m_view_secret_key, additional_recv_derivation, hwdev); + r = hwdev.generate_key_derivation(additional_tx_public_keys[i], ack.m_view_secret_key, additional_recv_derivation); CHECK_AND_ASSERT_MES(r, false, "key image helper: failed to generate_key_derivation(" << additional_tx_public_keys[i] << ", " << ack.m_view_secret_key << ")"); additional_recv_derivations.push_back(additional_recv_derivation); } @@ -267,7 +193,7 @@ namespace cryptonote { // derive secret key with subaddress - step 1: original CN derivation crypto::secret_key scalar_step1; - crypto::derive_secret_key(recv_derivation, real_output_index, ack.m_spend_secret_key, scalar_step1, hwdev); // computes Hs(a*R || idx) + b + hwdev.derive_secret_key(recv_derivation, real_output_index, ack.m_spend_secret_key, scalar_step1); // computes Hs(a*R || idx) + b // step 2: add Hs(a || index_major || index_minor) crypto::secret_key subaddr_sk; @@ -287,17 +213,17 @@ namespace cryptonote if (ack.m_multisig_keys.empty()) { // when not in multisig, we know the full spend secret key, so the output pubkey can be obtained by scalarmultBase - CHECK_AND_ASSERT_MES(crypto::secret_key_to_public_key(in_ephemeral.sec, in_ephemeral.pub, hwdev), false, "Failed to derive public key"); + CHECK_AND_ASSERT_MES(hwdev.secret_key_to_public_key(in_ephemeral.sec, in_ephemeral.pub), false, "Failed to derive public key"); } else { // when in multisig, we only know the partial spend secret key. but we do know the full spend public key, so the output pubkey can be obtained by using the standard CN key derivation - CHECK_AND_ASSERT_MES(crypto::derive_public_key(recv_derivation, real_output_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub, hwdev), false, "Failed to derive public key"); + CHECK_AND_ASSERT_MES(hwdev.derive_public_key(recv_derivation, real_output_index, ack.m_account_address.m_spend_public_key, in_ephemeral.pub), false, "Failed to derive public key"); // and don't forget to add the contribution from the subaddress part if (!received_index.is_zero()) { crypto::public_key subaddr_pk; - CHECK_AND_ASSERT_MES(crypto::secret_key_to_public_key(subaddr_sk, subaddr_pk, hwdev), false, "Failed to derive public key"); + CHECK_AND_ASSERT_MES(hwdev.secret_key_to_public_key(subaddr_sk, subaddr_pk), false, "Failed to derive public key"); add_public_key(in_ephemeral.pub, in_ephemeral.pub, subaddr_pk); } } @@ -306,7 +232,7 @@ namespace cryptonote false, "key image helper precomp: given output pubkey doesn't match the derived one"); } - crypto::generate_key_image(in_ephemeral.pub, in_ephemeral.sec, ki, hwdev); + hwdev.generate_key_image(in_ephemeral.pub, in_ephemeral.sec, ki); return true; } //--------------------------------------------------------------- @@ -570,41 +496,6 @@ namespace cryptonote return true; } //--------------------------------------------------------------- - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) - { - crypto::key_derivation derivation; - crypto::hash hash; - char data[33]; /* A hash, and an extra byte */ - - if (!generate_key_derivation(public_key, secret_key, derivation)) - return false; - - memcpy(data, &derivation, 32); - data[32] = ENCRYPTED_PAYMENT_ID_TAIL; - cn_fast_hash(data, 33, hash); - - for (size_t b = 0; b < 8; ++b) - payment_id.data[b] ^= hash.data[b]; - - return true; - } - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) - { - // Encryption and decryption are the same operation (xor with a key) - return encrypt_payment_id(payment_id, public_key, secret_key); - } - - //--------------------------------------------------------------- - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key,hw::device &hwdev) - { - return hwdev.encrypt_payment_id(public_key, secret_key, payment_id); - } - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key, hw::device &hwdev) - { - // Encryption and decryption are the same operation (xor with a key) - return encrypt_payment_id(payment_id, public_key, secret_key, hwdev); - } - //--------------------------------------------------------------- bool get_inputs_money_amount(const transaction& tx, uint64_t& money) { money = 0; @@ -704,10 +595,10 @@ namespace cryptonote bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, const std::vector& additional_tx_pub_keys, size_t output_index) { crypto::key_derivation derivation; - bool r = generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation, acc.get_device()); + bool r = acc.get_device().generate_key_derivation(tx_pub_key, acc.m_view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation"); crypto::public_key pk; - r = derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk, acc.get_device()); + r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk); CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key"); if (pk == out_key.key) return true; @@ -715,9 +606,9 @@ namespace cryptonote if (!additional_tx_pub_keys.empty()) { CHECK_AND_ASSERT_MES(output_index < additional_tx_pub_keys.size(), false, "wrong number of additional tx pubkeys"); - r = generate_key_derivation(additional_tx_pub_keys[output_index], acc.m_view_secret_key, derivation, acc.get_device()); + r = acc.get_device().generate_key_derivation(additional_tx_pub_keys[output_index], acc.m_view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "Failed to generate key derivation"); - r = derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk, acc.get_device()); + r = acc.get_device().derive_public_key(derivation, output_index, acc.m_account_address.m_spend_public_key, pk); CHECK_AND_ASSERT_MES(r, false, "Failed to derive public key"); return pk == out_key.key; } @@ -728,7 +619,7 @@ namespace cryptonote { // try the shared tx pubkey crypto::public_key subaddress_spendkey; - derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey,hwdev); + hwdev.derive_subaddress_public_key(out_key, derivation, output_index, subaddress_spendkey); auto found = subaddresses.find(subaddress_spendkey); if (found != subaddresses.end()) return subaddress_receive_info{ found->second, derivation }; @@ -736,7 +627,7 @@ namespace cryptonote if (!additional_derivations.empty()) { CHECK_AND_ASSERT_MES(output_index < additional_derivations.size(), boost::none, "wrong number of additional derivations"); - derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey, hwdev); + hwdev.derive_subaddress_public_key(out_key, additional_derivations[output_index], output_index, subaddress_spendkey); found = subaddresses.find(subaddress_spendkey); if (found != subaddresses.end()) return subaddress_receive_info{ found->second, additional_derivations[output_index] }; @@ -1136,64 +1027,4 @@ namespace cryptonote sc_sub((unsigned char*)key.data, (const unsigned char*)key.data, (const unsigned char*)hash.data); return key; } - - //--------------------------------------------------------------- - #define CHACHA8_KEY_TAIL 0x8c - bool generate_chacha_key_from_secret_keys(const account_keys &keys, crypto::chacha_key &key) - { - const crypto::secret_key &view_key = keys.m_view_secret_key; - const crypto::secret_key &spend_key = keys.m_spend_secret_key; - tools::scrubbed_arr data; - memcpy(data.data(), &view_key, sizeof(view_key)); - memcpy(data.data() + sizeof(view_key), &spend_key, sizeof(spend_key)); - data[sizeof(data) - 1] = CHACHA8_KEY_TAIL; - crypto::generate_chacha_key(data.data(), sizeof(data), key); - return true; - } - - //--------------------------------------------------------------- - crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) - { - if (index.is_zero()) - return keys.m_account_address.m_spend_public_key; - - // m = Hs(a || index_major || index_minor) - crypto::secret_key m = cryptonote::get_subaddress_secret_key(keys.m_view_secret_key, index); - - // M = m*G - crypto::public_key M; - crypto::secret_key_to_public_key(m, M); - - // D = B + M - crypto::public_key D; - add_public_key(D, keys.m_account_address.m_spend_public_key, M); // could have defined add_public_key() under src/crypto - return D; - } - - //--------------------------------------------------------------- - cryptonote::account_public_address get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index& index) - { - if (index.is_zero()) - return keys.m_account_address; - - crypto::public_key D = get_subaddress_spend_public_key(keys, index); - - // C = a*D - crypto::public_key C; - secret_key_mult_public_key(C, D, keys.m_view_secret_key); // could have defined secret_key_mult_public_key() under src/crypto - - // result: (C, D) - cryptonote::account_public_address address; - address.m_view_public_key = C; - address.m_spend_public_key = D; - return address; - } - - //--------------------------------------------------------------- - bool verify_keys(const crypto::secret_key& sec, const crypto::public_key& expected_pub) - { - crypto::public_key pub; - bool r = crypto::secret_key_to_public_key(sec, pub); - return r && expected_pub == pub; - } } diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 7bd34ea87..79466e9c4 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -37,7 +37,6 @@ #include "crypto/crypto.h" #include "crypto/hash.h" #include -#include "device/device_declare.hpp" namespace epee { @@ -52,10 +51,6 @@ namespace cryptonote bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash); bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx); bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx); - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key); - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key, hw::device &hwdev); - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key); - bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key, hw::device &hwdev); template bool find_tx_extra_field_by_type(const std::vector& tx_extra_fields, T& field, size_t index = 0) @@ -95,10 +90,6 @@ namespace cryptonote bool lookup_acc_outs(const account_keys& acc, const transaction& tx, std::vector& outs, uint64_t& money_transfered); bool get_tx_fee(const transaction& tx, uint64_t & fee); uint64_t get_tx_fee(const transaction& tx); - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index); - crypto::secret_key get_subaddress_secret_key(const crypto::secret_key& a, const subaddress_index& index, hw::device &hwdev); - std::vector get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end); - std::vector get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end, hw::device &hwdev); bool generate_key_image_helper(const account_keys& ack, const std::unordered_map& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev); bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev); void get_blob_hash(const blobdata& blob, crypto::hash& res); @@ -242,10 +233,4 @@ namespace cryptonote #define CHECKED_GET_SPECIFIC_VARIANT(variant_var, specific_type, variable_name, fail_return_val) \ CHECK_AND_ASSERT_MES(variant_var.type() == typeid(specific_type), fail_return_val, "wrong variant type: " << variant_var.type().name() << ", expected " << typeid(specific_type).name()); \ specific_type& variable_name = boost::get(variant_var); - - cryptonote::account_public_address get_subaddress(const cryptonote::account_keys &keys, const cryptonote::subaddress_index& index); - crypto::public_key get_subaddress_spend_public_key(const cryptonote::account_keys &keys, const cryptonote::subaddress_index& index); - bool generate_chacha_key_from_secret_keys(const cryptonote::account_keys &keys, crypto::chacha_key &key); - bool verify_keys(const crypto::secret_key& sec, const crypto::public_key& expected_pub); - } diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index df98feb5a..cbacc7893 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -41,7 +41,6 @@ using namespace epee; #include "crypto/hash.h" #include "ringct/rctSigs.h" #include "multisig/multisig.h" -#include "device/device.hpp" using namespace crypto; @@ -237,7 +236,7 @@ namespace cryptonote return false; } - if (!encrypt_payment_id(payment_id, view_key_pub, tx_key, hwdev)) + if (!hwdev.encrypt_payment_id(payment_id, view_key_pub, tx_key)) { LOG_ERROR("Failed to encrypt payment id"); return false; @@ -343,11 +342,11 @@ namespace cryptonote // if this is a single-destination transfer to a subaddress, we set the tx pubkey to R=s*D if (num_stdaddresses == 0 && num_subaddresses == 1) { - txkey_pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(single_dest_subaddress.m_spend_public_key), rct::sk2rct(tx_key), hwdev)); + txkey_pub = rct::rct2pk(hwdev.scalarmultKey(rct::pk2rct(single_dest_subaddress.m_spend_public_key), rct::sk2rct(tx_key))); } else { - txkey_pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(tx_key), hwdev)); + txkey_pub = rct::rct2pk(hwdev.scalarmultBase(rct::sk2rct(tx_key))); } remove_field_from_tx_extra(tx.extra, typeid(tx_extra_pub_key)); add_tx_pub_key_to_extra(tx, txkey_pub); @@ -376,22 +375,22 @@ namespace cryptonote { additional_txkey.sec = additional_tx_keys[output_index]; if (dst_entr.is_subaddress) - additional_txkey.pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec),hwdev)); + additional_txkey.pub = rct::rct2pk(hwdev.scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec))); else - additional_txkey.pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(additional_txkey.sec), hwdev)); + additional_txkey.pub = rct::rct2pk(hwdev.scalarmultBase(rct::sk2rct(additional_txkey.sec))); } bool r; if (change_addr && dst_entr.addr == *change_addr) { // sending change to yourself; derivation = a*R - r = crypto::generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation, hwdev); + r = hwdev.generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation); CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")"); } else { // sending to the recipient; derivation = r*A (or s*C in the subaddress scheme) - r = crypto::generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation, hwdev); + r = hwdev.generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation); CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")"); } @@ -403,10 +402,10 @@ namespace cryptonote if (tx.version > 1) { crypto::secret_key scalar1; - crypto::derivation_to_scalar(derivation, output_index, scalar1, hwdev); + hwdev.derivation_to_scalar(derivation, output_index, scalar1); amount_keys.push_back(rct::sk2rct(scalar1)); } - r = crypto::derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key, hwdev); + r = hwdev.derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key); CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")"); hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, output_index, amount_keys.back(), out_eph_public_key); diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 7eccc1cc2..cc2d20a54 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -37,7 +37,6 @@ if(PCSC_FOUND) endif() set(device_headers - device_declare.hpp device.hpp device_default.hpp log.hpp @@ -68,7 +67,7 @@ target_link_libraries(device PUBLIC ${PCSC_LIBRARIES} cncrypto - ringct + ringct_basic ${OPENSSL_CRYPTO_LIBRARIES} PRIVATE ${Blocks} diff --git a/src/device/device.hpp b/src/device/device.hpp index 1d2181fa3..b47460472 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -44,9 +44,9 @@ #pragma once -#include "cryptonote_basic/cryptonote_basic.h" -#include "cryptonote_basic/account.h" -#include "cryptonote_basic/subaddress_index.h" +#include "crypto/crypto.h" +#include "crypto/chacha.h" +#include "ringct/rctTypes.h" #ifndef USE_DEVICE_LEDGER #define USE_DEVICE_LEDGER 1 @@ -61,6 +61,14 @@ #define WITH_DEVICE_LEDGER #endif +// forward declaration needed because this header is included by headers in libcryptonote_basic which depends on libdevice +namespace cryptonote +{ + struct account_public_address; + struct account_keys; + struct subaddress_index; +} + namespace hw { namespace { //device funcion not supported diff --git a/src/device/device_declare.hpp b/src/device/device_declare.hpp deleted file mode 100644 index fcf5762af..000000000 --- a/src/device/device_declare.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#pragma once - -namespace hw { - class device; - - device& get_device(std::string device_descriptor); -} - diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index f93e7db15..6d60c8cc1 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -31,10 +31,13 @@ #include "device_default.hpp" - -#include "cryptonote_basic/cryptonote_format_utils.h" +#include "cryptonote_basic/account.h" +#include "cryptonote_basic/subaddress_index.h" #include "ringct/rctOps.h" +#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d +#define CHACHA8_KEY_TAIL 0x8c + namespace hw { namespace core { @@ -83,7 +86,14 @@ namespace hw { /* ======================================================================= */ bool device_default::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) { - return cryptonote::generate_chacha_key_from_secret_keys(keys, key); + const crypto::secret_key &view_key = keys.m_view_secret_key; + const crypto::secret_key &spend_key = keys.m_spend_secret_key; + tools::scrubbed_arr data; + memcpy(data.data(), &view_key, sizeof(view_key)); + memcpy(data.data() + sizeof(view_key), &spend_key, sizeof(spend_key)); + data[sizeof(data) - 1] = CHACHA8_KEY_TAIL; + crypto::generate_chacha_key(data.data(), sizeof(data), key); + return true; } bool device_default::get_public_address(cryptonote::account_public_address &pubkey) { dfns(); @@ -100,19 +110,84 @@ namespace hw { } crypto::public_key device_default::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { - return cryptonote::get_subaddress_spend_public_key(keys,index); + if (index.is_zero()) + return keys.m_account_address.m_spend_public_key; + + // m = Hs(a || index_major || index_minor) + crypto::secret_key m = get_subaddress_secret_key(keys.m_view_secret_key, index); + + // M = m*G + crypto::public_key M; + crypto::secret_key_to_public_key(m, M); + + // D = B + M + crypto::public_key D = rct::rct2pk(rct::addKeys(rct::pk2rct(keys.m_account_address.m_spend_public_key), rct::pk2rct(M))); + return D; } std::vector device_default::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) { - return cryptonote::get_subaddress_spend_public_keys(keys, account, begin, end); + CHECK_AND_ASSERT_THROW_MES(begin <= end, "begin > end"); + + std::vector pkeys; + pkeys.reserve(end - begin); + cryptonote::subaddress_index index = {account, begin}; + + ge_p3 p3; + ge_cached cached; + CHECK_AND_ASSERT_THROW_MES(ge_frombytes_vartime(&p3, (const unsigned char*)keys.m_account_address.m_spend_public_key.data) == 0, + "ge_frombytes_vartime failed to convert spend public key"); + ge_p3_to_cached(&cached, &p3); + + for (uint32_t idx = begin; idx < end; ++idx) + { + index.minor = idx; + if (index.is_zero()) + { + pkeys.push_back(keys.m_account_address.m_spend_public_key); + continue; + } + crypto::secret_key m = get_subaddress_secret_key(keys.m_view_secret_key, index); + + // M = m*G + ge_scalarmult_base(&p3, (const unsigned char*)m.data); + + // D = B + M + crypto::public_key D; + ge_p1p1 p1p1; + ge_add(&p1p1, &p3, &cached); + ge_p1p1_to_p3(&p3, &p1p1); + ge_p3_tobytes((unsigned char*)D.data, &p3); + + pkeys.push_back(D); + } + return pkeys; } cryptonote::account_public_address device_default::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { - return cryptonote::get_subaddress(keys,index); + if (index.is_zero()) + return keys.m_account_address; + + crypto::public_key D = get_subaddress_spend_public_key(keys, index); + + // C = a*D + crypto::public_key C = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(D), rct::sk2rct(keys.m_view_secret_key))); + + // result: (C, D) + cryptonote::account_public_address address; + address.m_view_public_key = C; + address.m_spend_public_key = D; + return address; } crypto::secret_key device_default::get_subaddress_secret_key(const crypto::secret_key &a, const cryptonote::subaddress_index &index) { - return cryptonote::get_subaddress_secret_key(a,index); + const char prefix[] = "SubAddr"; + char data[sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(cryptonote::subaddress_index)]; + memcpy(data, prefix, sizeof(prefix)); + memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); + memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &index, sizeof(cryptonote::subaddress_index)); + crypto::secret_key m; + crypto::hash_to_scalar(data, sizeof(data), m); + return m; } /* ======================================================================= */ @@ -120,7 +195,9 @@ namespace hw { /* ======================================================================= */ bool device_default::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) { - return cryptonote::verify_keys(secret_key, public_key); + crypto::public_key calculated_pub; + bool r = crypto::secret_key_to_public_key(secret_key, calculated_pub); + return r && public_key == calculated_pub; } bool device_default::scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) { @@ -190,7 +267,21 @@ namespace hw { } bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { - return cryptonote::encrypt_payment_id(payment_id, public_key, secret_key); + crypto::key_derivation derivation; + crypto::hash hash; + char data[33]; /* A hash, and an extra byte */ + + if (!generate_key_derivation(public_key, secret_key, derivation)) + return false; + + memcpy(data, &derivation, 32); + data[32] = ENCRYPTED_PAYMENT_ID_TAIL; + cn_fast_hash(data, 33, hash); + + for (size_t b = 0; b < 8; ++b) + payment_id.data[b] ^= hash.data[b]; + + return true; } bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) { diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 2ebeb5b9b..ccbc45b45 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -30,6 +30,8 @@ #include "device_ledger.hpp" #include "log.hpp" #include "ringct/rctOps.h" +#include "cryptonote_basic/account.h" +#include "cryptonote_basic/subaddress_index.h" diff --git a/src/multisig/multisig.cpp b/src/multisig/multisig.cpp index 91042d58a..d85c47772 100644 --- a/src/multisig/multisig.cpp +++ b/src/multisig/multisig.cpp @@ -33,7 +33,6 @@ #include "cryptonote_basic/account.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "multisig.h" -#include "device/device_default.hpp" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "multisig" diff --git a/src/ringct/CMakeLists.txt b/src/ringct/CMakeLists.txt index 2d3ea5cf4..c8dcdca26 100644 --- a/src/ringct/CMakeLists.txt +++ b/src/ringct/CMakeLists.txt @@ -26,21 +26,39 @@ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -set(ringct_sources +set(ringct_basic_sources rctOps.cpp - rctOps_device.cpp - rctSigs.cpp rctTypes.cpp rctCryptoOps.c bulletproofs.cc) +set(ringct_basic_private_headers + rctOps.h + rctTypes.h + bulletproofs.h) + +monero_private_headers(ringct_basic + ${crypto_private_headers}) +monero_add_library(ringct_basic + ${ringct_basic_sources} + ${ringct_basic_private_headers}) +target_link_libraries(ringct_basic + PUBLIC + common + cncrypto + PRIVATE + ${OPENSSL_LIBRARIES} + ${EXTRA_LIBRARIES}) + +set(ringct_sources + rctSigs.cpp +) + set(ringct_headers) set(ringct_private_headers - rctOps.h rctSigs.h - rctTypes.h - bulletproofs.h) +) monero_private_headers(ringct ${crypto_private_headers}) diff --git a/src/ringct/rctOps.h b/src/ringct/rctOps.h index c9f2e7a43..3f8f6955c 100644 --- a/src/ringct/rctOps.h +++ b/src/ringct/rctOps.h @@ -112,14 +112,10 @@ namespace rct { //does a * G where a is a scalar and G is the curve basepoint void scalarmultBase(key & aG, const key &a); - void scalarmultBase(key & aG, const key &a, hw::device &hwdev); key scalarmultBase(const key & a); - key scalarmultBase(const key & a, hw::device &hwdev); //does a * P where a is a scalar and P is an arbitrary point void scalarmultKey(key &aP, const key &P, const key &a); - void scalarmultKey(key &aP, const key &P, const key &a, hw::device &hwdev); key scalarmultKey(const key &P, const key &a); - key scalarmultKey(const key &P, const key &a, hw::device &hwdev); //Computes aH where H= toPoint(cn_fast_hash(G)), G the basepoint key scalarmultH(const key & a); @@ -178,8 +174,6 @@ namespace rct { //Elliptic Curve Diffie Helman: encodes and decodes the amount b and mask a // where C= aG + bH void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec); - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, hw::device &hwdev); void ecdhDecode(ecdhTuple & masked, const key & sharedSec); - void ecdhDecode(ecdhTuple & masked, const key & sharedSec, hw::device &hwdev); } #endif /* RCTOPS_H */ diff --git a/src/ringct/rctOps_device.cpp b/src/ringct/rctOps_device.cpp deleted file mode 100644 index fbfe8e9cf..000000000 --- a/src/ringct/rctOps_device.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#include "misc_log_ex.h" -#include "rctOps.h" -#include "device/device.hpp" -using namespace crypto; -using namespace std; - - -namespace rct -{ - void scalarmultKey(key & aP, const key &P, const key &a, hw::device &hwdev) { - hwdev.scalarmultKey(aP, P, a); - } - - key scalarmultKey(const key & P, const key & a, hw::device &hwdev) { - key aP; - hwdev.scalarmultKey(aP, P, a); - return aP; - } - - void scalarmultBase(key &aG, const key &a, hw::device &hwdev) { - hwdev.scalarmultBase(aG, a); - } - - key scalarmultBase(const key & a, hw::device &hwdev) { - key aG; - hwdev.scalarmultBase(aG, a); - return aG; - } - - void ecdhDecode(ecdhTuple & masked, const key & sharedSec, hw::device &hwdev) { - hwdev.ecdhDecode(masked, sharedSec); - } - - void ecdhEncode(ecdhTuple & unmasked, const key & sharedSec, hw::device &hwdev) { - hwdev.ecdhEncode(unmasked, sharedSec); - } -} \ No newline at end of file diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index ae0ee21c8..f1f2f85a5 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -35,9 +35,6 @@ #include "rctSigs.h" #include "bulletproofs.h" #include "cryptonote_basic/cryptonote_format_utils.h" -#include "cryptonote_basic/cryptonote_basic.h" -#include "cryptonote_basic/subaddress_index.h" -#include "device/device.hpp" using namespace crypto; using namespace std; @@ -669,7 +666,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(amounts[i]); - ecdhEncode(rv.ecdhInfo[i], amount_keys[i], hwdev); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); } //set txn fee @@ -750,7 +747,7 @@ namespace rct { //mask amount and mask rv.ecdhInfo[i].mask = copy(outSk[i].mask); rv.ecdhInfo[i].amount = d2h(outamounts[i]); - ecdhEncode(rv.ecdhInfo[i], amount_keys[i],hwdev); + hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i]); } //set txn fee @@ -1007,7 +1004,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - ecdhDecode(ecdh_info, sk, hwdev); + hwdev.ecdhDecode(ecdh_info, sk); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; @@ -1035,7 +1032,7 @@ namespace rct { //mask amount and mask ecdhTuple ecdh_info = rv.ecdhInfo[i]; - ecdhDecode(ecdh_info, sk, hwdev); + hwdev.ecdhDecode(ecdh_info, sk); mask = ecdh_info.mask; key amount = ecdh_info.amount; key C = rv.outPk[i].mask; diff --git a/src/ringct/rctSigs.h b/src/ringct/rctSigs.h index 7485938ee..b8aab0f11 100644 --- a/src/ringct/rctSigs.h +++ b/src/ringct/rctSigs.h @@ -50,8 +50,6 @@ extern "C" { #include "rctTypes.h" #include "rctOps.h" -#include "cryptonote_basic/cryptonote_basic.h" -#include "device/device_declare.hpp" //Define this flag when debugging to get additional info on the console #ifdef DBG @@ -60,6 +58,9 @@ extern "C" { #define DP(x) #endif +namespace hw { + class device; +} namespace rct { diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 71ce1574f..b6d94ef48 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -62,7 +62,6 @@ #include "ringct/rctSigs.h" #include "multisig/multisig.h" #include "wallet/wallet_args.h" -#include "device/device.hpp" #include #ifdef WIN32 diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 36b661004..d82e1dace 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -113,6 +113,7 @@ if (BUILD_GUI_DEPS) cncrypto device ringct + ringct_basic checkpoints version) diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index b03332f40..80f5780b5 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -37,7 +37,6 @@ #include "common/updates.h" #include "version.h" #include "net/http_client.h" -#include "device/device.hpp" #include #include diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c583fe64d..5135d0f48 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -66,7 +66,6 @@ using namespace epee; #include "memwipe.h" #include "common/base58.h" #include "ringct/rctSigs.h" -#include "device/device.hpp" extern "C" { @@ -561,7 +560,7 @@ crypto::hash8 get_short_payment_id(const tools::wallet2::pending_tx &ptx, hw::de MWARNING("Encrypted payment id found, but no destinations public key, cannot decrypt"); return crypto::null_hash8; } - decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key, hwdev); + hwdev.decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key); } } return payment_id8; @@ -887,7 +886,7 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index) for (index2.major = m_subaddress_labels.size(); index2.major < major_end; ++index2.major) { const uint32_t end = get_subaddress_clamped_sum((index2.major == index.major ? index.minor : 0), m_subaddress_lookahead_minor); - const std::vector pkeys = cryptonote::get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, 0, end, hwdev); + const std::vector pkeys = hwdev.get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, 0, end); for (index2.minor = 0; index2.minor < end; ++index2.minor) { const crypto::public_key &D = pkeys[index2.minor]; @@ -903,7 +902,7 @@ void wallet2::expand_subaddresses(const cryptonote::subaddress_index& index) const uint32_t end = get_subaddress_clamped_sum(index.minor, m_subaddress_lookahead_minor); const uint32_t begin = m_subaddress_labels[index.major].size(); cryptonote::subaddress_index index2 = {index.major, begin}; - const std::vector pkeys = cryptonote::get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, index2.minor, end, hwdev); + const std::vector pkeys = hwdev.get_subaddress_spend_public_keys(m_account.get_keys(), index2.major, index2.minor, end); for (; index2.minor < end; ++index2.minor) { const crypto::public_key &D = pkeys[index2.minor - begin]; @@ -985,7 +984,7 @@ void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivatio static uint64_t decodeRct(const rct::rctSig & rv, const crypto::key_derivation &derivation, unsigned int i, rct::key & mask, hw::device &hwdev) { crypto::secret_key scalar1; - crypto::derivation_to_scalar(derivation, i, scalar1, hwdev); + hwdev.derivation_to_scalar(derivation, i, scalar1); try { switch (rv.type) @@ -1078,7 +1077,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote const cryptonote::account_keys& keys = m_account.get_keys(); hw::device &hwdev = m_account.get_device(); crypto::key_derivation derivation; - if (!generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation, hwdev)) + if (!hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation)) { MWARNING("Failed to generate key derivation from tx pubkey, skipping"); static_assert(sizeof(derivation) == sizeof(rct::key), "Mismatched sizes of key_derivation and rct::key"); @@ -1091,7 +1090,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i) { additional_derivations.push_back({}); - if (!generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back(),hwdev)) + if (!hwdev.generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back())) { MWARNING("Failed to generate key derivation from tx pubkey, skipping"); additional_derivations.pop_back(); @@ -1383,7 +1382,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote LOG_PRINT_L2("Found encrypted payment ID: " << payment_id8); if (tx_pub_key != null_pkey) { - if (!decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key, m_account.get_device())) + if (!m_account.get_device().decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key)) { LOG_PRINT_L0("Failed to decrypt payment ID: " << payment_id8); } @@ -4347,7 +4346,7 @@ crypto::hash wallet2::get_payment_id(const pending_tx &ptx) const MWARNING("Encrypted payment id found, but no destinations public key, cannot decrypt"); return crypto::null_hash; } - if (decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key, m_account.get_device())) + if (m_account.get_device().decrypt_payment_id(payment_id8, ptx.dests[0].addr.m_view_public_key, ptx.tx_key)) { memcpy(payment_id.data, payment_id8.data, 8); } @@ -7855,13 +7854,13 @@ bool wallet2::check_spend_proof(const crypto::hash &txid, const std::string &mes void wallet2::check_tx_key(const crypto::hash &txid, const crypto::secret_key &tx_key, const std::vector &additional_tx_keys, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) { crypto::key_derivation derivation; - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(address.m_view_public_key, tx_key, derivation, m_account.get_device()), error::wallet_internal_error, + THROW_WALLET_EXCEPTION_IF(!m_account.get_device().generate_key_derivation(address.m_view_public_key, tx_key, derivation), error::wallet_internal_error, "Failed to generate key derivation from supplied parameters"); std::vector additional_derivations; additional_derivations.resize(additional_tx_keys.size()); for (size_t i = 0; i < additional_tx_keys.size(); ++i) - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(address.m_view_public_key, additional_tx_keys[i], additional_derivations[i], m_account.get_device()), error::wallet_internal_error, + THROW_WALLET_EXCEPTION_IF(!m_account.get_device().generate_key_derivation(address.m_view_public_key, additional_tx_keys[i], additional_derivations[i]), error::wallet_internal_error, "Failed to generate key derivation from supplied parameters"); check_tx_key_helper(txid, derivation, additional_derivations, address, received, in_pool, confirmations); @@ -7903,13 +7902,13 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de continue; crypto::public_key derived_out_key; - bool r = derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key, hwdev); + bool r = hwdev.derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key"); bool found = out_key->key == derived_out_key; crypto::key_derivation found_derivation = derivation; if (!found && !additional_derivations.empty()) { - r = derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key,hwdev); + r = hwdev.derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key"); found = out_key->key == derived_out_key; found_derivation = additional_derivations[n]; @@ -7925,9 +7924,9 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de else { crypto::secret_key scalar1; - crypto::derivation_to_scalar(found_derivation, n, scalar1, hwdev); + hwdev.derivation_to_scalar(found_derivation, n, scalar1); rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n]; - rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), hwdev); + hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1)); const rct::key C = tx.rct_signatures.outPk[n].mask; rct::key Ctmp; rct::addKeys2(Ctmp, ecdh_info.mask, ecdh_info.amount, rct::H); @@ -8297,7 +8296,7 @@ std::string wallet2::get_reserve_proof(const boost::optional additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(spent_tx); std::vector additional_derivations; for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i) { additional_derivations.push_back({}); - r = generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back(), hwdev); + r = hwdev.generate_key_derivation(additional_tx_pub_keys[i], keys.m_view_secret_key, additional_derivations.back()); THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to generate key derivation"); } size_t output_index = 0; 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