mirror of
https://github.com/monero-project/monero.git
synced 2025-08-24 04:45:12 -04:00
Updates InProofV1, OutProofV1, and ReserveProofV1 to new V2 variants that include all public proof parameters in Schnorr challenges, along with hash function domain separators. Includes new randomized unit tests.
This commit is contained in:
parent
5d850dde99
commit
6bfcd31015
7 changed files with 332 additions and 31 deletions
|
@ -11425,7 +11425,7 @@ std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypt
|
|||
hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[i], additional_tx_keys[i - 1], sig[i]);
|
||||
}
|
||||
}
|
||||
sig_str = std::string("OutProofV1");
|
||||
sig_str = std::string("OutProofV2");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -11461,7 +11461,7 @@ std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypt
|
|||
hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], boost::none, shared_secret[i], a, sig[i]);
|
||||
}
|
||||
}
|
||||
sig_str = std::string("InProofV1");
|
||||
sig_str = std::string("InProofV2");
|
||||
}
|
||||
const size_t num_sigs = shared_secret.size();
|
||||
|
||||
|
@ -11540,8 +11540,14 @@ bool wallet2::check_tx_proof(const crypto::hash &txid, const cryptonote::account
|
|||
|
||||
bool wallet2::check_tx_proof(const cryptonote::transaction &tx, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message, const std::string &sig_str, uint64_t &received) const
|
||||
{
|
||||
// InProofV1, InProofV2, OutProofV1, OutProofV2
|
||||
const bool is_out = sig_str.substr(0, 3) == "Out";
|
||||
const std::string header = is_out ? "OutProofV1" : "InProofV1";
|
||||
const std::string header = is_out ? sig_str.substr(0,10) : sig_str.substr(0,9);
|
||||
int version = 2; // InProofV2
|
||||
if (is_out && sig_str.substr(8,2) == "V1") version = 1; // OutProofV1
|
||||
else if (is_out) version = 2; // OutProofV2
|
||||
else if (sig_str.substr(7,2) == "V1") version = 1; // InProofV1
|
||||
|
||||
const size_t header_len = header.size();
|
||||
THROW_WALLET_EXCEPTION_IF(sig_str.size() < header_len || sig_str.substr(0, header_len) != header, error::wallet_internal_error,
|
||||
"Signature header check error");
|
||||
|
@ -11588,27 +11594,27 @@ bool wallet2::check_tx_proof(const cryptonote::transaction &tx, const cryptonote
|
|||
if (is_out)
|
||||
{
|
||||
good_signature[0] = is_subaddress ?
|
||||
crypto::check_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[0], sig[0]) :
|
||||
crypto::check_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[0], sig[0]);
|
||||
crypto::check_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[0], sig[0], version) :
|
||||
crypto::check_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[0], sig[0], version);
|
||||
|
||||
for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i)
|
||||
{
|
||||
good_signature[i + 1] = is_subaddress ?
|
||||
crypto::check_tx_proof(prefix_hash, additional_tx_pub_keys[i], address.m_view_public_key, address.m_spend_public_key, shared_secret[i + 1], sig[i + 1]) :
|
||||
crypto::check_tx_proof(prefix_hash, additional_tx_pub_keys[i], address.m_view_public_key, boost::none, shared_secret[i + 1], sig[i + 1]);
|
||||
crypto::check_tx_proof(prefix_hash, additional_tx_pub_keys[i], address.m_view_public_key, address.m_spend_public_key, shared_secret[i + 1], sig[i + 1], version) :
|
||||
crypto::check_tx_proof(prefix_hash, additional_tx_pub_keys[i], address.m_view_public_key, boost::none, shared_secret[i + 1], sig[i + 1], version);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
good_signature[0] = is_subaddress ?
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, address.m_spend_public_key, shared_secret[0], sig[0]) :
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, shared_secret[0], sig[0]);
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, address.m_spend_public_key, shared_secret[0], sig[0], version) :
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, shared_secret[0], sig[0], version);
|
||||
|
||||
for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i)
|
||||
{
|
||||
good_signature[i + 1] = is_subaddress ?
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i], address.m_spend_public_key, shared_secret[i + 1], sig[i + 1]) :
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i], boost::none, shared_secret[i + 1], sig[i + 1]);
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i], address.m_spend_public_key, shared_secret[i + 1], sig[i + 1], version) :
|
||||
crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i], boost::none, shared_secret[i + 1], sig[i + 1], version);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11746,7 +11752,7 @@ std::string wallet2::get_reserve_proof(const boost::optional<std::pair<uint32_t,
|
|||
std::ostringstream oss;
|
||||
boost::archive::portable_binary_oarchive ar(oss);
|
||||
ar << proofs << subaddr_spendkeys;
|
||||
return "ReserveProofV1" + tools::base58::encode(oss.str());
|
||||
return "ReserveProofV2" + tools::base58::encode(oss.str());
|
||||
}
|
||||
|
||||
bool wallet2::check_reserve_proof(const cryptonote::account_public_address &address, const std::string &message, const std::string &sig_str, uint64_t &total, uint64_t &spent)
|
||||
|
@ -11755,12 +11761,18 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
|
|||
THROW_WALLET_EXCEPTION_IF(!check_connection(&rpc_version), error::wallet_internal_error, "Failed to connect to daemon: " + get_daemon_address());
|
||||
THROW_WALLET_EXCEPTION_IF(rpc_version < MAKE_CORE_RPC_VERSION(1, 0), error::wallet_internal_error, "Daemon RPC version is too old");
|
||||
|
||||
static constexpr char header[] = "ReserveProofV1";
|
||||
THROW_WALLET_EXCEPTION_IF(!boost::string_ref{sig_str}.starts_with(header), error::wallet_internal_error,
|
||||
static constexpr char header_v1[] = "ReserveProofV1";
|
||||
static constexpr char header_v2[] = "ReserveProofV2"; // assumes same length as header_v1
|
||||
THROW_WALLET_EXCEPTION_IF(!boost::string_ref{sig_str}.starts_with(header_v1) && !boost::string_ref{sig_str}.starts_with(header_v2), error::wallet_internal_error,
|
||||
"Signature header check error");
|
||||
int version = 2; // assume newest version
|
||||
if (boost::string_ref{sig_str}.starts_with(header_v1))
|
||||
version = 1;
|
||||
else if (boost::string_ref{sig_str}.starts_with(header_v2))
|
||||
version = 2;
|
||||
|
||||
std::string sig_decoded;
|
||||
THROW_WALLET_EXCEPTION_IF(!tools::base58::decode(sig_str.substr(std::strlen(header)), sig_decoded), error::wallet_internal_error,
|
||||
THROW_WALLET_EXCEPTION_IF(!tools::base58::decode(sig_str.substr(std::strlen(header_v1)), sig_decoded), error::wallet_internal_error,
|
||||
"Signature decoding error");
|
||||
|
||||
std::istringstream iss(sig_decoded);
|
||||
|
@ -11841,9 +11853,9 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr
|
|||
const std::vector<crypto::public_key> additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(tx);
|
||||
|
||||
// check singature for shared secret
|
||||
ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, proof.shared_secret, proof.shared_secret_sig);
|
||||
ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, proof.shared_secret, proof.shared_secret_sig, version);
|
||||
if (!ok && additional_tx_pub_keys.size() == tx.vout.size())
|
||||
ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[proof.index_in_tx], boost::none, proof.shared_secret, proof.shared_secret_sig);
|
||||
ok = crypto::check_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[proof.index_in_tx], boost::none, proof.shared_secret, proof.shared_secret_sig, version);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue