diff options
Diffstat (limited to 'src/mnemonics/electrum-words.cpp')
-rw-r--r-- | src/mnemonics/electrum-words.cpp | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index 33d36d2d0..ef1100a10 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2016, The Monero Project +// Copyright (c) 2014-2017, The Monero Project // // All rights reserved. // @@ -51,25 +51,31 @@ #include <boost/crc.hpp> #include <boost/algorithm/string/join.hpp> +#include "chinese_simplified.h" #include "english.h" +#include "dutch.h" +#include "french.h" #include "italian.h" #include "german.h" #include "spanish.h" #include "portuguese.h" #include "japanese.h" #include "russian.h" -#include "old_english.h" +#include "english_old.h" #include "language_base.h" #include "singleton.h" namespace { + uint32_t create_checksum_index(const std::vector<std::string> &word_list, + uint32_t unique_prefix_length); + bool checksum_test(std::vector<std::string> seed, uint32_t unique_prefix_length); /*! * \brief Finds the word list that contains the seed words and puts the indices * where matches occured in matched_indices. * \param seed List of words to match. - * \param has_checksum If word list passed checksum test, we need to only do a prefix check. + * \param has_checksum The seed has a checksum word (maybe not checked). * \param matched_indices The indices where the seed words were found are added to this. * \param language Language instance pointer to write to after it is found. * \return true if all the words were present in some language false if not. @@ -79,15 +85,19 @@ namespace { // If there's a new language added, add an instance of it here. std::vector<Language::Base*> language_instances({ + Language::Singleton<Language::Chinese_Simplified>::instance(), Language::Singleton<Language::English>::instance(), + Language::Singleton<Language::Dutch>::instance(), + Language::Singleton<Language::French>::instance(), Language::Singleton<Language::Spanish>::instance(), Language::Singleton<Language::German>::instance(), Language::Singleton<Language::Italian>::instance(), Language::Singleton<Language::Portuguese>::instance(), Language::Singleton<Language::Japanese>::instance(), Language::Singleton<Language::Russian>::instance(), - Language::Singleton<Language::OldEnglish>::instance() + Language::Singleton<Language::EnglishOld>::instance() }); + Language::Base *fallback = NULL; // Iterate through all the languages and find a match for (std::vector<Language::Base*>::iterator it1 = language_instances.begin(); @@ -126,12 +136,33 @@ namespace } if (full_match) { + // if we were using prefix only, and we have a checksum, check it now + // to avoid false positives due to prefix set being too common + if (has_checksum) + if (!checksum_test(seed, (*it1)->get_unique_prefix_length())) + { + fallback = *it1; + full_match = false; + } + } + if (full_match) + { *language = *it1; return true; } // Some didn't match. Clear the index array. matched_indices.clear(); } + + // if we get there, we've not found a good match, but we might have a fallback, + // if we detected a match which did not fit the checksum, which might be a badly + // typed/transcribed seed in the right language + if (fallback) + { + *language = fallback; + return true; + } + return false; } @@ -211,7 +242,7 @@ namespace crypto std::vector<std::string> seed; boost::algorithm::trim(words); - boost::split(seed, words, boost::is_any_of(" ")); + boost::split(seed, words, boost::is_any_of(" "), boost::token_compress_on); // error on non-compliant word list if (seed.size() != seed_length/2 && seed.size() != seed_length && @@ -287,30 +318,42 @@ namespace crypto { language = Language::Singleton<Language::English>::instance(); } - else if (language_name == "Spanish") + else if (language_name == "Nederlands") + { + language = Language::Singleton<Language::Dutch>::instance(); + } + else if (language_name == "Français") + { + language = Language::Singleton<Language::French>::instance(); + } + else if (language_name == "Español") { language = Language::Singleton<Language::Spanish>::instance(); } - else if (language_name == "Portuguese") + else if (language_name == "Português") { language = Language::Singleton<Language::Portuguese>::instance(); } - else if (language_name == "Japanese") + else if (language_name == "日本語") { language = Language::Singleton<Language::Japanese>::instance(); } - else if (language_name == "Italian") + else if (language_name == "Italiano") { language = Language::Singleton<Language::Italian>::instance(); } - else if (language_name == "German") + else if (language_name == "Deutsch") { language = Language::Singleton<Language::German>::instance(); } - else if (language_name == "Russian") + else if (language_name == "русский язык") { language = Language::Singleton<Language::Russian>::instance(); } + else if (language_name == "简体中文 (中国)") + { + language = Language::Singleton<Language::Chinese_Simplified>::instance(); + } else { return false; @@ -356,13 +399,16 @@ namespace crypto void get_language_list(std::vector<std::string> &languages) { std::vector<Language::Base*> language_instances({ + Language::Singleton<Language::German>::instance(), Language::Singleton<Language::English>::instance(), Language::Singleton<Language::Spanish>::instance(), - Language::Singleton<Language::German>::instance(), + Language::Singleton<Language::French>::instance(), Language::Singleton<Language::Italian>::instance(), + Language::Singleton<Language::Dutch>::instance(), Language::Singleton<Language::Portuguese>::instance(), Language::Singleton<Language::Russian>::instance(), - Language::Singleton<Language::Japanese>::instance() + Language::Singleton<Language::Japanese>::instance(), + Language::Singleton<Language::Chinese_Simplified>::instance() }); for (std::vector<Language::Base*>::iterator it = language_instances.begin(); it != language_instances.end(); it++) |