Skip to content

Commit

Permalink
Implement ElectrumWords::get_invalid_word
Browse files Browse the repository at this point in the history
  • Loading branch information
b4n6-b4n6 committed Aug 31, 2024
1 parent a1dc85c commit 08b7fe4
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 1 deletion.
53 changes: 53 additions & 0 deletions src/mnemonics/electrum-words.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,59 @@ namespace crypto
return true;
}

std::string get_invalid_word(const epee::wipeable_string &words)
{
// 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::Esperanto>::instance(),
Language::Singleton<Language::Lojban>::instance(),
Language::Singleton<Language::EnglishOld>::instance()
});

std::vector<epee::wipeable_string> seed;
words.split(seed);

for (
std::vector<epee::wipeable_string>::const_iterator seed_i = seed.begin();
seed_i != seed.end();
seed_i++
)
{
bool has_any = false;

for (
std::vector<Language::Base*>::iterator lang_i = language_instances.begin();
lang_i != language_instances.end() && !has_any;
lang_i++
)
{
auto &word_map = (*lang_i)->get_word_map();

if (word_map.count(*seed_i) != 0)
{
has_any = true;
break;
}
}

if (!has_any) {
return std::string(seed_i->data(), seed_i->size());
}
}

return "";
}

/*!
* \brief Converts bytes (secret key) to seed words.
* \param src Secret key
Expand Down
2 changes: 2 additions & 0 deletions src/mnemonics/electrum-words.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ namespace crypto
bool words_to_bytes(const epee::wipeable_string &words, crypto::secret_key& dst,
std::string &language_name);

std::string get_invalid_word(const epee::wipeable_string &words);

/*!
* \brief Converts bytes to seed words.
* \param src Secret data
Expand Down
7 changes: 6 additions & 1 deletion src/wallet/api/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,12 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c
crypto::secret_key recovery_key;
std::string old_language;
if (!crypto::ElectrumWords::words_to_bytes(seed, recovery_key, old_language)) {
setStatusError(tr("Electrum-style word list failed verification"));
std::string invalid_word = crypto::ElectrumWords::get_invalid_word(seed);
if (invalid_word != "") {
setStatusError((boost::format(tr("Invalid word %s")) % ("'" + invalid_word + "'")).str());
} else {
setStatusError(tr("Electrum-style word list failed verification"));
}
return false;
}
if (!seed_offset.empty())
Expand Down
51 changes: 51 additions & 0 deletions tests/unit_tests/mnemonics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,3 +255,54 @@ TEST(mnemonics, partial_word_tolerance)
ASSERT_EQ(true, res);
ASSERT_STREQ(language_name_1.c_str(), "English");
}

TEST(mnemonics, get_invalid_word)
{
ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"crim bam scamp gna limi woma wron tuit birth mundane donuts square cohesive dolphin titans narrate fue saved wrap aloof magic mirr toget upda wra"
) == "crim"
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"criminal bamboo scamper gnaw limits womanly wrong tuition birth mundane donuts square cohesive dolphin titans narrate fue saved wrap aloof magically mirror together update wrap"
) == "fue"
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"a a a a a a a a a a a a a a a a a a a a a a a a a"
) == "a"
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandonnn abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"
) == "abandonnn"
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"abando abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandonnn abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"
) == "abando"
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"criminal bamboo scamper gnaw limits womanly wrong tuition birth mundane donuts square cohesive dolphin titans narrate fuel saved wrap aloof magically mirror together update wrap"
) == ""
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon"
) == ""
);

ASSERT_TRUE(
crypto::ElectrumWords::get_invalid_word(
""
) == ""
);
}

0 comments on commit 08b7fe4

Please sign in to comment.