aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2020-12-17 11:57:53 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2022-04-05 18:50:17 +0000
commita0d80b1f95cee64edfeba799f4fe9b8fb2ef4f43 (patch)
treeac0526f8b6747105010dacc20b3cd70e18ca993f /src/cryptonote_core
parentUpdates from security audit (diff)
downloadmonero-a0d80b1f95cee64edfeba799f4fe9b8fb2ef4f43.tar.xz
plug bulletproofs plus into consensus
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp35
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp23
2 files changed, 53 insertions, 5 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 34031fb7c..cd9972d1e 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -3143,6 +3143,32 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
}
}
+ // from v15, allow bulletproofs plus
+ if (hf_version < HF_VERSION_BULLETPROOF_PLUS) {
+ if (tx.version >= 2) {
+ const bool bulletproof_plus = rct::is_rct_bulletproof_plus(tx.rct_signatures.type);
+ if (bulletproof_plus || !tx.rct_signatures.p.bulletproofs_plus.empty())
+ {
+ MERROR_VER("Bulletproofs plus are not allowed before v" << std::to_string(HF_VERSION_BULLETPROOF_PLUS));
+ tvc.m_invalid_output = true;
+ return false;
+ }
+ }
+ }
+
+ // from v16, forbid bulletproofs
+ if (hf_version > HF_VERSION_BULLETPROOF_PLUS) {
+ if (tx.version >= 2) {
+ const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
+ if (bulletproof)
+ {
+ MERROR_VER("Bulletproof range proofs are not allowed after v" + std::to_string(HF_VERSION_BULLETPROOF_PLUS));
+ tvc.m_invalid_output = true;
+ return false;
+ }
+ }
+ }
+
return true;
}
//------------------------------------------------------------------
@@ -3183,7 +3209,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
}
}
}
- else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG)
+ else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
{
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
rv.mixRing.resize(pubkeys.size());
@@ -3224,7 +3250,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
}
}
}
- else if (rv.type == rct::RCTTypeCLSAG)
+ else if (rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus)
{
if (!tx.pruned)
{
@@ -3516,6 +3542,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
case rct::RCTTypeBulletproof:
case rct::RCTTypeBulletproof2:
case rct::RCTTypeCLSAG:
+ case rct::RCTTypeBulletproofPlus:
{
// check all this, either reconstructed (so should really pass), or not
{
@@ -3551,7 +3578,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
}
- const size_t n_sigs = rv.type == rct::RCTTypeCLSAG ? rv.p.CLSAGs.size() : rv.p.MGs.size();
+ const size_t n_sigs = rct::is_rct_clsag(rv.type) ? rv.p.CLSAGs.size() : rv.p.MGs.size();
if (n_sigs != tx.vin.size())
{
MERROR_VER("Failed to check ringct signatures: mismatched MGs/vin sizes");
@@ -3560,7 +3587,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
for (size_t n = 0; n < tx.vin.size(); ++n)
{
bool error;
- if (rv.type == rct::RCTTypeCLSAG)
+ if (rct::is_rct_clsag(rv.type))
error = memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.CLSAGs[n].I, 32);
else
error = rv.p.MGs[n].II.empty() || memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.MGs[n].II[0], 32);
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 4c6536318..1da4e2d41 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -879,6 +879,16 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
+ static bool is_canonical_bulletproof_plus_layout(const std::vector<rct::BulletproofPlus> &proofs)
+ {
+ if (proofs.size() != 1)
+ return false;
+ const size_t sz = proofs[0].V.size();
+ if (sz == 0 || sz > BULLETPROOF_PLUS_MAX_OUTPUTS)
+ return false;
+ return true;
+ }
+ //-----------------------------------------------------------------------------------------------
bool core::handle_incoming_tx_accumulated_batch(std::vector<tx_verification_batch_info> &tx_info, bool keeped_by_block)
{
bool ret = true;
@@ -943,6 +953,17 @@ namespace cryptonote
}
rvv.push_back(&rv); // delayed batch verification
break;
+ case rct::RCTTypeBulletproofPlus:
+ if (!is_canonical_bulletproof_plus_layout(rv.p.bulletproofs_plus))
+ {
+ MERROR_VER("Bulletproof_plus does not have canonical form");
+ set_semantics_failed(tx_info[n].tx_hash);
+ tx_info[n].tvc.m_verifivation_failed = true;
+ tx_info[n].result = false;
+ break;
+ }
+ rvv.push_back(&rv); // delayed batch verification
+ break;
default:
MERROR_VER("Unknown rct type: " << rv.type);
set_semantics_failed(tx_info[n].tx_hash);
@@ -960,7 +981,7 @@ namespace cryptonote
{
if (!tx_info[n].result)
continue;
- if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeCLSAG)
+ if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeCLSAG && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproofPlus)
continue;
if (assumed_bad || !rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures))
{