rct: change the simple flag to a type
for future expansion
This commit is contained in:
parent
c5be4b0bea
commit
3ab2ab3e76
|
@ -2464,8 +2464,9 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
|
||||||
// from version 2, check ringct signatures
|
// from version 2, check ringct signatures
|
||||||
// obviously, the original and simple rct APIs use a mixRing that's indexes
|
// obviously, the original and simple rct APIs use a mixRing that's indexes
|
||||||
// in opposite orders, because it'd be too simple otherwise...
|
// 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;
|
rct::ctkeyM reconstructed_mixRing;
|
||||||
std::vector<rct::keyV> reconstructed_II;
|
std::vector<rct::keyV> reconstructed_II;
|
||||||
rct::ctkeyV reconstructed_outPk;
|
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!");
|
LOG_PRINT_L1("Failed to check ringct signatures!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
case rct::RCTTypeFull: {
|
||||||
{
|
|
||||||
rct::ctkeyM reconstructed_mixRing;
|
rct::ctkeyM reconstructed_mixRing;
|
||||||
rct::keyV reconstructed_II;
|
rct::keyV reconstructed_II;
|
||||||
rct::ctkeyV reconstructed_outPk;
|
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!");
|
LOG_PRINT_L1("Failed to check ringct signatures!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
LOG_PRINT_L1("Unsupported rct type: " << tx.rct_signatures.type);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -231,18 +231,21 @@ namespace cryptonote
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FIELD(rct_signatures)
|
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())
|
if (rct_signatures.mixRing.size() && rct_signatures.mixRing.size() != vin.size())
|
||||||
return false;
|
return false;
|
||||||
}
|
break;
|
||||||
else
|
case rct::RCTTypeFull:
|
||||||
{
|
|
||||||
for (size_t i = 0; i < rct_signatures.mixRing.size(); ++i)
|
for (size_t i = 0; i < rct_signatures.mixRing.size(); ++i)
|
||||||
{
|
{
|
||||||
if (rct_signatures.mixRing[i].size() != vin.size())
|
if (rct_signatures.mixRing[i].size() != vin.size())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
|
|
|
@ -248,15 +248,17 @@ namespace boost
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
inline void serialize(Archive &a, rct::rctSig &x, const boost::serialization::version_type ver)
|
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.message; message is not serialized, as it can be reconstructed from the tx data
|
||||||
a & x.rangeSigs;
|
a & x.rangeSigs;
|
||||||
if (x.simple)
|
if (x.type == rct::RCTTypeSimple)
|
||||||
a & x.MGs;
|
a & x.MGs;
|
||||||
else
|
if (x.type == rct::RCTTypeFull)
|
||||||
a & x.MG;
|
a & x.MG;
|
||||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
// 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.pseudoOuts;
|
||||||
a & x.ecdhInfo;
|
a & x.ecdhInfo;
|
||||||
serializeOutPk(a, x.outPk, ver);
|
serializeOutPk(a, x.outPk, ver);
|
||||||
|
|
|
@ -563,7 +563,7 @@ namespace rct {
|
||||||
}
|
}
|
||||||
|
|
||||||
rctSig rv;
|
rctSig rv;
|
||||||
rv.simple = false;
|
rv.type = RCTTypeFull;
|
||||||
rv.outPk.resize(destinations.size());
|
rv.outPk.resize(destinations.size());
|
||||||
rv.rangeSigs.resize(destinations.size());
|
rv.rangeSigs.resize(destinations.size());
|
||||||
rv.ecdhInfo.resize(destinations.size());
|
rv.ecdhInfo.resize(destinations.size());
|
||||||
|
@ -625,7 +625,7 @@ namespace rct {
|
||||||
}
|
}
|
||||||
|
|
||||||
rctSig rv;
|
rctSig rv;
|
||||||
rv.simple = true;
|
rv.type = RCTTypeSimple;
|
||||||
rv.message = message;
|
rv.message = message;
|
||||||
rv.outPk.resize(destinations.size());
|
rv.outPk.resize(destinations.size());
|
||||||
rv.rangeSigs.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
|
// 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
|
// 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) {
|
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.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(outPk.size() == rv.ecdhInfo.size(), false, "Mismatched sizes of outPk and rv.ecdhInfo");
|
||||||
|
|
||||||
|
@ -739,7 +739,7 @@ namespace rct {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
bool rvb = true;
|
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.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(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");
|
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
|
// 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
|
// 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&)) {
|
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.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(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");
|
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&)) {
|
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.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(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");
|
CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
|
||||||
|
|
|
@ -173,8 +173,12 @@ namespace rct {
|
||||||
// ecdhInfo holds an encoded mask / amount to be passed to each receiver
|
// ecdhInfo holds an encoded mask / amount to be passed to each receiver
|
||||||
// outPk contains public keypairs which are destinations (P, C),
|
// outPk contains public keypairs which are destinations (P, C),
|
||||||
// P = address, C = commitment to amount
|
// P = address, C = commitment to amount
|
||||||
|
enum {
|
||||||
|
RCTTypeFull = 0,
|
||||||
|
RCTTypeSimple = 1,
|
||||||
|
};
|
||||||
struct rctSig {
|
struct rctSig {
|
||||||
bool simple;
|
uint8_t type;
|
||||||
key message;
|
key message;
|
||||||
vector<rangeSig> rangeSigs;
|
vector<rangeSig> rangeSigs;
|
||||||
mgSig MG; // for non simple rct
|
mgSig MG; // for non simple rct
|
||||||
|
@ -187,15 +191,15 @@ namespace rct {
|
||||||
xmr_amount txnFee; // contains b
|
xmr_amount txnFee; // contains b
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
FIELD(simple)
|
FIELD(type)
|
||||||
// FIELD(message) - not serialized, it can be reconstructed
|
// FIELD(message) - not serialized, it can be reconstructed
|
||||||
FIELD(rangeSigs)
|
FIELD(rangeSigs)
|
||||||
if (simple)
|
if (type == RCTTypeSimple)
|
||||||
FIELD(MGs)
|
FIELD(MGs)
|
||||||
else
|
else
|
||||||
FIELD(MG)
|
FIELD(MG)
|
||||||
// FIELD(mixRing) - not serialized, it can be reconstructed
|
// FIELD(mixRing) - not serialized, it can be reconstructed
|
||||||
if (simple)
|
if (type == RCTTypeSimple)
|
||||||
FIELD(pseudoOuts)
|
FIELD(pseudoOuts)
|
||||||
FIELD(ecdhInfo)
|
FIELD(ecdhInfo)
|
||||||
if (typename Archive<W>::is_saving()) {
|
if (typename Archive<W>::is_saving()) {
|
||||||
|
|
|
@ -211,10 +211,16 @@ static uint64_t decodeRct(const rct::rctSig & rv, const rct::key & sk, unsigned
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (rv.simple)
|
switch (rv.type)
|
||||||
|
{
|
||||||
|
case rct::RCTTypeSimple:
|
||||||
return rct::decodeRctSimpleFromSharedSecret(rv, sk, i, mask);
|
return rct::decodeRctSimpleFromSharedSecret(rv, sk, i, mask);
|
||||||
else
|
case rct::RCTTypeFull:
|
||||||
return rct::decodeRctFromSharedSecret(rv, sk, i, mask);
|
return rct::decodeRctFromSharedSecret(rv, sk, i, mask);
|
||||||
|
default:
|
||||||
|
LOG_ERROR("Unsupported rct type: " << rv.type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -126,7 +126,7 @@ bool gen_rct_tx_validation_base::generate_with(std::vector<test_event_entry>& ev
|
||||||
for (size_t o = 0; o < 4; ++o)
|
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)));
|
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]);
|
rct::decodeRctSimpleFromSharedSecret(rct_txes[n].rct_signatures, amount_key, o, rct_tx_masks[o+n*4]);
|
||||||
else
|
else
|
||||||
rct::decodeRctFromSharedSecret(rct_txes[n].rct_signatures, amount_key, o, rct_tx_masks[o+n*4]);
|
rct::decodeRctFromSharedSecret(rct_txes[n].rct_signatures, amount_key, o, rct_tx_masks[o+n*4]);
|
||||||
|
|
|
@ -591,7 +591,7 @@ TEST(Serialization, serializes_ringct_types)
|
||||||
|
|
||||||
ASSERT_TRUE(serialization::dump_binary(s0, blob));
|
ASSERT_TRUE(serialization::dump_binary(s0, blob));
|
||||||
ASSERT_TRUE(serialization::parse_binary(blob, s1));
|
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());
|
ASSERT_TRUE(s0.rangeSigs.size() == s1.rangeSigs.size());
|
||||||
for (size_t n = 0; n < s0.rangeSigs.size(); ++n)
|
for (size_t n = 0; n < s0.rangeSigs.size(); ++n)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue