From 9acb635efd40fab35276734b40205bb6ee36e2b5 Mon Sep 17 00:00:00 2001 From: cslashm Date: Tue, 5 Mar 2019 02:10:28 +0100 Subject: [PATCH] Fix computation of change address + Fix v11 fork Always send TX public key when generating output destination keys: it may be an additional TX public key in case of subaddress; before we always use R. Fix the commitment mask generation: It must be delegated to device as it implies the amount key. Send MONERO_VERSION string in reset command to allow version compatibility check. Some enhancement of debug log. --- src/device/CMakeLists.txt | 1 + src/device/device.hpp | 2 ++ src/device/device_default.cpp | 4 +++ src/device/device_default.hpp | 2 ++ src/device/device_ledger.cpp | 66 +++++++++++++++++++++++++++++------ src/device/device_ledger.hpp | 2 ++ src/ringct/rctSigs.cpp | 8 ++--- 7 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index 8f446f42a..52538b9f7 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -79,5 +79,6 @@ target_link_libraries(device ringct_basic ${OPENSSL_CRYPTO_LIBRARIES} PRIVATE + version ${Blocks} ${EXTRA_LIBRARIES}) diff --git a/src/device/device.hpp b/src/device/device.hpp index c0cdcd753..3774d4e8a 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -189,6 +189,8 @@ namespace hw { return encrypt_payment_id(payment_id, public_key, secret_key); } + virtual rct::key genCommitmentMask(const rct::key &amount_key) = 0; + virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) = 0; virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) = 0; diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index c6cd7c06b..94bd8a75c 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -349,6 +349,10 @@ namespace hw { return true; } + rct::key device_default::genCommitmentMask(const rct::key &amount_key) { + return rct::genCommitmentMask(amount_key); + } + bool device_default::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) { rct::ecdhEncode(unmasked, sharedSec, short_amount); return true; diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index 04b9b4234..cac4b784c 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -111,6 +111,8 @@ namespace hw { bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; + rct::key genCommitmentMask(const rct::key &amount_key) override; + bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) override; bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) override; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index f73b1d5a7..8ead665a7 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -27,6 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // +#include "version.h" #include "device_ledger.hpp" #include "log.hpp" #include "ringct/rctOps.h" @@ -173,6 +174,7 @@ namespace hw { #define INS_SET_SIGNATURE_MODE 0x72 #define INS_GET_ADDITIONAL_KEY 0x74 #define INS_STEALTH 0x76 + #define INS_GEN_COMMITMENT_MASK 0x77 #define INS_BLIND 0x78 #define INS_UNBLIND 0x7A #define INS_GEN_TXOUT_KEYS 0x7B @@ -295,8 +297,14 @@ namespace hw { } bool device_ledger::reset() { - send_simple(INS_RESET); - return true; + reset_buffer(); + int offset = set_command_header_noopt(INS_RESET); + memmove(this->buffer_send+offset, MONERO_VERSION, strlen(MONERO_VERSION)); + offset += strlen(MONERO_VERSION); + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + return true; } unsigned int device_ledger::exchange(unsigned int ok, unsigned int mask) { @@ -307,9 +315,9 @@ namespace hw { this->length_recv -= 2; this->sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1]; + logRESP(); ASSERT_SW(this->sw,ok,msk); - logRESP(); return this->sw; } @@ -1157,13 +1165,18 @@ namespace hw { const cryptonote::account_keys sender_account_keys_x = 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; - const crypto::secret_key &tx_key_x = tx_key; - const cryptonote::tx_destination_entry &dst_entr_x = dst_entr; - 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 std::vector &additional_tx_keys_x = additional_tx_keys; + const crypto::public_key txkey_pub_x = txkey_pub; + const crypto::secret_key tx_key_x = hw::ledger::decrypt(tx_key); + const cryptonote::tx_destination_entry dst_entr_x = dst_entr; + 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; + + std::vector additional_tx_keys_x; + for (const auto k: additional_tx_keys) { + additional_tx_keys_x.push_back(hw::ledger::decrypt(k)); + } + std::vector additional_tx_public_keys_x; std::vector amount_keys_x; crypto::public_key out_eph_public_key_x; @@ -1207,6 +1220,9 @@ namespace hw { //tx_sec memmove(&this->buffer_send[offset], sec->data, 32); offset += 32; + //tx_pub + memmove(&this->buffer_send[offset], txkey_pub.data, 32); + offset += 32; //Aout memmove(&this->buffer_send[offset], dst_entr.addr.m_view_public_key.data, 32); offset += 32; @@ -1264,7 +1280,7 @@ namespace hw { #ifdef DEBUG_HWDEVICE hw::ledger::check32("generate_output_ephemeral_keys", "amount_key", (const char*)amount_keys_x.back().bytes, (const char*)hw::ledger::decrypt(amount_keys.back()).bytes); if (need_additional_txkeys) { - hw::ledger::check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_keys_x.back().data, additional_tx_keys.back().data); + hw::ledger::check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_public_keys_x.back().data, additional_tx_public_keys.back().data); } hw::ledger::check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data, out_eph_public_key.data); #endif @@ -1279,6 +1295,32 @@ namespace hw { return true; } + rct::key device_ledger::genCommitmentMask(const rct::key &AKout) { + #ifdef DEBUG_HWDEVICE + const rct::key AKout_x = hw::ledger::decrypt(AKout); + rct::key mask_x; + mask_x = this->controle_device->genCommitmentMask(AKout_x); + #endif + + rct::key mask; + int offset = set_command_header_noopt(INS_GEN_COMMITMENT_MASK); + // AKout + memmove(this->buffer_send+offset, AKout.bytes, 32); + offset += 32; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + + memmove(mask.bytes, &this->buffer_recv[0], 32); + + #ifdef DEBUG_HWDEVICE + hw::ledger::check32("genCommitmentMask", "mask", (const char*)mask_x.bytes, (const char*)mask.bytes); + #endif + + return mask; + } + bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout, bool short_amount) { AUTO_LOCK_CMD(); @@ -1310,6 +1352,7 @@ namespace hw { memmove(unmasked.mask.bytes, &this->buffer_recv[32], 32); #ifdef DEBUG_HWDEVICE + MDEBUG("ecdhEncode: Akout: "<buffer_recv[32], 32); #ifdef DEBUG_HWDEVICE + MDEBUG("ecdhEncode: Akout: "< &amounts, const std::vector &sk) + Bulletproof proveRangeBulletproof(keyV &C, keyV &masks, const std::vector &amounts, const std::vector &sk, hw::device &hwdev) { CHECK_AND_ASSERT_THROW_MES(amounts.size() == sk.size(), "Invalid amounts/sk sizes"); masks.resize(amounts.size()); for (size_t i = 0; i < masks.size(); ++i) - masks[i] = genCommitmentMask(sk[i]); + masks[i] = hwdev.genCommitmentMask(sk[i]); Bulletproof proof = bulletproof_PROVE(amounts, masks); CHECK_AND_ASSERT_THROW_MES(proof.V.size() == amounts.size(), "V does not have the expected size"); C = proof.V; @@ -757,7 +757,7 @@ namespace rct { { rct::keyV C, masks; const std::vector keys(amount_keys.begin(), amount_keys.end()); - rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts, keys)); + rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts, keys, hwdev)); #ifdef DBG CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof"); #endif @@ -780,7 +780,7 @@ namespace rct { std::vector keys(batch_size); for (size_t j = 0; j < batch_size; ++j) keys[j] = amount_keys[amounts_proved + j]; - rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts, keys)); + rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, batch_amounts, keys, hwdev)); #ifdef DBG CHECK_AND_ASSERT_THROW_MES(verBulletproof(rv.p.bulletproofs.back()), "verBulletproof failed on newly created proof"); #endif