|
|
@ -4801,6 +4801,7 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password,
|
|
|
|
std::vector<crypto::secret_key> multisig_keys;
|
|
|
|
std::vector<crypto::secret_key> multisig_keys;
|
|
|
|
rct::key spend_pkey = rct::identity();
|
|
|
|
rct::key spend_pkey = rct::identity();
|
|
|
|
rct::key spend_skey;
|
|
|
|
rct::key spend_skey;
|
|
|
|
|
|
|
|
auto wiper = epee::misc_utils::create_scope_leave_handler([&](){memwipe(&spend_skey, sizeof(spend_skey));});
|
|
|
|
std::vector<crypto::public_key> multisig_signers;
|
|
|
|
std::vector<crypto::public_key> multisig_signers;
|
|
|
|
|
|
|
|
|
|
|
|
// decrypt keys
|
|
|
|
// decrypt keys
|
|
|
@ -6411,7 +6412,7 @@ void wallet2::commit_tx(pending_tx& ptx)
|
|
|
|
|
|
|
|
|
|
|
|
// tx generated, get rid of used k values
|
|
|
|
// tx generated, get rid of used k values
|
|
|
|
for (size_t idx: ptx.selected_transfers)
|
|
|
|
for (size_t idx: ptx.selected_transfers)
|
|
|
|
m_transfers[idx].m_multisig_k.clear();
|
|
|
|
memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
|
|
|
|
|
|
|
|
|
|
|
|
//fee includes dust if dust policy specified it.
|
|
|
|
//fee includes dust if dust policy specified it.
|
|
|
|
LOG_PRINT_L1("Transaction successfully sent. <" << txid << ">" << ENDL
|
|
|
|
LOG_PRINT_L1("Transaction successfully sent. <" << txid << ">" << ENDL
|
|
|
@ -6853,13 +6854,13 @@ std::string wallet2::save_multisig_tx(multisig_tx_set txs)
|
|
|
|
// txes generated, get rid of used k values
|
|
|
|
// txes generated, get rid of used k values
|
|
|
|
for (size_t n = 0; n < txs.m_ptx.size(); ++n)
|
|
|
|
for (size_t n = 0; n < txs.m_ptx.size(); ++n)
|
|
|
|
for (size_t idx: txs.m_ptx[n].construction_data.selected_transfers)
|
|
|
|
for (size_t idx: txs.m_ptx[n].construction_data.selected_transfers)
|
|
|
|
m_transfers[idx].m_multisig_k.clear();
|
|
|
|
memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
|
|
|
|
|
|
|
|
|
|
|
|
// zero out some data we don't want to share
|
|
|
|
// zero out some data we don't want to share
|
|
|
|
for (auto &ptx: txs.m_ptx)
|
|
|
|
for (auto &ptx: txs.m_ptx)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (auto &e: ptx.construction_data.sources)
|
|
|
|
for (auto &e: ptx.construction_data.sources)
|
|
|
|
e.multisig_kLRki.k = rct::zero();
|
|
|
|
memwipe(&e.multisig_kLRki.k, sizeof(e.multisig_kLRki.k));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (auto &ptx: txs.m_ptx)
|
|
|
|
for (auto &ptx: txs.m_ptx)
|
|
|
@ -7067,10 +7068,12 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
|
|
|
|
ptx.tx.rct_signatures = sig.sigs;
|
|
|
|
ptx.tx.rct_signatures = sig.sigs;
|
|
|
|
|
|
|
|
|
|
|
|
rct::keyV k;
|
|
|
|
rct::keyV k;
|
|
|
|
|
|
|
|
rct::key skey = rct::zero();
|
|
|
|
|
|
|
|
auto wiper = epee::misc_utils::create_scope_leave_handler([&](){ memwipe(k.data(), k.size() * sizeof(k[0])); memwipe(&skey, sizeof(skey)); });
|
|
|
|
|
|
|
|
|
|
|
|
for (size_t idx: sd.selected_transfers)
|
|
|
|
for (size_t idx: sd.selected_transfers)
|
|
|
|
k.push_back(get_multisig_k(idx, sig.used_L));
|
|
|
|
k.push_back(get_multisig_k(idx, sig.used_L));
|
|
|
|
|
|
|
|
|
|
|
|
rct::key skey = rct::zero();
|
|
|
|
|
|
|
|
for (const auto &msk: get_account().get_multisig_keys())
|
|
|
|
for (const auto &msk: get_account().get_multisig_keys())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
crypto::public_key pmsk = get_multisig_signing_public_key(msk);
|
|
|
|
crypto::public_key pmsk = get_multisig_signing_public_key(msk);
|
|
|
@ -7118,7 +7121,7 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector<crypto
|
|
|
|
// txes generated, get rid of used k values
|
|
|
|
// txes generated, get rid of used k values
|
|
|
|
for (size_t n = 0; n < exported_txs.m_ptx.size(); ++n)
|
|
|
|
for (size_t n = 0; n < exported_txs.m_ptx.size(); ++n)
|
|
|
|
for (size_t idx: exported_txs.m_ptx[n].construction_data.selected_transfers)
|
|
|
|
for (size_t idx: exported_txs.m_ptx[n].construction_data.selected_transfers)
|
|
|
|
m_transfers[idx].m_multisig_k.clear();
|
|
|
|
memwipe(m_transfers[idx].m_multisig_k.data(), m_transfers[idx].m_multisig_k.size() * sizeof(m_transfers[idx].m_multisig_k[0]));
|
|
|
|
|
|
|
|
|
|
|
|
exported_txs.m_signers.insert(get_multisig_signer_public_key());
|
|
|
|
exported_txs.m_signers.insert(get_multisig_signer_public_key());
|
|
|
|
|
|
|
|
|
|
|
@ -12868,7 +12871,7 @@ cryptonote::blobdata wallet2::export_multisig()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
transfer_details &td = m_transfers[n];
|
|
|
|
transfer_details &td = m_transfers[n];
|
|
|
|
crypto::key_image ki;
|
|
|
|
crypto::key_image ki;
|
|
|
|
td.m_multisig_k.clear();
|
|
|
|
memwipe(td.m_multisig_k.data(), td.m_multisig_k.size() * sizeof(td.m_multisig_k[0]));
|
|
|
|
info[n].m_LR.clear();
|
|
|
|
info[n].m_LR.clear();
|
|
|
|
info[n].m_partial_key_images.clear();
|
|
|
|
info[n].m_partial_key_images.clear();
|
|
|
|
|
|
|
|
|
|
|
@ -12977,6 +12980,7 @@ size_t wallet2::import_multisig(std::vector<cryptonote::blobdata> blobs)
|
|
|
|
CHECK_AND_ASSERT_THROW_MES(info.size() + 1 <= m_multisig_signers.size() && info.size() + 1 >= m_multisig_threshold, "Wrong number of multisig sources");
|
|
|
|
CHECK_AND_ASSERT_THROW_MES(info.size() + 1 <= m_multisig_signers.size() && info.size() + 1 >= m_multisig_threshold, "Wrong number of multisig sources");
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<rct::key>> k;
|
|
|
|
std::vector<std::vector<rct::key>> k;
|
|
|
|
|
|
|
|
auto wiper = epee::misc_utils::create_scope_leave_handler([&](){memwipe(k.data(), k.size() * sizeof(k[0]));});
|
|
|
|
k.reserve(m_transfers.size());
|
|
|
|
k.reserve(m_transfers.size());
|
|
|
|
for (const auto &td: m_transfers)
|
|
|
|
for (const auto &td: m_transfers)
|
|
|
|
k.push_back(td.m_multisig_k);
|
|
|
|
k.push_back(td.m_multisig_k);
|
|
|
|