aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcslashm <cslashm@gmail.com>2018-04-09 16:07:11 +0200
committercslashm <cslashm@gmail.com>2018-04-09 16:53:13 +0200
commitd481410bff5c2a189d303ce81ec7e94cc470cc3d (patch)
tree055459bf1390d2d777c0bf6f288487301a649762
parentMerge pull request #3512 (diff)
downloadmonero-d481410bff5c2a189d303ce81ec7e94cc470cc3d.tar.xz
Fix sub-address tx scan.
When additional keys was needed, the TX scan failed because the derivation data was always recomputed with the main tx_key and not the corresponding additional one. Moreover this patch avoid perf decreasing when not using HW device.
-rw-r--r--src/device/device.hpp1
-rw-r--r--src/device/device_default.cpp4
-rw-r--r--src/device/device_default.hpp1
-rw-r--r--src/device/device_ledger.cpp23
-rw-r--r--src/device/device_ledger.hpp1
-rw-r--r--src/wallet/wallet2.cpp6
6 files changed, 33 insertions, 3 deletions
diff --git a/src/device/device.hpp b/src/device/device.hpp
index db489ff0c..9df0cb39d 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -145,6 +145,7 @@ namespace hw {
virtual bool sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) = 0;
virtual crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) = 0;
virtual bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) = 0;
+ virtual bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) = 0;
virtual bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) = 0;
virtual bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) = 0;
virtual bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) = 0;
diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp
index 56bd1e164..0071f7d4f 100644
--- a/src/device/device_default.cpp
+++ b/src/device/device_default.cpp
@@ -264,6 +264,10 @@ namespace hw {
return true;
}
+ bool device_default::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations){
+ return true;
+ }
+
/* ======================================================================= */
/* TRANSACTION */
/* ======================================================================= */
diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp
index 53942f53a..649fed862 100644
--- a/src/device/device_default.hpp
+++ b/src/device/device_default.hpp
@@ -93,6 +93,7 @@ namespace hw {
bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override;
crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override;
bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override;
+ bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations);
bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override;
bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override;
bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override;
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index ee1497438..3b9ab6744 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -56,6 +56,7 @@ namespace hw {
#define ASSERT_RV(rv) CHECK_AND_ASSERT_THROW_MES((rv)==SCARD_S_SUCCESS, "Fail SCard API : (" << (rv) << ") "<< pcsc_stringify_error(rv)<<" Device="<<this->id<<", hCard="<<hCard<<", hContext="<<hContext);
#define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), "Wrong Device Status : SW=" << std::hex << (sw) << " (EXPECT=" << std::hex << (ok) << ", MASK=" << std::hex << (mask) << ")") ;
#define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ;
+ #define ASSERT_X(exp,msg) CHECK_AND_ASSERT_THROW_MES(exp, msg);
#ifdef DEBUG_HWDEVICE
crypto::secret_key dbg_viewkey;
@@ -125,6 +126,10 @@ namespace hw {
return sec == crypto::null_skey;
}
+ bool operator==(const crypto::key_derivation &d0, const crypto::key_derivation &d1) {
+ return !memcmp(&d0, &d1, sizeof(d0));
+ }
+
/* ===================================================================== */
/* === Device ==== */
/* ===================================================================== */
@@ -1094,6 +1099,24 @@ namespace hw {
return r;
}
+ bool device_ledger::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) {
+ const crypto::public_key *pkey=NULL;
+ if (derivation == main_derivation) {
+ pkey = &tx_pub_key;
+ MDEBUG("conceal derivation with main tx pub key");
+ } else {
+ for(size_t n=0; n < additional_derivations.size();++n) {
+ if(derivation == additional_derivations[n]) {
+ pkey = &additional_tx_pub_keys[n];
+ MDEBUG("conceal derivation with additionnal tx pub key");
+ break;
+ }
+ }
+ }
+ ASSERT_X(pkey, "Mismatched derivation on scan info");
+ return this->generate_key_derivation(*pkey, crypto::null_skey, derivation);
+ }
+
bool device_ledger::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) {
AUTO_LOCK_CMD();
int offset;
diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp
index 652cfb34b..9f73bd070 100644
--- a/src/device/device_ledger.hpp
+++ b/src/device/device_ledger.hpp
@@ -169,6 +169,7 @@ namespace hw {
bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override;
crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override;
bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override;
+ bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations);
bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override;
bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override;
bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index b06444132..b5ae1b53e 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1181,7 +1181,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
if (tx_scan_info[i].received)
{
- hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation);
+ hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations);
scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs);
}
}
@@ -1204,7 +1204,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
if (tx_scan_info[i].received)
{
- hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation);
+ hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations);
scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs);
}
}
@@ -1220,7 +1220,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
{
hwdev_lock.lock();
hwdev.set_mode(hw::device::NONE);
- hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, tx_scan_info[i].received->derivation);
+ hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations);
scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs);
hwdev_lock.unlock();
}