aboutsummaryrefslogtreecommitdiff
path: root/tests/unit_tests/multisig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit_tests/multisig.cpp')
-rw-r--r--tests/unit_tests/multisig.cpp88
1 files changed, 64 insertions, 24 deletions
diff --git a/tests/unit_tests/multisig.cpp b/tests/unit_tests/multisig.cpp
index 8f8ad52e1..3b3c4197c 100644
--- a/tests/unit_tests/multisig.cpp
+++ b/tests/unit_tests/multisig.cpp
@@ -96,8 +96,46 @@ static std::vector<std::string> exchange_round(std::vector<tools::wallet2>& wall
new_infos.reserve(infos.size());
for (size_t i = 0; i < wallets.size(); ++i)
+ new_infos.push_back(wallets[i].exchange_multisig_keys("", infos));
+
+ return new_infos;
+}
+
+static std::vector<std::string> exchange_round_force_update(std::vector<tools::wallet2>& wallets,
+ const std::vector<std::string>& infos,
+ const std::size_t round_in_progress)
+{
+ EXPECT_TRUE(wallets.size() == infos.size());
+ std::vector<std::string> new_infos;
+ std::vector<std::string> temp_force_update_infos;
+ new_infos.reserve(infos.size());
+
+ // when force-updating, we only need at most 'num_signers - 1 - (round - 1)' messages from other signers
+ size_t num_other_messages_required{wallets.size() - 1 - (round_in_progress - 1)};
+ if (num_other_messages_required > wallets.size())
+ num_other_messages_required = 0; //overflow case for post-kex verification round of 1-of-N
+
+ for (size_t i = 0; i < wallets.size(); ++i)
{
- new_infos.push_back(wallets[i].exchange_multisig_keys("", infos));
+ temp_force_update_infos.clear();
+ temp_force_update_infos.reserve(num_other_messages_required + 1);
+ temp_force_update_infos.push_back(infos[i]); //always include the local signer's message for this round
+
+ size_t infos_collected{0};
+ for (size_t wallet_index = 0; wallet_index < wallets.size(); ++wallet_index)
+ {
+ // skip the local signer's message
+ if (wallet_index == i)
+ continue;
+
+ temp_force_update_infos.push_back(infos[wallet_index]);
+ ++infos_collected;
+
+ if (infos_collected == num_other_messages_required)
+ break;
+ }
+
+ new_infos.push_back(wallets[i].exchange_multisig_keys("", temp_force_update_infos, true));
}
return new_infos;
@@ -105,7 +143,7 @@ static std::vector<std::string> exchange_round(std::vector<tools::wallet2>& wall
static void check_results(const std::vector<std::string> &intermediate_infos,
std::vector<tools::wallet2>& wallets,
- std::uint32_t M)
+ const std::uint32_t M)
{
// check results
std::unordered_set<crypto::secret_key> unique_privkeys;
@@ -167,8 +205,9 @@ static void check_results(const std::vector<std::string> &intermediate_infos,
wallets[0].encrypt_keys("");
}
-static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
+static void make_wallets(const unsigned int M, const unsigned int N, const bool force_update)
{
+ std::vector<tools::wallet2> wallets(N);
ASSERT_TRUE(wallets.size() > 1 && wallets.size() <= KEYS_COUNT);
ASSERT_TRUE(M <= wallets.size());
std::uint32_t total_rounds_required = multisig::multisig_setup_rounds_required(wallets.size(), M);
@@ -207,9 +246,12 @@ static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
wallets[0].multisig(&ready);
while (!ready)
{
- intermediate_infos = exchange_round(wallets, intermediate_infos);
- wallets[0].multisig(&ready);
+ if (force_update)
+ intermediate_infos = exchange_round_force_update(wallets, intermediate_infos, rounds_complete + 1);
+ else
+ intermediate_infos = exchange_round(wallets, intermediate_infos);
+ wallets[0].multisig(&ready);
++rounds_complete;
}
@@ -220,38 +262,38 @@ static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
TEST(multisig, make_1_2)
{
- std::vector<tools::wallet2> wallets(2);
- make_wallets(wallets, 1);
+ make_wallets(1, 2, false);
+ make_wallets(1, 2, true);
}
TEST(multisig, make_1_3)
{
- std::vector<tools::wallet2> wallets(3);
- make_wallets(wallets, 1);
+ make_wallets(1, 3, false);
+ make_wallets(1, 3, true);
}
TEST(multisig, make_2_2)
{
- std::vector<tools::wallet2> wallets(2);
- make_wallets(wallets, 2);
+ make_wallets(2, 2, false);
+ make_wallets(2, 2, true);
}
TEST(multisig, make_3_3)
{
- std::vector<tools::wallet2> wallets(3);
- make_wallets(wallets, 3);
+ make_wallets(3, 3, false);
+ make_wallets(3, 3, true);
}
TEST(multisig, make_2_3)
{
- std::vector<tools::wallet2> wallets(3);
- make_wallets(wallets, 2);
+ make_wallets(2, 3, false);
+ make_wallets(2, 3, true);
}
TEST(multisig, make_2_4)
{
- std::vector<tools::wallet2> wallets(4);
- make_wallets(wallets, 2);
+ make_wallets(2, 4, false);
+ make_wallets(2, 4, true);
}
TEST(multisig, multisig_kex_msg)
@@ -272,9 +314,7 @@ TEST(multisig, multisig_kex_msg)
signing_skey = rct::rct2sk(rct::skGen());
}
- crypto::secret_key ancillary_skey = rct::rct2sk(rct::skGen());
- while (ancillary_skey == crypto::null_skey)
- ancillary_skey = rct::rct2sk(rct::skGen());
+ const crypto::secret_key ancillary_skey{rct::rct2sk(rct::skGen())};
// misc. edge cases
EXPECT_NO_THROW((multisig_kex_msg{}));
@@ -312,8 +352,8 @@ TEST(multisig, multisig_kex_msg)
// test that keys can be recovered if stored in a message and the message's reverse
// round 1
- multisig_kex_msg msg_rnd1{1, signing_skey, std::vector<crypto::public_key>{pubkey1}, ancillary_skey};
- multisig_kex_msg msg_rnd1_reverse{msg_rnd1.get_msg()};
+ const multisig_kex_msg msg_rnd1{1, signing_skey, std::vector<crypto::public_key>{pubkey1}, ancillary_skey};
+ const multisig_kex_msg msg_rnd1_reverse{msg_rnd1.get_msg()};
EXPECT_EQ(msg_rnd1.get_round(), 1);
EXPECT_EQ(msg_rnd1.get_round(), msg_rnd1_reverse.get_round());
EXPECT_EQ(msg_rnd1.get_signing_pubkey(), signing_pubkey);
@@ -324,8 +364,8 @@ TEST(multisig, multisig_kex_msg)
EXPECT_EQ(msg_rnd1.get_msg_privkey(), msg_rnd1_reverse.get_msg_privkey());
// round 2
- multisig_kex_msg msg_rnd2{2, signing_skey, std::vector<crypto::public_key>{pubkey1, pubkey2}, ancillary_skey};
- multisig_kex_msg msg_rnd2_reverse{msg_rnd2.get_msg()};
+ const multisig_kex_msg msg_rnd2{2, signing_skey, std::vector<crypto::public_key>{pubkey1, pubkey2}, ancillary_skey};
+ const multisig_kex_msg msg_rnd2_reverse{msg_rnd2.get_msg()};
EXPECT_EQ(msg_rnd2.get_round(), 2);
EXPECT_EQ(msg_rnd2.get_round(), msg_rnd2_reverse.get_round());
EXPECT_EQ(msg_rnd2.get_signing_pubkey(), signing_pubkey);