aboutsummaryrefslogtreecommitdiff
path: root/src/mnemonics/electrum-words.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mnemonics/electrum-words.cpp')
-rw-r--r--src/mnemonics/electrum-words.cpp72
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++)