From ea87b30f8907ee11252433811e7a7d0c46758cca Mon Sep 17 00:00:00 2001 From: j-berman Date: Mon, 15 Nov 2021 05:23:53 -0800 Subject: Add view tags to outputs to reduce wallet scanning time Implements view tags as proposed by @UkoeHB in MRL issue https://github.com/monero-project/research-lab/issues/73 At tx construction, the sender adds a 1-byte view tag to each output. The view tag is derived from the sender-receiver shared secret. When scanning for outputs, the receiver can check the view tag for a match, in order to reduce scanning time. When the view tag does not match, the wallet avoids the more expensive EC operations when deriving the output public key using the shared secret. --- src/device/device.hpp | 3 ++- src/device/device_default.cpp | 14 +++++++++++++- src/device/device_default.hpp | 4 +++- src/device/device_ledger.cpp | 7 +++++-- src/device/device_ledger.hpp | 3 ++- 5 files changed, 25 insertions(+), 6 deletions(-) (limited to 'src/device') diff --git a/src/device/device.hpp b/src/device/device.hpp index ba47115e7..eca91006f 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -222,7 +222,8 @@ namespace hw { const bool &need_additional_txkeys, const std::vector &additional_tx_keys, std::vector &additional_tx_public_keys, std::vector &amount_keys, - crypto::public_key &out_eph_public_key) = 0; + crypto::public_key &out_eph_public_key, + const bool use_view_tags, crypto::view_tag &view_tag) = 0; virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0; virtual bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) = 0; diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index e7b452d40..d70ece229 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -263,6 +263,11 @@ namespace hw { return true; } + bool device_default::derive_view_tag(const crypto::key_derivation &derivation, const std::size_t output_index, crypto::view_tag &view_tag) { + crypto::derive_view_tag(derivation, output_index, view_tag); + return true; + } + bool device_default::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector &additional_derivations){ return true; } @@ -291,7 +296,8 @@ namespace hw { const cryptonote::tx_destination_entry &dst_entr, const boost::optional &change_addr, const size_t output_index, const bool &need_additional_txkeys, const std::vector &additional_tx_keys, std::vector &additional_tx_public_keys, - std::vector &amount_keys, crypto::public_key &out_eph_public_key) { + std::vector &amount_keys, crypto::public_key &out_eph_public_key, + const bool use_view_tags, crypto::view_tag &view_tag) { crypto::key_derivation derivation; @@ -331,6 +337,12 @@ namespace hw { derivation_to_scalar(derivation, output_index, scalar1); amount_keys.push_back(rct::sk2rct(scalar1)); } + + if (use_view_tags) + { + derive_view_tag(derivation, output_index, view_tag); + } + r = 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 << ")"); diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index 60d2ba203..7d3543652 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -101,6 +101,7 @@ namespace hw { 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; bool secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) override; bool generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image) override; + bool derive_view_tag(const crypto::key_derivation &derivation, const std::size_t output_index, crypto::view_tag &view_tag); /* ======================================================================= */ @@ -126,7 +127,8 @@ namespace hw { const bool &need_additional_txkeys, const std::vector &additional_tx_keys, std::vector &additional_tx_public_keys, std::vector &amount_keys, - crypto::public_key &out_eph_public_key) override; + crypto::public_key &out_eph_public_key, + bool use_view_tags, crypto::view_tag &view_tag) override; bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override; bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 378d9f533..84c81bfcd 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -1527,7 +1527,8 @@ namespace hw { const bool &need_additional_txkeys, const std::vector &additional_tx_keys, std::vector &additional_tx_public_keys, std::vector &amount_keys, - crypto::public_key &out_eph_public_key) { + crypto::public_key &out_eph_public_key, + bool use_view_tags, crypto::view_tag &view_tag) { AUTO_LOCK_CMD(); #ifdef DEBUG_HWDEVICE @@ -1541,6 +1542,8 @@ namespace hw { const boost::optional change_addr_x = change_addr; const size_t output_index_x = output_index; const bool need_additional_txkeys_x = need_additional_txkeys; + const bool use_view_tags_x = use_view_tags; + const crypto::view_tag view_tag_x = view_tag; std::vector additional_tx_keys_x; for (const auto &k: additional_tx_keys) { @@ -1568,7 +1571,7 @@ namespace hw { 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); + additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x, use_view_tags_x, view_tag_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); } diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 06521a56f..074bfaa8d 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -273,7 +273,8 @@ namespace hw { const bool &need_additional_txkeys, const std::vector &additional_tx_keys, std::vector &additional_tx_public_keys, std::vector &amount_keys, - crypto::public_key &out_eph_public_key) override; + crypto::public_key &out_eph_public_key, + const bool use_view_tags, crypto::view_tag &view_tag) override; bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override; bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override; -- cgit v1.2.3