From f7c928e3a21285d8f797d30daf231a023e7261a0 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Tue, 16 Jan 2024 19:01:57 +0100 Subject: [PATCH] outputs with zero pubkeys (00..00, torsion element of order 4) should not be used as inputs at all (even as mixins) --- src/currency_core/blockchain_storage.h | 17 +++++++++++++++++ src/currency_core/currency_format_utils.cpp | 12 +++++++++--- src/currency_core/currency_format_utils.h | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/currency_core/blockchain_storage.h b/src/currency_core/blockchain_storage.h index e53ae190..d9e7e478 100644 --- a/src/currency_core/blockchain_storage.h +++ b/src/currency_core/blockchain_storage.h @@ -737,6 +737,8 @@ namespace currency template bool blockchain_storage::scan_outputkeys_for_indexes(const transaction &validated_tx, const txin_v& verified_input, visitor_t& vis, uint64_t& max_related_block_height, scan_for_keys_context& scan_context) const { + bool hf4 = this->is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM); + uint64_t amount = get_amount_from_variant(verified_input); const std::vector& key_offsets = get_key_offsets_from_txin_v(verified_input); @@ -809,6 +811,11 @@ namespace currency bool mixattr_ok = is_mixattr_applicable_for_fake_outs_counter(tx_ptr->tx.version, outtk.mix_attr, key_offsets.size() - 1); CHECK_AND_ASSERT_MES(mixattr_ok, false, "tx input ref #" << output_index << " violates mixin restrictions: tx.version = " << tx_ptr->tx.version << ", mix_attr = " << static_cast(outtk.mix_attr) << ", key_offsets.size = " << key_offsets.size()); + if (hf4) + { + bool legit_output_key = validate_output_key_legit(outtk.key); + CHECK_AND_ASSERT_MES(legit_output_key, false, "tx input ref #" << output_index << " violates public key restrictions: tx.version = " << tx_ptr->tx.version << ", outtk.key = " << outtk.key); + } } else if (o.target.type() == typeid(txout_htlc)) { @@ -828,6 +835,12 @@ namespace currency //HTLC IS expired, can be used ONLY by pkey_after_expiration and ONLY by to_key input scan_context.htlc_is_expired = true; } + if (hf4) + { + bool legit_output_key = validate_output_key_legit(scan_context.htlc_is_expired ? htlc_out.pkey_refund: htlc_out.pkey_redeem); + CHECK_AND_ASSERT_MES(legit_output_key, false, "tx input ref #" << output_index << " violates public key restrictions: tx.version = " << tx_ptr->tx.version << ", outtk.key = " << static_cast(scan_context.htlc_is_expired ? htlc_out.pkey_refund : htlc_out.pkey_redeem)); + } + } else { @@ -852,6 +865,10 @@ namespace currency r = is_mixattr_applicable_for_fake_outs_counter(tx_ptr->tx.version, out_zc.mix_attr, key_offsets.size() - 1); CHECK_AND_ASSERT_MES(r, false, "tx input ref #" << output_index << " violates mixin restrictions: tx.version = " << tx_ptr->tx.version << ", mix_attr = " << static_cast(out_zc.mix_attr) << ", key_offsets.size = " << key_offsets.size()); + bool legit_output_key = validate_output_key_legit(out_zc.stealth_address); + CHECK_AND_ASSERT_MES(legit_output_key, false, "tx input ref #" << output_index << " violates public key restrictions: tx.version = " << tx_ptr->tx.version << ", outtk.key = " << out_zc.stealth_address); + + TIME_MEASURE_START_PD(tx_check_inputs_loop_scan_outputkeys_loop_handle_output); if (!vis.handle_output(tx_ptr->tx, validated_tx, out_zc, n)) { diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index d732a49b..faa72a9f 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -3330,9 +3330,15 @@ namespace currency att.push_back(tsa); return true; } - - - + //--------------------------------------------------------------- + bool validate_output_key_legit(const crypto::public_key& k) + { + if (currency::null_pkey == k) + { + return false; + } + return true; + } //--------------------------------------------------------------- std::string print_money_brief(uint64_t amount, size_t decimal_point /* = CURRENCY_DISPLAY_DECIMAL_POINT */) { diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index c7728eff..dace13a0 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -407,7 +407,7 @@ namespace currency std::vector relative_output_offsets_to_absolute(const std::vector& off); bool absolute_sorted_output_offsets_to_relative_in_place(std::vector& offsets) noexcept; - + bool validate_output_key_legit(const crypto::public_key& k); // prints amount in format "3.14", "0.0" std::string print_money_brief(uint64_t amount, size_t decimal_point = CURRENCY_DISPLAY_DECIMAL_POINT);