From 3c0e87e1b604a846bf6a16c9eb5b45a05548541a Mon Sep 17 00:00:00 2001 From: Oran Juice Date: Fri, 26 Sep 2014 23:34:35 +0530 Subject: [PATCH] Supports wallet restoration --- src/mnemonics/electrum-words.cpp | 54 ++++++++++++++++++++++--------- src/simplewallet/simplewallet.cpp | 10 +++--- 2 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index 756306014..251503d9b 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -54,13 +54,15 @@ namespace const std::string LANGUAGES_DIRECTORY = "languages"; const std::string OLD_WORD_FILE = "old-word-list"; - bool is_first_use() + bool is_uninitialized() { return num_words == 0 ? true : false; } void create_data_structures(const std::string &word_file) { + words_array.clear(); + words_map.clear(); std::ifstream input_stream; input_stream.open(word_file.c_str(), std::ifstream::in); @@ -76,6 +78,18 @@ namespace } input_stream.close(); } + + bool word_list_file_match(const std::vector &wlist) + { + for (std::vector::const_iterator it = wlist.begin(); it != wlist.end(); it++) + { + if (words_map.count(*it) == 0) + { + return false; + } + } + return true; + } } namespace crypto @@ -93,6 +107,11 @@ namespace crypto { create_data_structures(WORD_LISTS_DIRECTORY + '/' + LANGUAGES_DIRECTORY + '/' + language); } + if (num_words == 0) + { + throw std::runtime_error(std::string("Word list file is corrupt: ") + + old_word_list ? OLD_WORD_FILE : (LANGUAGES_DIRECTORY + '/' + language)); + } } /* convert words to bytes, 3 words -> 4 bytes @@ -104,16 +123,29 @@ namespace crypto */ bool words_to_bytes(const std::string& words, crypto::secret_key& dst) { - if (is_first_use()) + std::vector wlist; + + boost::split(wlist, words, boost::is_any_of(" ")); + + std::vector languages; + + std::vector::iterator it; + get_language_list(languages); + for (it = languages.begin(); it != languages.end() && + !word_list_file_match(wlist); it++) + { + init(*it); + } + if (it == languages.end()) { init("", true); + if (!word_list_file_match(wlist)) + { + return false; + } } int n = num_words; - std::vector wlist; - - boost::split(wlist, words, boost::is_any_of(" ")); - // error on non-compliant word list if (wlist.size() != 12 && wlist.size() != 24) return false; @@ -122,14 +154,6 @@ namespace crypto uint32_t val; uint32_t w1, w2, w3; - // verify all three words exist in the word list - if (words_map.count(wlist[i*3]) == 0 || - words_map.count(wlist[i*3 + 1]) == 0 || - words_map.count(wlist[i*3 + 2]) == 0) - { - return false; - } - w1 = words_map.at(wlist[i*3]); w2 = words_map.at(wlist[i*3 + 1]); w3 = words_map.at(wlist[i*3 + 2]); @@ -159,7 +183,7 @@ namespace crypto */ bool bytes_to_words(const crypto::secret_key& src, std::string& words) { - if (is_first_use()) + if (is_uninitialized()) { init("", true); } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c9f4d6ec8..b368da01a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -489,11 +489,13 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas // convert rng value to electrum-style word list std::string electrum_words; - std::string mnemonic_language = get_mnemonic_language(); - std::cout << "(" << (mnemonic_language) << ")" << std::endl; - - crypto::ElectrumWords::init(mnemonic_language); + if (m_restore_deterministic_wallet) + { + // Ask for language only if it not a wallet restore. + std::string mnemonic_language = get_mnemonic_language(); + crypto::ElectrumWords::init(mnemonic_language); + } crypto::ElectrumWords::bytes_to_words(recovery_val, electrum_words); std::string print_electrum = "";