From 39b595090b664950f8c15812873dda517d65b466 Mon Sep 17 00:00:00 2001 From: cslashm Date: Thu, 21 Mar 2019 14:40:56 +0100 Subject: [PATCH] add get_tx_proof_support --- src/device/device.hpp | 19 +--- src/device/device_default.cpp | 6 +- src/device/device_default.hpp | 4 + src/device/device_ledger.cpp | 144 ++++++++++++++++++++++++++---- src/device/device_ledger.hpp | 7 +- src/device/log.hpp | 13 +++ src/simplewallet/simplewallet.cpp | 5 -- src/wallet/wallet2.cpp | 53 ++++++----- 8 files changed, 189 insertions(+), 62 deletions(-) diff --git a/src/device/device.hpp b/src/device/device.hpp index 3774d4e8a19..618cc581c44 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -27,21 +27,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // - -/* Note about debug: - * To debug Device you can def the following : - * #define DEBUG_HWDEVICE - * Activate debug mechanism: - * - Add more trace - * - All computation done by device are checked by default device. - * Required IODUMMYCRYPT_HWDEVICE or IONOCRYPT_HWDEVICE for fully working - * #define IODUMMYCRYPT_HWDEVICE 1 - * - It assumes sensitive data encryption is is off on device side. a XOR with 0x55. This allow Ledger Class to make check on clear value - * #define IONOCRYPT_HWDEVICE 1 - * - It assumes sensitive data encryption is off on device side. - */ - - #pragma once #include "crypto/crypto.h" @@ -180,6 +165,10 @@ namespace hw { /* TRANSACTION */ /* ======================================================================= */ + virtual void generate_tx_proof(const crypto::hash &prefix_hash, + const crypto::public_key &R, const crypto::public_key &A, const boost::optional &B, const crypto::public_key &D, const crypto::secret_key &r, + crypto::signature &sig) = 0; + virtual bool open_tx(crypto::secret_key &tx_key) = 0; virtual bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) = 0; diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index 94bd8a75c24..0d45dd17d50 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -37,7 +37,6 @@ #include "cryptonote_core/cryptonote_tx_utils.h" #include "ringct/rctOps.h" -#include "log.hpp" #define ENCRYPTED_PAYMENT_ID_TAIL 0x8d #define CHACHA8_KEY_TAIL 0x8c @@ -273,6 +272,11 @@ namespace hw { /* ======================================================================= */ /* TRANSACTION */ /* ======================================================================= */ + void device_default::generate_tx_proof(const crypto::hash &prefix_hash, + const crypto::public_key &R, const crypto::public_key &A, const boost::optional &B, const crypto::public_key &D, const crypto::secret_key &r, + crypto::signature &sig) { + crypto::generate_tx_proof(prefix_hash, R, A, B, D, r, sig); + } bool device_default::open_tx(crypto::secret_key &tx_key) { cryptonote::keypair txkey = cryptonote::keypair::generate(*this); diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index cac4b784c03..983a56835a0 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -107,6 +107,10 @@ namespace hw { /* TRANSACTION */ /* ======================================================================= */ + void generate_tx_proof(const crypto::hash &prefix_hash, + const crypto::public_key &R, const crypto::public_key &A, const boost::optional &B, const crypto::public_key &D, const crypto::secret_key &r, + crypto::signature &sig) override; + bool open_tx(crypto::secret_key &tx_key) override; bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 5dd3193ec7e..c05b92ec6b3 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2018, The Monero Project +// Copyright (c) 2017-2019, The Monero Project // // All rights reserved. // @@ -29,7 +29,6 @@ #include "version.h" #include "device_ledger.hpp" -#include "log.hpp" #include "ringct/rctOps.h" #include "cryptonote_basic/account.h" #include "cryptonote_basic/subaddress_index.h" @@ -182,6 +181,7 @@ namespace hw { #define INS_MLSAG 0x7E #define INS_CLOSE_TX 0x80 + #define INS_GET_TX_PROOF 0xA0 #define INS_GET_RESPONSE 0xc0 @@ -274,7 +274,6 @@ namespace hw { int device_ledger::set_command_header(unsigned char ins, unsigned char p1, unsigned char p2) { reset_buffer(); - int offset = 0; this->buffer_send[0] = PROTOCOL_VERSION; this->buffer_send[1] = ins; this->buffer_send[2] = p1; @@ -686,7 +685,7 @@ namespace hw { bool device_ledger::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) { AUTO_LOCK_CMD(); - int offset, sw; + int offset; offset = set_command_header_noopt(INS_VERIFY_KEY); //sec @@ -782,7 +781,11 @@ namespace hw { const crypto::secret_key a_x = hw::ledger::decrypt(a); const crypto::secret_key b_x = hw::ledger::decrypt(b); crypto::secret_key r_x; + rct::key aG_x; + log_hexbuffer("sc_secret_add: [[IN]] a ", (char*)a_x.data, 32); + log_hexbuffer("sc_secret_add: [[IN]] b ", (char*)b_x.data, 32); this->controle_device->sc_secret_add(r_x, a_x, b_x); + log_hexbuffer("sc_secret_add: [[OUT]] aG", (char*)r_x.data, 32); #endif int offset = set_command_header_noopt(INS_SECRET_KEY_ADD); @@ -815,10 +818,13 @@ namespace hw { } #ifdef DEBUG_HWDEVICE - bool recover_x = recover; - const crypto::secret_key recovery_key_x = recovery_key; crypto::public_key pub_x; crypto::secret_key sec_x; + crypto::secret_key recovery_key_x; + if (recover) { + recovery_key_x = hw::ledger::decrypt(recovery_key); + log_hexbuffer("generate_keys: [[IN]] pub", (char*)recovery_key_x.data, 32); + } #endif send_simple(INS_GENERATE_KEYPAIR); @@ -830,6 +836,9 @@ namespace hw { #ifdef DEBUG_HWDEVICE crypto::secret_key sec_clear = hw::ledger::decrypt(sec); sec_x = sec_clear; + log_hexbuffer("generate_keys: [[OUT]] pub", (char*)pub.data, 32); + log_hexbuffer("generate_keys: [[OUT]] sec", (char*)sec_clear.data, 32); + crypto::secret_key_to_public_key(sec_x,pub_x); hw::ledger::check32("generate_keys", "pub", pub_x.data, pub.data); #endif @@ -844,7 +853,7 @@ namespace hw { #ifdef DEBUG_HWDEVICE const crypto::public_key pub_x = pub; - const crypto::secret_key sec_x = hw::ledger::decrypt(sec); + const crypto::secret_key sec_x = (sec == rct::rct2sk(rct::I)) ? sec: hw::ledger::decrypt(sec); crypto::key_derivation derivation_x; log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32); log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32); @@ -860,7 +869,6 @@ namespace hw { assert(is_fake_view_key(sec)); r = crypto::generate_key_derivation(pub, this->viewkey, derivation); } else { - int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION); //pub memmove(this->buffer_send+offset, pub.data, 32); @@ -879,11 +887,11 @@ namespace hw { } #ifdef DEBUG_HWDEVICE crypto::key_derivation derivation_clear ; - if ((this->mode == TRANSACTION_PARSE) && has_view_key) { - derivation_clear = derivation; - }else { - derivation_clear = hw::ledger::decrypt(derivation); - } + if ((this->mode == TRANSACTION_PARSE) && has_view_key) { + derivation_clear = derivation; + } else { + derivation_clear = hw::ledger::decrypt(derivation); + } hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data); #endif @@ -1044,7 +1052,7 @@ namespace hw { bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x); log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32); if (!rc){ - log_message("secret_key_to_public_key", "secret_key rejected"); + log_message("FAIL secret_key_to_public_key", "secret_key rejected"); } #endif @@ -1106,6 +1114,77 @@ namespace hw { /* TRANSACTION */ /* ======================================================================= */ + + + void device_ledger::generate_tx_proof(const crypto::hash &prefix_hash, + const crypto::public_key &R, const crypto::public_key &A, const boost::optional &B, const crypto::public_key &D, const crypto::secret_key &r, + crypto::signature &sig) { + + AUTO_LOCK_CMD(); + + #ifdef DEBUG_HWDEVICE + const crypto::hash prefix_hash_x = prefix_hash; + const crypto::public_key R_x = R; + const crypto::public_key A_x = A; + const boost::optional B_x = B; + const crypto::public_key D_x = D; + const crypto::secret_key r_x = hw::ledger::decrypt(r); + crypto::signature sig_x; + log_hexbuffer("generate_tx_proof: [[IN]] prefix_hash ", prefix_hash_x.data, 32); + log_hexbuffer("generate_tx_proof: [[IN]] R ", R_x.data, 32); + log_hexbuffer("generate_tx_proof: [[IN]] A ", A_x.data, 32); + if (B_x) { + log_hexbuffer("generate_tx_proof: [[IN]] B ", (*B_x).data, 32); + } + log_hexbuffer("generate_tx_proof: [[IN]] D ", D_x.data, 32); + log_hexbuffer("generate_tx_proof: [[IN]] r ", r_x.data, 32); + #endif + + + int offset = set_command_header(INS_GET_TX_PROOF); + //options + this->buffer_send[offset] = B?0x01:0x00; + offset += 1; + //prefix_hash + memmove(&this->buffer_send[offset], prefix_hash.data, 32); + offset += 32; + // R + memmove(&this->buffer_send[offset], R.data, 32); + offset += 32; + // A + memmove(&this->buffer_send[offset], A.data, 32); + offset += 32; + // B + if (B) { + memmove(&this->buffer_send[offset], (*B).data, 32); + } else { + memset(&this->buffer_send[offset], 0, 32); + } + offset += 32; + // D + memmove(&this->buffer_send[offset], D.data, 32); + offset += 32; + // r + memmove(&this->buffer_send[offset], r.data, 32); + offset += 32; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + + memmove(sig.c.data, &this->buffer_recv[0], 32); + memmove(sig.r.data, &this->buffer_recv[32], 32); + #ifdef DEBUG_HWDEVICE + log_hexbuffer("GENERATE_TX_PROOF: **c** ", sig.c.data, sizeof( sig.c.data)); + log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r.data, sizeof( sig.r.data)); + + this->controle_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x, &this->buffer_recv[64]); + hw::ledger::check32("generate_tx_proof", "c", sig_x.c.data, sig.c.data); + hw::ledger::check32("generate_tx_proof", "r", sig_x.r.data, sig.r.data); + + #endif + } + bool device_ledger::open_tx(crypto::secret_key &tx_key) { AUTO_LOCK_CMD(); @@ -1124,7 +1203,11 @@ namespace hw { this->exchange(); memmove(tx_key.data, &this->buffer_recv[32], 32); - + #ifdef DEBUG_HWDEVICE + const crypto::secret_key r_x = hw::ledger::decrypt(tx_key); + log_hexbuffer("open_tx: [[OUT]] R ", (char*)&this->buffer_recv[0], 32); + log_hexbuffer("open_tx: [[OUT]] r ", r_x.data, 32); + #endif return true; } @@ -1135,7 +1218,11 @@ namespace hw { const crypto::public_key public_key_x = public_key; const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key); crypto::hash8 payment_id_x = payment_id; + log_hexbuffer("encrypt_payment_id: [[IN]] payment_id ", payment_id_x.data, 32); + log_hexbuffer("encrypt_payment_id: [[IN]] public_key ", public_key_x.data, 32); + log_hexbuffer("encrypt_payment_id: [[IN]] secret_key ", secret_key_x.data, 32); this->controle_device->encrypt_payment_id(payment_id_x, public_key_x, secret_key_x); + log_hexbuffer("encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data, 32); #endif int offset = set_command_header_noopt(INS_STEALTH); @@ -1172,7 +1259,7 @@ namespace hw { #ifdef DEBUG_HWDEVICE const size_t &tx_version_x = tx_version; - const cryptonote::account_keys sender_account_keys_x = sender_account_keys; + const cryptonote::account_keys sender_account_keys_x = hw::ledger::decrypt(sender_account_keys); memmove((void*)sender_account_keys_x.m_view_secret_key.data, dbg_viewkey.data, 32); const crypto::public_key txkey_pub_x = txkey_pub; @@ -1190,8 +1277,30 @@ namespace hw { std::vector additional_tx_public_keys_x; std::vector amount_keys_x; crypto::public_key out_eph_public_key_x; + + log_message ("generate_output_ephemeral_keys: [[IN]] tx_version", std::to_string(tx_version_x)); + //log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.view", sender_account_keys.m_sview_secret_key.data, 32); + //log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.spend", sender_account_keys.m_spend_secret_key.data, 32); + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] txkey_pub", txkey_pub_x.data, 32); + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] tx_key", tx_key_x.data, 32); + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.view", dst_entr_x.addr.m_view_public_key.data, 32); + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.spend", dst_entr_x.addr.m_spend_public_key.data, 32); + if (change_addr) { + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.view", (*change_addr_x).m_view_public_key.data, 32); + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.spend", (*change_addr_x).m_spend_public_key.data, 32); + } + log_message ("generate_output_ephemeral_keys: [[IN]] output_index", std::to_string(output_index_x)); + log_message ("generate_output_ephemeral_keys: [[IN]] need_additional_txkeys", std::to_string(need_additional_txkeys_x)); + if(need_additional_txkeys_x) { + log_hexbuffer("generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[output_index].data, 32); + } this->controle_device->generate_output_ephemeral_keys(tx_version_x, sender_account_keys_x, txkey_pub_x, tx_key_x, dst_entr_x, change_addr_x, output_index_x, need_additional_txkeys_x, additional_tx_keys_x, additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x); + if(need_additional_txkeys_x) { + log_hexbuffer("additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data, 32); + } + log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] amount_keys ", (char*)amount_keys_x.back().bytes, 32); + log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] out_eph_public_key ", out_eph_public_key_x.data, 32); #endif @@ -1589,7 +1698,6 @@ namespace hw { bool device_ledger::mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &II) { AUTO_LOCK_CMD(); - unsigned char options; #ifdef DEBUG_HWDEVICE const rct::key H_x = H; @@ -1633,7 +1741,6 @@ namespace hw { bool device_ledger::mlsag_prepare(rct::key &a, rct::key &aG) { AUTO_LOCK_CMD(); - unsigned char options; #ifdef DEBUG_HWDEVICE rct::key a_x; @@ -1656,7 +1763,6 @@ namespace hw { bool device_ledger::mlsag_hash(const rct::keyV &long_message, rct::key &c) { AUTO_LOCK_CMD(); - unsigned char options; size_t cnt; #ifdef DEBUG_HWDEVICE diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 5bc617f8038..dc279330681 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -33,6 +33,8 @@ #include #include #include "device.hpp" +#include "log.hpp" + #include "device_io_hid.hpp" #include #include @@ -201,7 +203,10 @@ namespace hw { /* ======================================================================= */ /* TRANSACTION */ /* ======================================================================= */ - + void generate_tx_proof(const crypto::hash &prefix_hash, + const crypto::public_key &R, const crypto::public_key &A, const boost::optional &B, const crypto::public_key &D, const crypto::secret_key &r, + crypto::signature &sig) override; + bool open_tx(crypto::secret_key &tx_key) override; bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; diff --git a/src/device/log.hpp b/src/device/log.hpp index 25a214a6c6e..709d0ae8081 100644 --- a/src/device/log.hpp +++ b/src/device/log.hpp @@ -40,6 +40,19 @@ namespace hw { + /* Note about debug: + * To debug Device you can def the following : + * #define DEBUG_HWDEVICE + * Activate debug mechanism: + * - Add more trace + * - All computation done by device are checked by default device. + * Required IODUMMYCRYPT_HWDEVICE or IONOCRYPT_HWDEVICE for fully working + * #define IODUMMYCRYPT_HWDEVICE 1 + * - It assumes sensitive data encryption is is off on device side. a XOR with 0x55. This allow Ledger Class to make check on clear value + * #define IONOCRYPT_HWDEVICE 1 + * - It assumes sensitive data encryption is off on device side. + */ + void buffer_to_str(char *to_buff, size_t to_len, const char *buff, size_t len) ; void log_hexbuffer(const std::string &msg, const char* buff, size_t len); void log_message(const std::string &msg, const std::string &info ); diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 4a4754471cb..b61c704ef65 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -6213,11 +6213,6 @@ bool simple_wallet::set_tx_key(const std::vector &args_) //---------------------------------------------------------------------------------------------------- bool simple_wallet::get_tx_proof(const std::vector &args) { - if (m_wallet->key_on_device()) - { - fail_msg_writer() << tr("command not supported by HW wallet"); - return true; - } if (args.size() != 2 && args.size() != 3) { fail_msg_writer() << tr("usage: get_tx_proof
[]"); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 85dfbd9d772..49af15f6b6e 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -9570,8 +9570,9 @@ void wallet2::check_tx_key(const crypto::hash &txid, const crypto::secret_key &t std::vector additional_derivations; additional_derivations.resize(additional_tx_keys.size()); + hw::device &hwdev = m_account.get_device(); 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]), error::wallet_internal_error, + THROW_WALLET_EXCEPTION_IF(!hwdev.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); @@ -9667,6 +9668,8 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message) { + hw::device &hwdev = m_account.get_device(); + rct::key aP; // determine if the address is found in the subaddress hash table (i.e. whether the proof is outbound or inbound) const bool is_out = m_subaddresses.count(address.m_spend_public_key) == 0; @@ -9688,30 +9691,34 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac shared_secret.resize(num_sigs); sig.resize(num_sigs); - shared_secret[0] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_view_public_key), rct::sk2rct(tx_key))); + hwdev.scalarmultKey(aP, rct::pk2rct(address.m_view_public_key), rct::sk2rct(tx_key)); + shared_secret[0] = rct::rct2pk(aP); crypto::public_key tx_pub_key; if (is_subaddress) { - tx_pub_key = rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_spend_public_key), rct::sk2rct(tx_key))); - crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[0], tx_key, sig[0]); + hwdev.scalarmultKey(aP, rct::pk2rct(address.m_spend_public_key), rct::sk2rct(tx_key)); + tx_pub_key = rct2pk(aP); + hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[0], tx_key, sig[0]); } else { - crypto::secret_key_to_public_key(tx_key, tx_pub_key); - crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[0], tx_key, sig[0]); + hwdev.secret_key_to_public_key(tx_key, tx_pub_key); + hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[0], tx_key, sig[0]); } for (size_t i = 1; i < num_sigs; ++i) { - shared_secret[i] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_view_public_key), rct::sk2rct(additional_tx_keys[i - 1]))); + hwdev.scalarmultKey(aP, rct::pk2rct(address.m_view_public_key), rct::sk2rct(additional_tx_keys[i - 1])); + shared_secret[i] = rct::rct2pk(aP); if (is_subaddress) { - tx_pub_key = rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_spend_public_key), rct::sk2rct(additional_tx_keys[i - 1]))); - crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[i], additional_tx_keys[i - 1], sig[i]); + hwdev.scalarmultKey(aP, rct::pk2rct(address.m_spend_public_key), rct::sk2rct(additional_tx_keys[i - 1])); + tx_pub_key = rct2pk(aP); + hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[i], additional_tx_keys[i - 1], sig[i]); } else { - crypto::secret_key_to_public_key(additional_tx_keys[i - 1], tx_pub_key); - crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[i], additional_tx_keys[i - 1], sig[i]); + hwdev.secret_key_to_public_key(additional_tx_keys[i - 1], tx_pub_key); + hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[i], additional_tx_keys[i - 1], sig[i]); } } sig_str = std::string("OutProofV1"); @@ -9752,25 +9759,27 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac sig.resize(num_sigs); const crypto::secret_key& a = m_account.get_keys().m_view_secret_key; - shared_secret[0] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(tx_pub_key), rct::sk2rct(a))); + hwdev.scalarmultKey(aP, rct::pk2rct(tx_pub_key), rct::sk2rct(a)); + shared_secret[0] = rct2pk(aP); if (is_subaddress) { - crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, address.m_spend_public_key, shared_secret[0], a, sig[0]); + hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, address.m_spend_public_key, shared_secret[0], a, sig[0]); } else { - crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, shared_secret[0], a, sig[0]); + hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, shared_secret[0], a, sig[0]); } for (size_t i = 1; i < num_sigs; ++i) { - shared_secret[i] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(additional_tx_pub_keys[i - 1]), rct::sk2rct(a))); + hwdev.scalarmultKey(aP,rct::pk2rct(additional_tx_pub_keys[i - 1]), rct::sk2rct(a)); + shared_secret[i] = rct2pk(aP); if (is_subaddress) { - crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], address.m_spend_public_key, shared_secret[i], a, sig[i]); + hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], address.m_spend_public_key, shared_secret[i], a, sig[i]); } else { - crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], boost::none, shared_secret[i], a, sig[i]); + hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], boost::none, shared_secret[i], a, sig[i]); } } sig_str = std::string("InProofV1"); @@ -9779,10 +9788,10 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac // check if this address actually received any funds crypto::key_derivation derivation; - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(shared_secret[0], rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation"); + THROW_WALLET_EXCEPTION_IF(!hwdev.generate_key_derivation(shared_secret[0], rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation"); std::vector additional_derivations(num_sigs - 1); for (size_t i = 1; i < num_sigs; ++i) - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(shared_secret[i], rct::rct2sk(rct::I), additional_derivations[i - 1]), error::wallet_internal_error, "Failed to generate key derivation"); + THROW_WALLET_EXCEPTION_IF(!hwdev.generate_key_derivation(shared_secret[i], rct::rct2sk(rct::I), additional_derivations[i - 1]), error::wallet_internal_error, "Failed to generate key derivation"); uint64_t received; bool in_pool; uint64_t confirmations; @@ -9799,6 +9808,8 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac bool wallet2::check_tx_proof(const crypto::hash &txid, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message, const std::string &sig_str, uint64_t &received, bool &in_pool, uint64_t &confirmations) { + hw::device &hwdev = m_account.get_device(); + const bool is_out = sig_str.substr(0, 3) == "Out"; const std::string header = is_out ? "OutProofV1" : "InProofV1"; const size_t header_len = header.size(); @@ -9900,12 +9911,12 @@ bool wallet2::check_tx_proof(const crypto::hash &txid, const cryptonote::account // obtain key derivation by multiplying scalar 1 to the shared secret crypto::key_derivation derivation; if (good_signature[0]) - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(shared_secret[0], rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation"); + THROW_WALLET_EXCEPTION_IF(!hwdev.generate_key_derivation(shared_secret[0], rct::rct2sk(rct::I), derivation), error::wallet_internal_error, "Failed to generate key derivation"); std::vector additional_derivations(num_sigs - 1); for (size_t i = 1; i < num_sigs; ++i) if (good_signature[i]) - THROW_WALLET_EXCEPTION_IF(!crypto::generate_key_derivation(shared_secret[i], rct::rct2sk(rct::I), additional_derivations[i - 1]), error::wallet_internal_error, "Failed to generate key derivation"); + THROW_WALLET_EXCEPTION_IF(!hwdev.generate_key_derivation(shared_secret[i], rct::rct2sk(rct::I), additional_derivations[i - 1]), error::wallet_internal_error, "Failed to generate key derivation"); check_tx_key_helper(txid, derivation, additional_derivations, address, received, in_pool, confirmations); return true;