Merge pull request #8220

0d6ecb1 multisig: add post-kex verification round to check that all participants have completed the multisig address (koe)
This commit is contained in:
luigi1111 2022-05-10 16:41:02 -05:00
commit c1625a8928
No known key found for this signature in database
GPG key ID: F4ACA0183641E010
9 changed files with 336 additions and 194 deletions

View file

@ -81,9 +81,7 @@ static bool make_multisig_accounts(std::vector<cryptonote::account_base> &accoun
for (std::size_t account_index{0}; account_index < accounts.size(); ++account_index)
{
multisig_accounts[account_index].initialize_kex(threshold, signers, round_msgs);
if (!multisig_accounts[account_index].multisig_is_ready())
temp_round_msgs[account_index] = multisig_accounts[account_index].get_next_kex_round_msg();
temp_round_msgs[account_index] = multisig_accounts[account_index].get_next_kex_round_msg();
}
// perform key exchange rounds
@ -94,9 +92,7 @@ static bool make_multisig_accounts(std::vector<cryptonote::account_base> &accoun
for (std::size_t account_index{0}; account_index < multisig_accounts.size(); ++account_index)
{
multisig_accounts[account_index].kex_update(round_msgs);
if (!multisig_accounts[account_index].multisig_is_ready())
temp_round_msgs[account_index] = multisig_accounts[account_index].get_next_kex_round_msg();
temp_round_msgs[account_index] = multisig_accounts[account_index].get_next_kex_round_msg();
}
}

View file

@ -125,17 +125,18 @@ class MultisigTest():
for i in range(N_total):
res = self.wallet[i].is_multisig()
assert res.multisig == True
assert res.ready == (M_threshold == N_total)
assert not res.ready
assert res.threshold == M_threshold
assert res.total == N_total
while True:
n_empty = 0
for i in range(len(next_stage)):
if len(next_stage[i]) == 0:
n_empty += 1
assert n_empty == 0 or n_empty == len(next_stage)
if n_empty == len(next_stage):
n_ready = 0
for i in range(N_total):
res = self.wallet[i].is_multisig()
if res.ready == True:
n_ready += 1
assert n_ready == 0 or n_ready == N_total
if n_ready == N_total:
break
info = next_stage
next_stage = []
@ -162,54 +163,72 @@ class MultisigTest():
'peeled mixture ionic radar utopia puddle buying illness nuns gadget river spout cavernous bounced paradise drunk looking cottage jump tequila melting went winter adjust spout',
'dilute gutter certain antics pamphlet macro enjoy left slid guarded bogeys upload nineteen bomb jubilee enhanced irritate turnip eggs swung jukebox loudly reduce sedan slid',
]
info = []
wallet = [None, None, None]
for i in range(3):
wallet[i] = Wallet(idx = i)
try: wallet[i].close_wallet()
info2of2 = []
wallet2of2 = [None, None]
for i in range(2):
wallet2of2[i] = Wallet(idx = i)
try: wallet2of2[i].close_wallet()
except: pass
res = wallet[i].restore_deterministic_wallet(seed = seeds[i])
res = wallet[i].is_multisig()
res = wallet2of2[i].restore_deterministic_wallet(seed = seeds[i])
res = wallet2of2[i].is_multisig()
assert not res.multisig
res = wallet[i].prepare_multisig()
res = wallet2of2[i].prepare_multisig()
assert len(res.multisig_info) > 0
info.append(res.multisig_info)
info2of2.append(res.multisig_info)
for i in range(3):
ok = False
try: res = wallet[i].exchange_multisig_keys(info)
except: ok = True
assert ok
res = wallet[i].is_multisig()
assert not res.multisig
res = wallet[0].make_multisig(info[0:2], 2)
res = wallet[0].is_multisig()
kex_info = []
res = wallet2of2[0].make_multisig(info2of2, 2)
kex_info.append(res.multisig_info)
res = wallet2of2[1].make_multisig(info2of2, 2)
kex_info.append(res.multisig_info)
res = wallet2of2[0].exchange_multisig_keys(kex_info)
res = wallet2of2[0].is_multisig()
assert res.multisig
assert res.ready
ok = False
try: res = wallet[0].prepare_multisig()
try: res = wallet2of2[0].prepare_multisig()
except: ok = True
assert ok
ok = False
try: res = wallet[0].make_multisig(info[0:2], 2)
try: res = wallet2of2[0].make_multisig(info2of2, 2)
except: ok = True
assert ok
res = wallet[1].make_multisig(info, 2)
res = wallet[1].is_multisig()
info2of3 = []
wallet2of3 = [None, None, None]
for i in range(3):
wallet2of3[i] = Wallet(idx = i)
try: wallet2of3[i].close_wallet()
except: pass
res = wallet2of3[i].restore_deterministic_wallet(seed = seeds[i])
res = wallet2of3[i].is_multisig()
assert not res.multisig
res = wallet2of3[i].prepare_multisig()
assert len(res.multisig_info) > 0
info2of3.append(res.multisig_info)
for i in range(3):
ok = False
try: res = wallet2of3[i].exchange_multisig_keys(info)
except: ok = True
assert ok
res = wallet2of3[i].is_multisig()
assert not res.multisig
res = wallet2of3[1].make_multisig(info2of3, 2)
res = wallet2of3[1].is_multisig()
assert res.multisig
assert not res.ready
ok = False
try: res = wallet[1].prepare_multisig()
try: res = wallet2of3[1].prepare_multisig()
except: ok = True
assert ok
ok = False
try: res = wallet[1].make_multisig(info[0:2], 2)
try: res = wallet2of3[1].make_multisig(info2of3[0:2], 2)
except: ok = True
assert ok

View file

@ -120,7 +120,7 @@ static void check_results(const std::vector<std::string> &intermediate_infos,
for (size_t i = 0; i < wallets.size(); ++i)
{
EXPECT_TRUE(intermediate_infos[i].empty());
EXPECT_TRUE(!intermediate_infos[i].empty());
bool ready;
uint32_t threshold, total;
EXPECT_TRUE(wallets[i].multisig(&ready, &threshold, &total));
@ -171,7 +171,7 @@ static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
{
ASSERT_TRUE(wallets.size() > 1 && wallets.size() <= KEYS_COUNT);
ASSERT_TRUE(M <= wallets.size());
std::uint32_t rounds_required = multisig::multisig_kex_rounds_required(wallets.size(), M);
std::uint32_t total_rounds_required = multisig::multisig_kex_rounds_required(wallets.size(), M) + 1;
std::uint32_t rounds_complete{0};
// initialize wallets, get first round multisig kex msgs
@ -203,18 +203,17 @@ static void make_wallets(std::vector<tools::wallet2>& wallets, unsigned int M)
++rounds_complete;
// perform kex rounds until kex is complete
while (!intermediate_infos[0].empty())
bool ready;
wallets[0].multisig(&ready);
while (!ready)
{
bool ready{false};
wallets[0].multisig(&ready);
EXPECT_FALSE(ready);
intermediate_infos = exchange_round(wallets, intermediate_infos);
wallets[0].multisig(&ready);
++rounds_complete;
}
EXPECT_EQ(rounds_required, rounds_complete);
EXPECT_EQ(total_rounds_required, rounds_complete);
check_results(intermediate_infos, wallets, M);
}