2018-12-27 18:50:45 +03:00
|
|
|
|
// Copyright (c) 2012-2013 The Cryptonote developers
|
|
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
2024-08-20 20:23:21 +05:00
|
|
|
|
#include <exception>
|
|
|
|
|
|
|
2018-12-27 18:50:45 +03:00
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "include_base_utils.h"
|
|
|
|
|
|
#include "currency_core/account.h"
|
2024-08-20 20:23:21 +05:00
|
|
|
|
#include "currency_core/currency_format_utils.h"
|
2018-12-27 18:50:45 +03:00
|
|
|
|
|
2020-06-30 00:46:38 +03:00
|
|
|
|
TEST(wallet_seed, store_restore_test)
|
2018-12-27 18:50:45 +03:00
|
|
|
|
{
|
|
|
|
|
|
for (size_t i = 0; i != 100; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
currency::account_base acc;
|
|
|
|
|
|
acc.generate();
|
2020-11-18 21:20:08 +01:00
|
|
|
|
auto seed_phrase = acc.get_seed_phrase("");
|
2018-12-27 18:50:45 +03:00
|
|
|
|
|
|
|
|
|
|
currency::account_base acc2;
|
2020-11-18 21:20:08 +01:00
|
|
|
|
bool r = acc2.restore_from_seed_phrase(seed_phrase, "");
|
2018-12-27 18:50:45 +03:00
|
|
|
|
ASSERT_TRUE(r);
|
|
|
|
|
|
|
|
|
|
|
|
if (memcmp(&acc2.get_keys(), &acc.get_keys(), sizeof(currency::account_keys)))
|
|
|
|
|
|
{
|
|
|
|
|
|
ASSERT_TRUE(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i != 100; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
currency::account_base acc;
|
|
|
|
|
|
acc.generate();
|
2020-11-18 21:20:08 +01:00
|
|
|
|
auto seed_phrase = acc.get_seed_phrase("");
|
2018-12-27 18:50:45 +03:00
|
|
|
|
|
|
|
|
|
|
currency::account_base acc2;
|
2020-11-18 21:20:08 +01:00
|
|
|
|
bool r = acc2.restore_from_seed_phrase(seed_phrase, "");
|
2018-12-27 18:50:45 +03:00
|
|
|
|
ASSERT_TRUE(r);
|
|
|
|
|
|
|
|
|
|
|
|
if (memcmp(&acc2.get_keys(), &acc.get_keys(), sizeof(currency::account_keys)))
|
|
|
|
|
|
{
|
|
|
|
|
|
ASSERT_TRUE(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2020-05-07 15:01:01 +03:00
|
|
|
|
|
|
|
|
|
|
struct wallet_seed_entry
|
|
|
|
|
|
{
|
|
|
|
|
|
std::string seed_phrase;
|
|
|
|
|
|
std::string spend_secret_key;
|
|
|
|
|
|
std::string view_secret_key;
|
|
|
|
|
|
uint64_t timestamp;
|
|
|
|
|
|
bool auditable;
|
|
|
|
|
|
bool valid;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
wallet_seed_entry wallet_seed_entries[] =
|
|
|
|
|
|
{
|
|
|
|
|
|
{
|
|
|
|
|
|
// legacy 24-word seed phrase -- invalid
|
2020-11-18 21:20:08 +01:00
|
|
|
|
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew god",
|
2020-05-07 15:01:01 +03:00
|
|
|
|
"",
|
|
|
|
|
|
"",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// old-style 25-word seed phrase -- valid
|
2020-11-18 21:20:08 +01:00
|
|
|
|
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew god",
|
2020-05-07 15:01:01 +03:00
|
|
|
|
"5e051454d7226b5734ebd64f754b57db4c655ecda00bd324f1b241d0b6381c0f",
|
|
|
|
|
|
"7dde5590fdf430568c00556ac2accf09da6cde9a29a4bc7d1cb6fd267130f006",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
true
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// old-style 25-word seed phrase -- valid
|
|
|
|
|
|
"conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation conversation",
|
|
|
|
|
|
"71162f207499bc16260957c36a6586bb931d54be33ff56b94d565dfedbb3c70e",
|
|
|
|
|
|
"8454372096986c457f4e7dceef2f39b6050c35d87b31d9c9eb8d37bf8f1f430f",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
true
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// old-style 25-word seed phrase -- invalid word
|
|
|
|
|
|
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew!",
|
|
|
|
|
|
"",
|
|
|
|
|
|
"",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// old-style 25-word seed phrase -- invalid word
|
|
|
|
|
|
"six six six six six six six six six sex six six six six six six six six six six six six six six six",
|
|
|
|
|
|
"",
|
|
|
|
|
|
"",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// new-style 26-word seed phrase -- invalid word
|
|
|
|
|
|
"six six six six six six six six six six six six six six six six six six six six six six six six six sex",
|
|
|
|
|
|
"",
|
|
|
|
|
|
"",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// new-style 26-word seed phrase -- invalid checksum
|
|
|
|
|
|
"six six six six six six six six six six six six six six six six six six six six six six six six six six",
|
|
|
|
|
|
"",
|
|
|
|
|
|
"",
|
|
|
|
|
|
0,
|
|
|
|
|
|
false,
|
|
|
|
|
|
false
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// new-style 26-word seed phrase - valid
|
|
|
|
|
|
"six six six six six six six six six six six six six six six six six six six six six six six six six frown",
|
|
|
|
|
|
"F54F61E3B974AD86171AE4944205C7BD0395BD7845899CDA8B1FBC5C947BB402",
|
|
|
|
|
|
"A18715058BBD914959C3A735B2022E9AE1D04452BC1FAD9E63C53668B7F57907",
|
|
|
|
|
|
1922832000,
|
|
|
|
|
|
false,
|
|
|
|
|
|
true
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
// new-style 26-word seed phrase auditable - valid
|
|
|
|
|
|
"six six six six six six six six six six six six six six six six six six six six six six six six six grace",
|
|
|
|
|
|
"F54F61E3B974AD86171AE4944205C7BD0395BD7845899CDA8B1FBC5C947BB402",
|
|
|
|
|
|
"A18715058BBD914959C3A735B2022E9AE1D04452BC1FAD9E63C53668B7F57907",
|
|
|
|
|
|
1922832000,
|
|
|
|
|
|
true,
|
|
|
|
|
|
true
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
TEST(wallet_seed, basic_test)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (size_t i = 0; i < sizeof wallet_seed_entries / sizeof wallet_seed_entries[0]; ++i)
|
|
|
|
|
|
{
|
|
|
|
|
|
const wallet_seed_entry& wse = wallet_seed_entries[i];
|
|
|
|
|
|
currency::account_base acc;
|
|
|
|
|
|
bool r = false;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2020-11-18 21:20:08 +01:00
|
|
|
|
r = acc.restore_from_seed_phrase(wse.seed_phrase, "");
|
2020-11-20 16:40:54 +01:00
|
|
|
|
if (r)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (size_t j = 0; j != 100; j++)
|
|
|
|
|
|
{
|
|
|
|
|
|
//generate random password
|
|
|
|
|
|
std::string pass = epee::string_tools::pod_to_hex(crypto::cn_fast_hash(&j, sizeof(j)));
|
2024-11-10 22:18:01 +01:00
|
|
|
|
pass.resize(std::min(j, (size_t)40));
|
|
|
|
|
|
|
2020-11-20 16:40:54 +01:00
|
|
|
|
//get secured seed
|
|
|
|
|
|
std::string secured_seed = acc.get_seed_phrase(pass);
|
|
|
|
|
|
|
2024-11-10 22:18:01 +01:00
|
|
|
|
currency::account_base acc2{};
|
|
|
|
|
|
if (!pass.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
//try to restore it without password(should fail)
|
|
|
|
|
|
bool r_fail = acc2.restore_from_seed_phrase(secured_seed, "");
|
|
|
|
|
|
ASSERT_EQ(r_fail, false);
|
|
|
|
|
|
}
|
2020-11-20 16:40:54 +01:00
|
|
|
|
|
|
|
|
|
|
//try to restore it with wrong password
|
|
|
|
|
|
bool r_fake_pass = acc2.restore_from_seed_phrase(secured_seed, "fake_password");
|
|
|
|
|
|
if (r_fake_pass)
|
|
|
|
|
|
{
|
|
|
|
|
|
//accidentally checksumm matched(quite possible)
|
|
|
|
|
|
ASSERT_EQ(false, acc2.get_keys() == acc.get_keys());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//try to restore it from right password
|
|
|
|
|
|
currency::account_base acc3;
|
|
|
|
|
|
bool r_true_res = acc3.restore_from_seed_phrase(secured_seed, pass);
|
|
|
|
|
|
ASSERT_EQ(true, r_true_res);
|
2024-11-10 22:18:01 +01:00
|
|
|
|
r = acc3.get_keys() == acc.get_keys();
|
|
|
|
|
|
ASSERT_TRUE(r);
|
2020-11-20 16:40:54 +01:00
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-07 15:01:01 +03:00
|
|
|
|
}
|
|
|
|
|
|
catch (...)
|
|
|
|
|
|
{
|
|
|
|
|
|
r = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
ASSERT_EQ(r, wse.valid);
|
|
|
|
|
|
|
|
|
|
|
|
if (r)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (wse.timestamp)
|
2022-05-11 21:02:06 +02:00
|
|
|
|
{
|
2020-05-07 15:01:01 +03:00
|
|
|
|
ASSERT_EQ(wse.timestamp, acc.get_createtime());
|
2022-05-11 21:02:06 +02:00
|
|
|
|
}
|
2020-05-07 15:01:01 +03:00
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(wse.auditable, acc.get_public_address().is_auditable());
|
|
|
|
|
|
|
|
|
|
|
|
// check keys
|
|
|
|
|
|
crypto::secret_key v, s;
|
|
|
|
|
|
ASSERT_TRUE(epee::string_tools::parse_tpod_from_hex_string(wse.spend_secret_key, s));
|
|
|
|
|
|
ASSERT_EQ(s, acc.get_keys().spend_secret_key);
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(epee::string_tools::parse_tpod_from_hex_string(wse.view_secret_key, v));
|
|
|
|
|
|
ASSERT_EQ(v, acc.get_keys().view_secret_key);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2024-08-20 20:23:21 +05:00
|
|
|
|
|
|
|
|
|
|
TEST(wallet_seed, word_from_timestamp)
|
|
|
|
|
|
{
|
|
|
|
|
|
//timestamp = 0; use_password = false
|
|
|
|
|
|
ASSERT_EQ("like", currency::get_word_from_timestamp(0, false));
|
|
|
|
|
|
|
|
|
|
|
|
// timestamp = 0; use_password = true
|
|
|
|
|
|
ASSERT_EQ("among", currency::get_word_from_timestamp(0, true));
|
|
|
|
|
|
|
|
|
|
|
|
// timestamp = WALLET_BRAIN_DATE_OFFSET = 1543622400; use_password = false
|
|
|
|
|
|
ASSERT_EQ("like", currency::get_word_from_timestamp(1543622400, false));
|
|
|
|
|
|
|
|
|
|
|
|
// timestamp = WALLET_BRAIN_DATE_OFFSET = 1543622400; use_password = true
|
|
|
|
|
|
ASSERT_EQ("among", currency::get_word_from_timestamp(1543622400, true));
|
|
|
|
|
|
|
|
|
|
|
|
// timestamp = WALLET_BRAIN_DATE_OFFSET - 1 = 1543622399; use_password = false
|
|
|
|
|
|
ASSERT_EQ("like", currency::get_word_from_timestamp(1543622399, false));
|
|
|
|
|
|
|
|
|
|
|
|
// timestamp = WALLET_BRAIN_DATE_OFFSET + 1 = 1543622401; use_password = false
|
|
|
|
|
|
ASSERT_EQ("like", currency::get_word_from_timestamp(1543622401, false));
|
|
|
|
|
|
|
|
|
|
|
|
// timestamp = WALLET_BRAIN_DATE_OFFSET + 1 = 1543622401; use_password = true
|
|
|
|
|
|
ASSERT_EQ("among", currency::get_word_from_timestamp(1543622401, true));
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
Values get_word_from_timestamp(1, true),
|
|
|
|
|
|
get_word_from_timestamp(1543622401, true) must be equal.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ("among", currency::get_word_from_timestamp(1, true));
|
|
|
|
|
|
ASSERT_EQ(currency::get_word_from_timestamp(1, true),
|
|
|
|
|
|
currency::get_word_from_timestamp(1543622401, true));
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
2027462399 is the largest timestamp argument value under which the
|
|
|
|
|
|
inequality weeks_count < WALLET_BRAIN_DATE_MAX_WEEKS_COUNT is satisfied.
|
|
|
|
|
|
|
|
|
|
|
|
timestamp = 2027462399
|
|
|
|
|
|
date_offset = timestamp - WALLET_BRAIN_DATE_OFFSET = 483839999
|
|
|
|
|
|
weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM = 799
|
|
|
|
|
|
WALLET_BRAIN_DATE_MAX_WEEKS_COUNT = 800
|
|
|
|
|
|
WALLET_BRAIN_DATE_QUANTUM = 604800
|
|
|
|
|
|
|
|
|
|
|
|
floor(483839999 / 604800) = 799
|
|
|
|
|
|
floor(483840000 / 604800) = 800
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// weeks_count_32 = 799; wordsArray[799] = "ugly"
|
|
|
|
|
|
ASSERT_EQ("ugly", currency::get_word_from_timestamp(2027462399, false));
|
|
|
|
|
|
|
|
|
|
|
|
// weeks_count_32 = 799 + 800 = 1599; wordsArray[1599] = "moan"
|
|
|
|
|
|
ASSERT_EQ("moan", currency::get_word_from_timestamp(2027462399, true));
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
If you pass values >= 2027462399 + 1, then the inequality
|
|
|
|
|
|
weeks_count < WALLET_BRAIN_DATE_MAX_WEEKS_COUNT is not satisfied. The
|
|
|
|
|
|
function throws an exception.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
EXPECT_THROW(currency::get_word_from_timestamp(2027462400, false),
|
|
|
|
|
|
std::runtime_error);
|
|
|
|
|
|
|
|
|
|
|
|
EXPECT_THROW(currency::get_word_from_timestamp(2027462400, true),
|
|
|
|
|
|
std::runtime_error);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(wallet_seed, timestamp_from_word)
|
|
|
|
|
|
{
|
|
|
|
|
|
{
|
|
|
|
|
|
// WALLET_BRAIN_DATE_OFFSET = 1543622400
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{false};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(1543622400,
|
|
|
|
|
|
currency::get_timestamp_from_word("like", password_used));
|
|
|
|
|
|
ASSERT_FALSE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{true};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(1543622400,
|
|
|
|
|
|
currency::get_timestamp_from_word("like", password_used));
|
|
|
|
|
|
ASSERT_FALSE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
// WALLET_BRAIN_DATE_OFFSET = 1543622400
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{true};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(1543622400,
|
|
|
|
|
|
currency::get_timestamp_from_word("among", password_used));
|
|
|
|
|
|
ASSERT_TRUE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{false};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(1543622400,
|
|
|
|
|
|
currency::get_timestamp_from_word("among", password_used));
|
|
|
|
|
|
ASSERT_TRUE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
// (1625 - 800) * 604800 + 1543622400 = 2042582400
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{false};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(2026857600,
|
|
|
|
|
|
currency::get_timestamp_from_word("ugly", password_used));
|
|
|
|
|
|
ASSERT_FALSE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{true};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(2026857600,
|
|
|
|
|
|
currency::get_timestamp_from_word("ugly", password_used));
|
|
|
|
|
|
ASSERT_FALSE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
// (1625 - 800) * 604800 + 1543622400 = 2042582400
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{false};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(2042582400,
|
|
|
|
|
|
currency::get_timestamp_from_word("weary", password_used));
|
|
|
|
|
|
ASSERT_TRUE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
bool password_used{true};
|
|
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(2042582400,
|
|
|
|
|
|
currency::get_timestamp_from_word("weary", password_used));
|
|
|
|
|
|
ASSERT_TRUE(password_used);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|