multisig: fix #8537 seed restore (suggestions by @UkoeHB)
- spend secret key is no longer the sum of multisig key shares; no need to check that is the case upon restore. - restoring a multisig wallet from multisig info means that the wallet must have already completed all setup rounds. Upon restore, set the number of rounds completed accordingly.
This commit is contained in:
parent
727bc5b687
commit
fc8a5d68f1
@ -127,7 +127,7 @@ namespace multisig
|
|||||||
bool multisig_account::multisig_is_ready() const
|
bool multisig_account::multisig_is_ready() const
|
||||||
{
|
{
|
||||||
if (main_kex_rounds_done())
|
if (main_kex_rounds_done())
|
||||||
return m_kex_rounds_complete >= multisig_kex_rounds_required(m_signers.size(), m_threshold) + 1;
|
return m_kex_rounds_complete >= multisig_setup_rounds_required(m_signers.size(), m_threshold);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -200,4 +200,11 @@ namespace multisig
|
|||||||
return num_signers - threshold + 1;
|
return num_signers - threshold + 1;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
// EXTERNAL
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
std::uint32_t multisig_setup_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold)
|
||||||
|
{
|
||||||
|
return multisig_kex_rounds_required(num_signers, threshold) + 1;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
} //namespace multisig
|
} //namespace multisig
|
||||||
|
@ -245,4 +245,13 @@ namespace multisig
|
|||||||
* return: number of kex rounds required
|
* return: number of kex rounds required
|
||||||
*/
|
*/
|
||||||
std::uint32_t multisig_kex_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold);
|
std::uint32_t multisig_kex_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* brief: multisig_setup_rounds_required - The number of setup rounds required to produce an M-of-N shared key.
|
||||||
|
* - A participant must complete all kex rounds and 1 initialization round.
|
||||||
|
* param: num_signers - number of participants in multisig (N)
|
||||||
|
* param: threshold - threshold of multisig (M)
|
||||||
|
* return: number of setup rounds required
|
||||||
|
*/
|
||||||
|
std::uint32_t multisig_setup_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold);
|
||||||
} //namespace multisig
|
} //namespace multisig
|
||||||
|
@ -74,7 +74,7 @@ namespace multisig
|
|||||||
"Multisig threshold may not be larger than number of signers.");
|
"Multisig threshold may not be larger than number of signers.");
|
||||||
CHECK_AND_ASSERT_THROW_MES(threshold > 0, "Multisig threshold must be > 0.");
|
CHECK_AND_ASSERT_THROW_MES(threshold > 0, "Multisig threshold must be > 0.");
|
||||||
CHECK_AND_ASSERT_THROW_MES(round > 0, "Multisig kex round must be > 0.");
|
CHECK_AND_ASSERT_THROW_MES(round > 0, "Multisig kex round must be > 0.");
|
||||||
CHECK_AND_ASSERT_THROW_MES(round <= multisig_kex_rounds_required(num_signers, threshold) + 1,
|
CHECK_AND_ASSERT_THROW_MES(round <= multisig_setup_rounds_required(num_signers, threshold),
|
||||||
"Trying to process multisig kex for an invalid round.");
|
"Trying to process multisig kex for an invalid round.");
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------------------
|
||||||
|
@ -4684,7 +4684,8 @@ void wallet2::init_type(hw::device::device_type device_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates a wallet or restores one.
|
* \brief Generates a wallet or restores one. Assumes the multisig setup
|
||||||
|
* has already completed for the provided multisig info.
|
||||||
* \param wallet_ Name of wallet file
|
* \param wallet_ Name of wallet file
|
||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
* \param multisig_data The multisig restore info and keys
|
* \param multisig_data The multisig restore info and keys
|
||||||
@ -4743,11 +4744,6 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
|||||||
crypto::public_key local_signer;
|
crypto::public_key local_signer;
|
||||||
THROW_WALLET_EXCEPTION_IF(!crypto::secret_key_to_public_key(spend_secret_key, local_signer), error::invalid_multisig_seed);
|
THROW_WALLET_EXCEPTION_IF(!crypto::secret_key_to_public_key(spend_secret_key, local_signer), error::invalid_multisig_seed);
|
||||||
THROW_WALLET_EXCEPTION_IF(std::find(multisig_signers.begin(), multisig_signers.end(), local_signer) == multisig_signers.end(), error::invalid_multisig_seed);
|
THROW_WALLET_EXCEPTION_IF(std::find(multisig_signers.begin(), multisig_signers.end(), local_signer) == multisig_signers.end(), error::invalid_multisig_seed);
|
||||||
rct::key skey = rct::zero();
|
|
||||||
for (const auto &msk: multisig_keys)
|
|
||||||
sc_add(skey.bytes, skey.bytes, rct::sk2rct(msk).bytes);
|
|
||||||
THROW_WALLET_EXCEPTION_IF(!(rct::rct2sk(skey) == spend_secret_key), error::invalid_multisig_seed);
|
|
||||||
memwipe(&skey, sizeof(rct::key));
|
|
||||||
|
|
||||||
m_account.make_multisig(view_secret_key, spend_secret_key, spend_public_key, multisig_keys);
|
m_account.make_multisig(view_secret_key, spend_secret_key, spend_public_key, multisig_keys);
|
||||||
|
|
||||||
@ -4758,6 +4754,8 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string&
|
|||||||
m_multisig = true;
|
m_multisig = true;
|
||||||
m_multisig_threshold = threshold;
|
m_multisig_threshold = threshold;
|
||||||
m_multisig_signers = multisig_signers;
|
m_multisig_signers = multisig_signers;
|
||||||
|
// wallet is assumed already finalized
|
||||||
|
m_multisig_rounds_passed = multisig::multisig_setup_rounds_required(m_multisig_signers.size(), m_multisig_threshold);
|
||||||
setup_keys(password);
|
setup_keys(password);
|
||||||
|
|
||||||
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
|
create_keys_file(wallet_, false, password, m_nettype != MAINNET || create_address_file);
|
||||||
@ -5208,7 +5206,7 @@ bool wallet2::multisig(bool *ready, uint32_t *threshold, uint32_t *total) const
|
|||||||
if (ready)
|
if (ready)
|
||||||
{
|
{
|
||||||
*ready = !(get_account().get_keys().m_account_address.m_spend_public_key == rct::rct2pk(rct::identity())) &&
|
*ready = !(get_account().get_keys().m_account_address.m_spend_public_key == rct::rct2pk(rct::identity())) &&
|
||||||
(m_multisig_rounds_passed == multisig::multisig_kex_rounds_required(m_multisig_signers.size(), m_multisig_threshold) + 1);
|
(m_multisig_rounds_passed == multisig::multisig_setup_rounds_required(m_multisig_signers.size(), m_multisig_threshold));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -794,7 +794,8 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Generates a wallet or restores one.
|
* \brief Generates a wallet or restores one. Assumes the multisig setup
|
||||||
|
* has already completed for the provided multisig info.
|
||||||
* \param wallet_ Name of wallet file
|
* \param wallet_ Name of wallet file
|
||||||
* \param password Password of wallet file
|
* \param password Password of wallet file
|
||||||
* \param multisig_data The multisig restore info and keys
|
* \param multisig_data The multisig restore info and keys
|
||||||
|
@ -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(wallets.size() > 1 && wallets.size() <= KEYS_COUNT);
|
||||||
ASSERT_TRUE(M <= wallets.size());
|
ASSERT_TRUE(M <= wallets.size());
|
||||||
std::uint32_t total_rounds_required = multisig::multisig_kex_rounds_required(wallets.size(), M) + 1;
|
std::uint32_t total_rounds_required = multisig::multisig_setup_rounds_required(wallets.size(), M);
|
||||||
std::uint32_t rounds_complete{0};
|
std::uint32_t rounds_complete{0};
|
||||||
|
|
||||||
// initialize wallets, get first round multisig kex msgs
|
// initialize wallets, get first round multisig kex msgs
|
||||||
|
Loading…
Reference in New Issue
Block a user