From 3ab2ab3e7691dadf91ef39ed477e12f0144b8278 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Mon, 8 Aug 2016 13:49:42 +0100 Subject: [PATCH] rct: change the simple flag to a type for future expansion --- src/cryptonote_core/blockchain.cpp | 12 +++++++++--- src/cryptonote_core/cryptonote_basic.h | 11 +++++++---- src/cryptonote_core/cryptonote_boost_serialization.h | 10 ++++++---- src/ringct/rctSigs.cpp | 12 ++++++------ src/ringct/rctTypes.h | 12 ++++++++---- src/wallet/wallet2.cpp | 10 ++++++++-- tests/core_tests/rct.cpp | 2 +- tests/unit_tests/serialization.cpp | 2 +- 8 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 91a9d5d6..c81445f1 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2464,8 +2464,9 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context // from version 2, check ringct signatures // obviously, the original and simple rct APIs use a mixRing that's indexes // in opposite orders, because it'd be too simple otherwise... - if (tx.rct_signatures.simple) + switch (tx.rct_signatures.type) { + case rct::RCTTypeSimple: { rct::ctkeyM reconstructed_mixRing; std::vector reconstructed_II; rct::ctkeyV reconstructed_outPk; @@ -2568,9 +2569,9 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context LOG_PRINT_L1("Failed to check ringct signatures!"); return false; } + break; } - else - { + case rct::RCTTypeFull: { rct::ctkeyM reconstructed_mixRing; rct::keyV reconstructed_II; rct::ctkeyV reconstructed_outPk; @@ -2674,6 +2675,11 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context LOG_PRINT_L1("Failed to check ringct signatures!"); return false; } + break; + } + default: + LOG_PRINT_L1("Unsupported rct type: " << tx.rct_signatures.type); + return false; } } return true; diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index e5a5cc6f..b6804059 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -231,18 +231,21 @@ namespace cryptonote else { FIELD(rct_signatures) - if (rct_signatures.simple) + switch (rct_signatures.type) { + case rct::RCTTypeSimple: if (rct_signatures.mixRing.size() && rct_signatures.mixRing.size() != vin.size()) return false; - } - else - { + break; + case rct::RCTTypeFull: for (size_t i = 0; i < rct_signatures.mixRing.size(); ++i) { if (rct_signatures.mixRing[i].size() != vin.size()) return false; } + break; + default: + return false; } } END_SERIALIZE() diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h index 8a82aa7a..7a7cf858 100644 --- a/src/cryptonote_core/cryptonote_boost_serialization.h +++ b/src/cryptonote_core/cryptonote_boost_serialization.h @@ -248,15 +248,17 @@ namespace boost template inline void serialize(Archive &a, rct::rctSig &x, const boost::serialization::version_type ver) { - a & x.simple; + a & x.type; + if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple) + throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type"); // a & x.message; message is not serialized, as it can be reconstructed from the tx data a & x.rangeSigs; - if (x.simple) + if (x.type == rct::RCTTypeSimple) a & x.MGs; - else + if (x.type == rct::RCTTypeFull) a & x.MG; // a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets - if (x.simple) + if (x.type == rct::RCTTypeSimple) a & x.pseudoOuts; a & x.ecdhInfo; serializeOutPk(a, x.outPk, ver); diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index c252645f..d031f6c7 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -563,7 +563,7 @@ namespace rct { } rctSig rv; - rv.simple = false; + rv.type = RCTTypeFull; rv.outPk.resize(destinations.size()); rv.rangeSigs.resize(destinations.size()); rv.ecdhInfo.resize(destinations.size()); @@ -625,7 +625,7 @@ namespace rct { } rctSig rv; - rv.simple = true; + rv.type = RCTTypeSimple; rv.message = message; rv.outPk.resize(destinations.size()); rv.rangeSigs.resize(destinations.size()); @@ -700,7 +700,7 @@ namespace rct { // uses the attached ecdh info to find the amounts represented by each output commitment // must know the destination private key to find the correct amount, else will return a random number bool verRct(const rctSig & rv, const ctkeyM &mixRing, const keyV &II, const ctkeyV &outPk, const key &message) { - CHECK_AND_ASSERT_MES(!rv.simple, false, "verRct called on simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull, false, "verRct called on non-full rctSig"); CHECK_AND_ASSERT_MES(outPk.size() == rv.rangeSigs.size(), false, "Mismatched sizes of outPk and rv.rangeSigs"); CHECK_AND_ASSERT_MES(outPk.size() == rv.ecdhInfo.size(), false, "Mismatched sizes of outPk and rv.ecdhInfo"); @@ -739,7 +739,7 @@ namespace rct { size_t i = 0; bool rvb = true; - CHECK_AND_ASSERT_MES(rv.simple, false, "verRctSimple called on non simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple, false, "verRctSimple called on non simple rctSig"); CHECK_AND_ASSERT_MES(outPk.size() == rv.rangeSigs.size(), false, "Mismatched sizes of outPk and rv.rangeSigs"); CHECK_AND_ASSERT_MES(outPk.size() == rv.ecdhInfo.size(), false, "Mismatched sizes of outPk and rv.ecdhInfo"); CHECK_AND_ASSERT_MES(rv.pseudoOuts.size() == rv.MGs.size(), false, "Mismatched sizes of rv.pseudoOuts and rv.MGs"); @@ -803,7 +803,7 @@ namespace rct { // uses the attached ecdh info to find the amounts represented by each output commitment // must know the destination private key to find the correct amount, else will return a random number static xmr_amount decodeRctMain(const rctSig & rv, const key & sk, unsigned int i, key & mask, void (*decode)(ecdhTuple&, const key&)) { - CHECK_AND_ASSERT_MES(!rv.simple, false, "decodeRct called on simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeFull, false, "decodeRct called on non-full rctSig"); CHECK_AND_ASSERT_THROW_MES(rv.rangeSigs.size() > 0, "Empty rv.rangeSigs"); CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.rangeSigs.size(), "Mismatched sizes of rv.outPk and rv.rangeSigs"); CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index"); @@ -840,7 +840,7 @@ namespace rct { } static xmr_amount decodeRctSimpleMain(const rctSig & rv, const key & sk, unsigned int i, key &mask, void (*decode)(ecdhTuple &ecdh, const key&)) { - CHECK_AND_ASSERT_MES(rv.simple, false, "decodeRct called on non simple rctSig"); + CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple, false, "decodeRct called on non simple rctSig"); CHECK_AND_ASSERT_THROW_MES(rv.rangeSigs.size() > 0, "Empty rv.rangeSigs"); CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.rangeSigs.size(), "Mismatched sizes of rv.outPk and rv.rangeSigs"); CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index"); diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 8df403c6..98876a08 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -173,8 +173,12 @@ namespace rct { // ecdhInfo holds an encoded mask / amount to be passed to each receiver // outPk contains public keypairs which are destinations (P, C), // P = address, C = commitment to amount + enum { + RCTTypeFull = 0, + RCTTypeSimple = 1, + }; struct rctSig { - bool simple; + uint8_t type; key message; vector rangeSigs; mgSig MG; // for non simple rct @@ -187,15 +191,15 @@ namespace rct { xmr_amount txnFee; // contains b BEGIN_SERIALIZE_OBJECT() - FIELD(simple) + FIELD(type) // FIELD(message) - not serialized, it can be reconstructed FIELD(rangeSigs) - if (simple) + if (type == RCTTypeSimple) FIELD(MGs) else FIELD(MG) // FIELD(mixRing) - not serialized, it can be reconstructed - if (simple) + if (type == RCTTypeSimple) FIELD(pseudoOuts) FIELD(ecdhInfo) if (typename Archive::is_saving()) { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5d51efc1..c3fb160a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -211,10 +211,16 @@ static uint64_t decodeRct(const rct::rctSig & rv, const rct::key & sk, unsigned { try { - if (rv.simple) + switch (rv.type) + { + case rct::RCTTypeSimple: return rct::decodeRctSimpleFromSharedSecret(rv, sk, i, mask); - else + case rct::RCTTypeFull: return rct::decodeRctFromSharedSecret(rv, sk, i, mask); + default: + LOG_ERROR("Unsupported rct type: " << rv.type); + return 0; + } } catch (const std::exception &e) { diff --git a/tests/core_tests/rct.cpp b/tests/core_tests/rct.cpp index bf6ef136..d03e208b 100644 --- a/tests/core_tests/rct.cpp +++ b/tests/core_tests/rct.cpp @@ -126,7 +126,7 @@ bool gen_rct_tx_validation_base::generate_with(std::vector& ev for (size_t o = 0; o < 4; ++o) { rct::key amount_key = rct::hash_to_scalar(rct::scalarmultKey(rct::pk2rct(tx_pub_key), rct::sk2rct(miner_accounts[n].get_keys().m_view_secret_key))); - if (rct_txes[n].rct_signatures.simple) + if (rct_txes[n].rct_signatures.type == rct::RCTTypeSimple) rct::decodeRctSimpleFromSharedSecret(rct_txes[n].rct_signatures, amount_key, o, rct_tx_masks[o+n*4]); else rct::decodeRctFromSharedSecret(rct_txes[n].rct_signatures, amount_key, o, rct_tx_masks[o+n*4]); diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index 9311ca01..039c26fc 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -591,7 +591,7 @@ TEST(Serialization, serializes_ringct_types) ASSERT_TRUE(serialization::dump_binary(s0, blob)); ASSERT_TRUE(serialization::parse_binary(blob, s1)); - ASSERT_TRUE(s0.simple == s1.simple); + ASSERT_TRUE(s0.type == s1.type); ASSERT_TRUE(s0.rangeSigs.size() == s1.rangeSigs.size()); for (size_t n = 0; n < s0.rangeSigs.size(); ++n) {