From 6d0e47148bc400ca6668860e162fe2f4ad8a3dac Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 28 Jun 2016 16:03:28 +0100 Subject: [PATCH] rct: add the tx prefix hash into the MLSAG to protect the non-signatures parts of the tx from tampering. --- .../cryptonote_format_utils.cpp | 7 ++++--- tests/core_tests/chaingen_main.cpp | 2 ++ tests/core_tests/rct.cpp | 18 ++++++++++++++++++ tests/core_tests/rct.h | 13 +++++++++++++ tests/unit_tests/ringct.cpp | 10 +++++----- tests/unit_tests/serialization.cpp | 2 +- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/cryptonote_core/cryptonote_format_utils.cpp b/src/cryptonote_core/cryptonote_format_utils.cpp index 9f0693b30..4cc62c165 100644 --- a/src/cryptonote_core/cryptonote_format_utils.cpp +++ b/src/cryptonote_core/cryptonote_format_utils.cpp @@ -685,9 +685,6 @@ namespace cryptonote if (amount_in > amount_out) amounts.push_back(amount_in - amount_out); - LOG_PRINT_L1("Signing tx: " << obj_to_json_str(tx)); - tx.rct_signatures = rct::genRct(inSk, destinations, amounts, mixRing, sources[0].real_output); // same index assumption - // zero out all amounts to mask rct outputs, real amounts are now encrypted for (size_t i = 0; i < tx.vin.size(); ++i) { @@ -697,6 +694,10 @@ namespace cryptonote for (size_t i = 0; i < tx.vout.size(); ++i) tx.vout[i].amount = 0; + crypto::hash tx_prefix_hash; + get_transaction_prefix_hash(tx, tx_prefix_hash); + tx.rct_signatures = rct::genRct(inSk, destinations, amounts, mixRing, rct::hash2rct(tx_prefix_hash), sources[0].real_output); // same index assumption + LOG_PRINT2("construct_tx.log", "transaction_created: " << get_transaction_hash(tx) << ENDL << obj_to_json_str(tx) << ENDL, LOG_LEVEL_3); } diff --git a/tests/core_tests/chaingen_main.cpp b/tests/core_tests/chaingen_main.cpp index fc93b2e74..09cdb9227 100644 --- a/tests/core_tests/chaingen_main.cpp +++ b/tests/core_tests/chaingen_main.cpp @@ -199,6 +199,8 @@ int main(int argc, char* argv[]) GENERATE_AND_PLAY(gen_rct_tx_pre_rct_add_vout); GENERATE_AND_PLAY(gen_rct_tx_rct_add_vout); GENERATE_AND_PLAY(gen_rct_tx_pre_rct_increase_vin_and_fee); + GENERATE_AND_PLAY(gen_rct_tx_pre_rct_altered_extra); + GENERATE_AND_PLAY(gen_rct_tx_rct_altered_extra); std::cout << (failed_tests.empty() ? concolor::green : concolor::magenta); std::cout << "\nREPORT:\n"; diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp index 465d2036f..f16045ef6 100644 --- a/tests/core_tests/rct.cpp +++ b/tests/core_tests/rct.cpp @@ -467,3 +467,21 @@ bool gen_rct_tx_rct_add_vout::generate(std::vector& events) co NULL, [](transaction &tx) {tx.vout.push_back(tx.vout.back());}); } +bool gen_rct_tx_pre_rct_altered_extra::generate(std::vector& events) const +{ + const int mixin = 2; + const int out_idx[] = {0, -1}; + const uint64_t amount_paid = 10000; + return generate_with(events, out_idx, mixin, amount_paid, false, + NULL, [](transaction &tx) {std::string extra_nonce; crypto::hash pid = cryptonote::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); add_extra_nonce_to_tx_extra(tx.extra, extra_nonce);}); +} + +bool gen_rct_tx_rct_altered_extra::generate(std::vector& events) const +{ + const int mixin = 2; + const int out_idx[] = {1, -1}; + const uint64_t amount_paid = 10000; + return generate_with(events, out_idx, mixin, amount_paid, false, + NULL, [](transaction &tx) {std::string extra_nonce; crypto::hash pid = cryptonote::null_hash; set_payment_id_to_tx_extra_nonce(extra_nonce, pid); add_extra_nonce_to_tx_extra(tx.extra, extra_nonce);}); +} + diff --git a/tests/core_tests/rct.h b/tests/core_tests/rct.h index 1b79cbd8f..a93996566 100644 --- a/tests/core_tests/rct.h +++ b/tests/core_tests/rct.h @@ -249,3 +249,16 @@ struct gen_rct_tx_rct_add_vout : public gen_rct_tx_validation_base }; template<> struct get_test_options: public get_test_options {}; +// extra +struct gen_rct_tx_pre_rct_altered_extra : public gen_rct_tx_validation_base +{ + bool generate(std::vector& events) const; +}; +template<> struct get_test_options: public get_test_options {}; + +struct gen_rct_tx_rct_altered_extra : public gen_rct_tx_validation_base +{ + bool generate(std::vector& events) const; +}; +template<> struct get_test_options: public get_test_options {}; + diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp index 47da05f49..4b494edba 100644 --- a/tests/unit_tests/ringct.cpp +++ b/tests/unit_tests/ringct.cpp @@ -187,7 +187,7 @@ TEST(ringct, range_proofs) destinations.push_back(Pk); //compute rct data with mixin 500 - rctSig s = genRct(sc, pc, destinations, amounts, 3); + rctSig s = genRct(sc, pc, destinations, amounts, rct::zero(), 3); //verify rct data ASSERT_TRUE(verRct(s)); @@ -204,7 +204,7 @@ TEST(ringct, range_proofs) //compute rct data with mixin 500 - s = genRct(sc, pc, destinations, amounts, 3); + s = genRct(sc, pc, destinations, amounts, rct::zero(), 3); //verify rct data ASSERT_FALSE(verRct(s)); @@ -248,7 +248,7 @@ TEST(ringct, range_proofs_with_fee) destinations.push_back(Pk); //compute rct data with mixin 500 - rctSig s = genRct(sc, pc, destinations, amounts, 3); + rctSig s = genRct(sc, pc, destinations, amounts, rct::zero(), 3); //verify rct data ASSERT_TRUE(verRct(s)); @@ -265,7 +265,7 @@ TEST(ringct, range_proofs_with_fee) //compute rct data with mixin 500 - s = genRct(sc, pc, destinations, amounts, 3); + s = genRct(sc, pc, destinations, amounts, rct::zero(), 3); //verify rct data ASSERT_FALSE(verRct(s)); @@ -295,7 +295,7 @@ static rct::rctSig make_sample_rct_sig(int n_inputs, const uint64_t input_amount destinations.push_back(Pk); } - return genRct(sc, pc, destinations, amounts, 3);; + return genRct(sc, pc, destinations, amounts, rct::zero(), 3);; } static bool range_proof_test(bool expected_valid, diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index 5223298cd..01dff3e99 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -565,7 +565,7 @@ TEST(Serialization, serializes_ringct_types) rct::skpkGen(Sk, Pk); destinations.push_back(Pk); //compute rct data with mixin 500 - s0 = rct::genRct(sc, pc, destinations, amounts, 3); + s0 = rct::genRct(sc, pc, destinations, amounts, rct::zero(), 3); mg0 = s0.MG; ASSERT_TRUE(serialization::dump_binary(mg0, blob));