From 2290eff6d61db63b93d38d4fad15ab0524afd926 Mon Sep 17 00:00:00 2001 From: warptangent Date: Sat, 6 Dec 2014 01:46:41 -0800 Subject: [PATCH 1/5] replace lines with call to recently added print_seed() --- src/simplewallet/simplewallet.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index e1e2a198b..64b1e1da4 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -218,10 +218,7 @@ bool simple_wallet::seed(const std::vector &args/* = std::vector Date: Sat, 6 Dec 2014 01:47:54 -0800 Subject: [PATCH 2/5] indentation --- src/simplewallet/simplewallet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 64b1e1da4..ec51bd49d 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -222,7 +222,7 @@ bool simple_wallet::seed(const std::vector &args/* = std::vector Date: Sat, 6 Dec 2014 01:59:13 -0800 Subject: [PATCH 3/5] Extract check for deterministic keys to wallet2::is_deterministic() It's cleaner for wallet2.cpp and it also allows deterministic check by simplewallet.cpp. --- src/wallet/wallet2.cpp | 22 ++++++++++++++++------ src/wallet/wallet2.h | 4 ++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 066b006b4..58b715f20 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -89,8 +89,23 @@ void wallet2::init(const std::string& daemon_address, uint64_t upper_transaction m_daemon_address = daemon_address; } //---------------------------------------------------------------------------------------------------- +bool wallet2::is_deterministic() +{ + crypto::secret_key second; + keccak((uint8_t *)&get_account().get_keys().m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key)); + sc_reduce32((uint8_t *)&second); + bool keys_deterministic = memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0; + return keys_deterministic; +} +//---------------------------------------------------------------------------------------------------- bool wallet2::get_seed(std::string& electrum_words) { + bool keys_deterministic = is_deterministic(); + if (!keys_deterministic) + { + std::cout << "This is not a deterministic wallet" << std::endl; + return false; + } if (seed_language.empty()) { std::cout << "seed_language not set" << std::endl; @@ -99,12 +114,7 @@ bool wallet2::get_seed(std::string& electrum_words) crypto::ElectrumWords::bytes_to_words(get_account().get_keys().m_spend_secret_key, electrum_words, seed_language); - crypto::secret_key second; - keccak((uint8_t *)&get_account().get_keys().m_spend_secret_key, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key)); - - sc_reduce32((uint8_t *)&second); - - return memcmp(second.data,get_account().get_keys().m_view_secret_key.data, sizeof(crypto::secret_key)) == 0; + return true; } /*! * \brief Gets the seed language diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index bcd7ce6f7..f22c5d79d 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -168,6 +168,10 @@ namespace tools i_wallet2_callback* callback() const { return m_callback; } void callback(i_wallet2_callback* callback) { m_callback = callback; } + /*! + * \brief Checks if deterministic wallet + */ + bool is_deterministic(); bool get_seed(std::string& electrum_words); /*! * \brief Gets the seed language From 4c6230d6cfc9c147202b634ee7ebbacaebb9901c Mon Sep 17 00:00:00 2001 From: warptangent Date: Sat, 6 Dec 2014 01:48:33 -0800 Subject: [PATCH 4/5] Checking and handling for deterministic vs non-deterministic wallet simple_wallet::seed() - Check that wallet is deterministic. simple_wallet::new_wallet() - Prompt for seed language only if it's a non-deterministic wallet, along with previous conditions. simple_wallet::open_wallet() - Fixed check for deterministic wallet (flag based on command line non-deterministic argument was used before, but it's inapplicable to opening an existing wallet). - As with deterministic wallet, non-deterministic also included to be rewritten to new JSON format file. That's what's done for newly generated non-deterministic wallets, so old versions should be updated to same format. --- src/simplewallet/simplewallet.cpp | 52 ++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index ec51bd49d..4f7df2d3a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -206,16 +206,20 @@ bool simple_wallet::viewkey(const std::vector &args/* = std::vector bool simple_wallet::seed(const std::vector &args/* = std::vector()*/) { + bool success = false; std::string electrum_words; - if (m_wallet->get_seed_language().empty()) + if (m_wallet->is_deterministic()) { - std::string mnemonic_language = get_mnemonic_language(); - m_wallet->set_seed_language(mnemonic_language); + if (m_wallet->get_seed_language().empty()) + { + std::string mnemonic_language = get_mnemonic_language(); + m_wallet->set_seed_language(mnemonic_language); + } + + success = m_wallet->get_seed(electrum_words); } - bool success = m_wallet->get_seed(electrum_words); - if (success) { print_seed(electrum_words); @@ -508,9 +512,11 @@ bool simple_wallet::new_wallet(const std::string &wallet_file, const std::string crypto::ElectrumWords::get_is_old_style_seed(m_electrum_seed)); std::string mnemonic_language = old_language; - // Ask for seed language if it is not a wallet restore or if it was a deprecated wallet - // that was earlier used before this restore. - if (!m_restore_deterministic_wallet || was_deprecated_wallet) + // Ask for seed language if: + // it's a deterministic wallet AND + // (it is not a wallet restore OR if it was a deprecated wallet + // that was earlier used before this restore) + if ((!two_random) && (!m_restore_deterministic_wallet || was_deprecated_wallet)) { if (was_deprecated_wallet) { @@ -580,18 +586,28 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa << m_wallet->get_account().get_public_address_str(m_wallet->testnet()); // If the wallet file is deprecated, we should ask for mnemonic language again and store // everything in the new format. - if (!m_non_deterministic && m_wallet->is_deprecated()) + // NOTE: this is_deprecated() refers to the wallet file format before becoming JSON. It does not refer to the "old english" seed words form of "deprecated" used elsewhere. + if (m_wallet->is_deprecated()) { - message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << - "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"; - std::string mnemonic_language = get_mnemonic_language(); - m_wallet->set_seed_language(mnemonic_language); - m_wallet->rewrite(m_wallet_file, password); + if (m_wallet->is_deterministic()) + { + message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << + "a deprecated version of the wallet. Please proceed to upgrade your wallet.\n"; + std::string mnemonic_language = get_mnemonic_language(); + m_wallet->set_seed_language(mnemonic_language); + m_wallet->rewrite(m_wallet_file, password); - // Display the seed - std::string seed; - m_wallet->get_seed(seed); - print_seed(seed); + // Display the seed + std::string seed; + m_wallet->get_seed(seed); + print_seed(seed); + } + else + { + message_writer(epee::log_space::console_color_green, false) << "\nYou had been using " << + "a deprecated version of the wallet. Your wallet file format is being upgraded now.\n"; + m_wallet->rewrite(m_wallet_file, password); + } } } catch (const std::exception& e) From f9822c483ead4c392fdf1f1317af31a1bfa9e228 Mon Sep 17 00:00:00 2001 From: warptangent Date: Sat, 6 Dec 2014 03:09:46 -0800 Subject: [PATCH 5/5] wallet JSON update for non-deterministic wallet data wallet2::store_keys() and wallet2::load_keys() should only use the JSON attribute "seed_language" when applicable. That is only for deterministic wallets. - store_keys() don't add JSON attribute "seed_language" if seed_language is empty - load_keys() don't call set_seed_language if JSON attribute "seed_language" not present --- src/wallet/wallet2.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 58b715f20..163e19df4 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -486,8 +486,11 @@ bool wallet2::store_keys(const std::string& keys_file_name, const std::string& p rapidjson::Value value(rapidjson::kStringType); value.SetString(account_data.c_str(), account_data.length()); json.AddMember("key_data", value, json.GetAllocator()); - value.SetString(seed_language.c_str(), seed_language.length()); - json.AddMember("seed_language", value, json.GetAllocator()); + if (!seed_language.empty()) + { + value.SetString(seed_language.c_str(), seed_language.length()); + json.AddMember("seed_language", value, json.GetAllocator()); + } // Serialize the JSON object rapidjson::StringBuffer buffer; @@ -553,8 +556,11 @@ void wallet2::load_keys(const std::string& keys_file_name, const std::string& pa { account_data = std::string(json["key_data"].GetString(), json["key_data"].GetString() + json["key_data"].GetStringLength()); - set_seed_language(std::string(json["seed_language"].GetString(), json["seed_language"].GetString() + - json["seed_language"].GetStringLength())); + if (json.HasMember("seed_language")) + { + set_seed_language(std::string(json["seed_language"].GetString(), json["seed_language"].GetString() + + json["seed_language"].GetStringLength())); + } } const cryptonote::account_keys& keys = m_account.get_keys();