rct: do not serialize public keys in outPk

They can be reconstructed from vout
This commit is contained in:
moneromooo-monero
2016-07-23 12:09:33 +01:00
parent 83ab3151e8
commit cf33e1a52a
8 changed files with 87 additions and 34 deletions

View File

@@ -2468,11 +2468,12 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
{
rct::ctkeyM reconstructed_mixRing;
std::vector<rct::keyV> reconstructed_II;
rct::ctkeyV reconstructed_outPk;
// if the tx already has a non empty mixRing, use them,
// else reconstruct them
const rct::ctkeyM &mixRing = tx.rct_signatures.mixRing.empty() ? reconstructed_mixRing : tx.rct_signatures.mixRing;
// always do II, because it's split in the simple version
// always do II, because it's split in the simple version, and always do outPk
// all MGs should have the same II size (1)
for (size_t n = 0; n < tx.rct_signatures.MGs.size(); ++n)
@@ -2491,6 +2492,18 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
reconstructed_II[n].push_back(tx.rct_signatures.MGs[n].II[0]);
}
if (tx.rct_signatures.outPk.size() != tx.vout.size())
{
LOG_PRINT_L1("Failed to check ringct signatures: outPk and vout have different sizes");
return false;
}
reconstructed_outPk.resize(tx.vout.size());
for (size_t n = 0; n < tx.vout.size(); ++n)
{
reconstructed_outPk[n].dest = rct::pk2rct(boost::get<txout_to_key>(tx.vout[n].target).key);
reconstructed_outPk[n].mask = tx.rct_signatures.outPk[n].mask;
}
if (tx.rct_signatures.mixRing.empty())
{
reconstructed_mixRing.resize(pubkeys.size());
@@ -2551,7 +2564,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
}
}
if (!rct::verRctSimple(tx.rct_signatures, mixRing, &reconstructed_II, rct::hash2rct(tx_prefix_hash)))
if (!rct::verRctSimple(tx.rct_signatures, mixRing, &reconstructed_II, reconstructed_outPk, rct::hash2rct(tx_prefix_hash)))
{
LOG_PRINT_L1("Failed to check ringct signatures!");
return false;
@@ -2561,11 +2574,13 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
{
rct::ctkeyM reconstructed_mixRing;
rct::keyV reconstructed_II;
rct::ctkeyV reconstructed_outPk;
// if the tx already has a non empty mixRing and/or II, use them,
// else reconstruct them
// else reconstruct them. Always do outPk.
const rct::ctkeyM &mixRing = tx.rct_signatures.mixRing.empty() ? reconstructed_mixRing : tx.rct_signatures.mixRing;
const rct::keyV &II = tx.rct_signatures.MG.II.size() == 1 ? reconstructed_II : tx.rct_signatures.MG.II;
const rct::ctkeyV outPk = reconstructed_outPk;
// RCT needs the same mixin for all inputs
for (size_t n = 1; n < pubkeys.size(); ++n)
@@ -2599,6 +2614,18 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
reconstructed_II.push_back(tx.rct_signatures.MG.II.back());
}
if (tx.rct_signatures.outPk.size() != tx.vout.size())
{
LOG_PRINT_L1("Failed to check ringct signatures: outPk and vout have different sizes");
return false;
}
reconstructed_outPk.resize(tx.vout.size());
for (size_t n = 0; n < tx.vout.size(); ++n)
{
reconstructed_outPk[n].dest = rct::pk2rct(boost::get<txout_to_key>(tx.vout[n].target).key);
reconstructed_outPk[n].mask = tx.rct_signatures.outPk[n].mask;
}
// check all this, either recontructed (so should really pass), or not
{
bool size_matches = true;
@@ -2644,7 +2671,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, tx_verification_context
}
}
if (!rct::verRct(tx.rct_signatures, mixRing, II, rct::hash2rct(tx_prefix_hash)))
if (!rct::verRct(tx.rct_signatures, mixRing, II, outPk, rct::hash2rct(tx_prefix_hash)))
{
LOG_PRINT_L1("Failed to check ringct signatures!");
return false;