diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 13ae5b19e..1bfeb903d 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -646,7 +646,7 @@ namespace cryptonote { CHECK_AND_ASSERT_MES(tx.pruned, std::numeric_limits::max(), "get_pruned_transaction_weight does not support non pruned txes"); CHECK_AND_ASSERT_MES(tx.version >= 2, std::numeric_limits::max(), "get_pruned_transaction_weight does not support v1 txes"); - CHECK_AND_ASSERT_MES(tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus || tx.rct_signatures.type == rct::RCTTypeFullProofs, + CHECK_AND_ASSERT_MES(tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus || tx.rct_signatures.type == rct::RCTTypeFullProofs || tx.rct_signatures.type == rct::RCTTypeSalviumZero || tx.rct_signatures.type == rct::RCTTypeSalviumOne, std::numeric_limits::max(), "Unsupported rct_signatures type in get_pruned_transaction_weight"); CHECK_AND_ASSERT_MES(!tx.vin.empty(), std::numeric_limits::max(), "empty vin"); CHECK_AND_ASSERT_MES(tx.vin[0].type() == typeid(cryptonote::txin_to_key), std::numeric_limits::max(), "empty vin"); diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 1d26853c2..fb3360b4f 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -3605,10 +3605,26 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context } */ - if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { - // for v5, force the audit and the new SalviumOne RCT data + if (hf_version >= HF_VERSION_CARROT) { + // from v11, force the new SalviumOne RCT data if (tx.type == cryptonote::transaction_type::TRANSFER || tx.type == cryptonote::transaction_type::STAKE || tx.type == cryptonote::transaction_type::BURN || tx.type == cryptonote::transaction_type::CONVERT || tx.type == cryptonote::transaction_type::AUDIT) { if (tx.rct_signatures.type != rct::RCTTypeSalviumOne) { + MERROR_VER("SalviumOne data required after v" + std::to_string(HF_VERSION_CARROT)); + tvc.m_invalid_output = true; + return false; + } + } else { + if (tx.rct_signatures.type != rct::RCTTypeNull) { + MERROR_VER("NULL RCT required for coinbase TXs after v" + std::to_string(HF_VERSION_CARROT)); + tvc.m_invalid_output = true; + return false; + } + } + + else if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { + // for v5, force the audit and the new SalviumZero RCT data + if (tx.type == cryptonote::transaction_type::TRANSFER || tx.type == cryptonote::transaction_type::STAKE || tx.type == cryptonote::transaction_type::BURN || tx.type == cryptonote::transaction_type::CONVERT || tx.type == cryptonote::transaction_type::AUDIT) { + if (tx.rct_signatures.type != rct::RCTTypeSalviumZero) { MERROR_VER("FullProofs plus Audit data required after v" + std::to_string(HF_VERSION_SALVIUM_ONE_PROOFS)); tvc.m_invalid_output = true; return false; @@ -3748,7 +3764,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 || rv.type == rct::RCTTypeBulletproofPlus || rv.type == rct::RCTTypeFullProofs || rv.type == rct::RCTTypeSalviumOne) + else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG || rv.type == rct::RCTTypeBulletproofPlus || rv.type == rct::RCTTypeFullProofs || rv.type == rct::RCTTypeSalviumZero || rv.type == rct::RCTTypeSalviumOne) { CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys"); rv.mixRing.resize(pubkeys.size()); @@ -4098,8 +4114,13 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, const rct::rctSig &rv = tx.rct_signatures; // Check that after full proofs are enabled, the RCT version is set to enforce full proofs - if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { + if (hf_version >= HF_VERSION_CARROT) { if (rv.type != rct::RCTTypeNull && rv.type != rct::RCTTypeSalviumOne) { + MERROR_VER("Unsupported rct type (Salvium One / SPARC proofs are required): " << rv.type); + return false; + } + } else if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { + if (rv.type != rct::RCTTypeNull && rv.type != rct::RCTTypeSalviumZero) { MERROR_VER("Unsupported rct type (full proofs (with audit data) are required): " << rv.type); return false; } @@ -4123,6 +4144,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, case rct::RCTTypeCLSAG: case rct::RCTTypeBulletproofPlus: case rct::RCTTypeFullProofs: + case rct::RCTTypeSalviumZero: case rct::RCTTypeSalviumOne: { if (!ver_rct_non_semantics_simple_cached(tx, pubkeys, m_rct_ver_cache, RCT_CACHE_TYPE, hf_version)) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 6cb1a3ecb..9830b48d6 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -924,7 +924,7 @@ namespace cryptonote continue; const rct::rctSig &rv = tx_info[n].tx->rct_signatures; const uint8_t hf_version = m_blockchain_storage.get_current_hard_fork_version(); - if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { + if (hf_version >= HF_VERSION_CARROT) { if (rv.type != rct::RCTTypeNull && rv.type != rct::RCTTypeSalviumOne) { MERROR_VER("Invalid RCT type provided"); set_semantics_failed(tx_info[n].tx_hash); @@ -932,6 +932,14 @@ namespace cryptonote tx_info[n].result = false; return false; } + } else if (hf_version >= HF_VERSION_SALVIUM_ONE_PROOFS) { + if (rv.type != rct::RCTTypeNull && rv.type != rct::RCTTypeSalviumZero) { + MERROR_VER("Invalid RCT type provided"); + set_semantics_failed(tx_info[n].tx_hash); + tx_info[n].tvc.m_verifivation_failed = true; + tx_info[n].result = false; + return false; + } } else if (hf_version >= HF_VERSION_ENFORCE_FULL_PROOFS) { if (rv.type != rct::RCTTypeNull && rv.type != rct::RCTTypeFullProofs) { MERROR_VER("Invalid RCT type provided"); @@ -990,6 +998,7 @@ namespace cryptonote break; case rct::RCTTypeBulletproofPlus: case rct::RCTTypeFullProofs: + case rct::RCTTypeSalviumZero: case rct::RCTTypeSalviumOne: if (!is_canonical_bulletproof_plus_layout(rv.p.bulletproofs_plus)) { @@ -1017,7 +1026,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 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproofPlus && tx_info[n].tx->rct_signatures.type != rct::RCTTypeFullProofs && tx_info[n].tx->rct_signatures.type != rct::RCTTypeSalviumOne) + 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 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeFullProofs && tx_info[n].tx->rct_signatures.type != rct::RCTTypeSalviumZero && tx_info[n].tx->rct_signatures.type != rct::RCTTypeSalviumOne) continue; if (!rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures, tx_info[n].tx->type == cryptonote::transaction_type::BURN ? tx_info[n].tx->amount_burnt : diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 32eafd653..16bd7972e 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -1930,7 +1930,7 @@ namespace hw { // ====== Aout, Bout, AKout, C, v, k ====== kv_offset = data_offset; - if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG || type==rct::RCTTypeBulletproofPlus || type==rct::RCTTypeFullProofs) { + if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG || type==rct::RCTTypeBulletproofPlus || type==rct::RCTTypeFullProofs || type==rct::RCTTypeSalviumZero || type==rct::RCTTypeSalviumOne) { C_offset = kv_offset+ (8)*outputs_size; } else { C_offset = kv_offset+ (32+32)*outputs_size; @@ -1947,7 +1947,7 @@ namespace hw { offset = set_command_header(INS_VALIDATE, 0x02, i+1); //options this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ; - this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG || type==rct::RCTTypeBulletproofPlus || type==rct::RCTTypeFullProofs)?0x02:0x00; + this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG || type==rct::RCTTypeBulletproofPlus || type==rct::RCTTypeFullProofs || type==rct::RCTTypeSalviumZero || type==rct::RCTTypeSalviumOne)?0x02:0x00; offset += 1; //is_subaddress this->buffer_send[offset] = outKeys.is_subaddress; @@ -1968,7 +1968,7 @@ namespace hw { memmove(this->buffer_send+offset, data+C_offset,32); offset += 32; C_offset += 32; - if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG || type==rct::RCTTypeBulletproofPlus || type==rct::RCTTypeFullProofs) { + if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG || type==rct::RCTTypeBulletproofPlus || type==rct::RCTTypeFullProofs || type==rct::RCTTypeSalviumZero || type==rct::RCTTypeSalviumOne) { //k memset(this->buffer_send+offset, 0, 32); offset += 32; diff --git a/src/multisig/multisig_tx_builder_ringct.cpp b/src/multisig/multisig_tx_builder_ringct.cpp index f9a510a69..091fdeeff 100644 --- a/src/multisig/multisig_tx_builder_ringct.cpp +++ b/src/multisig/multisig_tx_builder_ringct.cpp @@ -857,6 +857,8 @@ static bool set_tx_rct_signatures( rv.type = rct::RCTTypeBulletproofPlus; else if (rct_config.bp_version == 5) rv.type = rct::RCTTypeFullProofs; + else if (rct_config.bp_version == 6) + rv.type = rct::RCTTypeSalviumZero; else return false; rv.txnFee = fee; @@ -934,7 +936,7 @@ static bool set_tx_rct_signatures( } sc_sub(difference.bytes, sumpouts.bytes, sumouts.bytes); rct::genC(rv.p_r, difference, 0); - if (rv.type == rct::RCTTypeFullProofs || rv.type == rct::RCTTypeSalviumOne) { + if (rv.type == rct::RCTTypeFullProofs || rv.type == rct::RCTTypeSalviumZero || rv.type == rct::RCTTypeSalviumOne) { rv.salvium_data.pr_proof = rct::PRProof_Gen(difference); #ifdef DBG CHECK_AND_ASSERT_THROW_MES(rct::PRProof_Ver(rv.p_r, rv.salvium_data.pr_proof), "PRProof_Ver() failed on recently created proof"); @@ -954,7 +956,7 @@ static bool set_tx_rct_signatures( // check balance if reconstructing the tx else { rv.p.pseudoOuts = unsigned_tx.rct_signatures.p.pseudoOuts; - if (rv.type == rct::RCTTypeFullProofs || rv.type == rct::RCTTypeSalviumOne) { + if (rv.type == rct::RCTTypeFullProofs || rv.type == rct::RCTTypeSalviumZero || rv.type == rct::RCTTypeSalviumOne) { if (!rct::PRProof_Ver(unsigned_tx.rct_signatures.p_r, unsigned_tx.rct_signatures.salvium_data.pr_proof)) return false; rv.p_r = unsigned_tx.rct_signatures.p_r; diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index 866d8b80e..465913fb8 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -1579,7 +1579,7 @@ namespace rct { DP(rv.p_r); // set salvium_data - if (rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumZero || rv.type == RCTTypeSalviumOne) { + if (rv.type == RCTTypeSalviumOne) { rv.salvium_data.pr_proof = PRProof_Gen(difference); #ifdef DBG CHECK_AND_ASSERT_THROW_MES(PRProof_Ver(rv.p_r, rv.salvium_data.pr_proof), "PRProof_Ver() failed on recently created proof"); diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index 286f7eddd..6942c0e82 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -1201,7 +1201,7 @@ void toJsonValue(rapidjson::Writer& dest, const rct::rctSig& INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask)); INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee); INSERT_INTO_JSON_OBJECT(dest, p_r, sig.p_r); - if (sig.type == rct::RCTTypeSalviumOne) { + if (sig.type == rct::RCTTypeSalviumZero || sig.type == rct::RCTTypeSalviumOne) { INSERT_INTO_JSON_OBJECT(dest, salvium_data, sig.salvium_data); } else if (sig.type == rct::RCTTypeFullProofs) { INSERT_INTO_JSON_OBJECT(dest, pr_proof, sig.salvium_data.pr_proof); @@ -1245,7 +1245,7 @@ void fromJsonValue(const rapidjson::Value& val, rct::rctSig& sig) GET_FROM_JSON_OBJECT(val, sig.outPk, commitments); GET_FROM_JSON_OBJECT(val, sig.txnFee, fee); GET_FROM_JSON_OBJECT(val, sig.p_r, p_r); - if (sig.type == rct::RCTTypeSalviumOne) { + if (sig.type == rct::RCTTypeSalviumZero || sig.type == rct::RCTTypeSalviumOne) { GET_FROM_JSON_OBJECT(val, sig.salvium_data, salvium_data); } else if (sig.type == rct::RCTTypeFullProofs) { GET_FROM_JSON_OBJECT(val, sig.salvium_data.pr_proof, pr_proof); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9634626b3..3fc05d34d 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -13541,7 +13541,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr crypto::secret_key shared_secret; crypto::derivation_to_scalar(derivation, proof.index_in_tx, shared_secret); rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[proof.index_in_tx]; - rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret), tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus || tx.rct_signatures.type == rct::RCTTypeFullProofs || tx.rct_signatures.type == rct::RCTTypeSalviumOne); + rct::ecdhDecode(ecdh_info, rct::sk2rct(shared_secret), tx.rct_signatures.type == rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG || tx.rct_signatures.type == rct::RCTTypeBulletproofPlus || tx.rct_signatures.type == rct::RCTTypeFullProofs || tx.rct_signatures.type == rct::RCTTypeSalviumZero || tx.rct_signatures.type == rct::RCTTypeSalviumOne); amount = rct::h2d(ecdh_info.amount); } total += amount;