diff --git a/src/common/crypto_serialization.h b/src/common/crypto_serialization.h index 56bdaadd..a5b5bd6c 100644 --- a/src/common/crypto_serialization.h +++ b/src/common/crypto_serialization.h @@ -204,6 +204,26 @@ namespace crypto END_BOOST_SERIALIZATION() }; + struct BGE_proof_s : public BGE_proof + { + BEGIN_SERIALIZE_OBJECT() + FIELD(A) + FIELD(B) + FIELD(Pk) + FIELD_N("f", (std::vector&)(f)) + FIELD(y) + FIELD(z) + END_SERIALIZE() + + BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(A) + BOOST_SERIALIZE(B) + BOOST_SERIALIZE(Pk) + BOOST_SERIALIZE(f) + BOOST_SERIALIZE(y) + BOOST_SERIALIZE(z) + END_BOOST_SERIALIZATION() + }; } // namespace crypto diff --git a/src/currency_core/blockchain_storage.cpp b/src/currency_core/blockchain_storage.cpp index 59b0dd16..5af4b705 100644 --- a/src/currency_core/blockchain_storage.cpp +++ b/src/currency_core/blockchain_storage.cpp @@ -1323,9 +1323,10 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t if (is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM)) // TODO @#@# consider moving to validate_tx_for_hardfork_specific_terms { CHECK_AND_ASSERT_MES(b.miner_tx.attachment.empty(), false, "coinbase transaction has attachments; attachments are not allowed for coinbase transactions."); - CHECK_AND_ASSERT_MES(b.miner_tx.proofs.size() == 2, false, "coinbase transaction has incorrect number of proofs (" << b.miner_tx.proofs.size() << "), expected 2"); - CHECK_AND_ASSERT_MES(b.miner_tx.proofs[0].type() == typeid(zc_outs_range_proof), false, "coinbase transaction has incorrect type of proof #0 (expected: zc_outs_range_proof)"); - CHECK_AND_ASSERT_MES(b.miner_tx.proofs[1].type() == typeid(zc_balance_proof), false, "coinbase transaction has incorrect type of proof #1 (expected: zc_balance_proof)"); + CHECK_AND_ASSERT_MES(b.miner_tx.proofs.size() == 3, false, "coinbase transaction has incorrect number of proofs (" << b.miner_tx.proofs.size() << "), expected 2"); + CHECK_AND_ASSERT_MES(b.miner_tx.proofs[0].type() == typeid(zc_asset_surjection_proof), false, "coinbase transaction has incorrect type of proof #0 (expected: zc_asset_surjection_proof)"); + CHECK_AND_ASSERT_MES(b.miner_tx.proofs[1].type() == typeid(zc_outs_range_proof), false, "coinbase transaction has incorrect type of proof #1 (expected: zc_outs_range_proof)"); + CHECK_AND_ASSERT_MES(b.miner_tx.proofs[2].type() == typeid(zc_balance_proof), false, "coinbase transaction has incorrect type of proof #2 (expected: zc_balance_proof)"); } else { diff --git a/src/currency_core/currency_basic.h b/src/currency_core/currency_basic.h index d80c2588..be786d59 100644 --- a/src/currency_core/currency_basic.h +++ b/src/currency_core/currency_basic.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2019 Zano Project +// Copyright (c) 2014-2023 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2014-2015 The Boolberry developers @@ -434,37 +434,17 @@ namespace currency struct zc_asset_surjection_proof { - std::vector bge_proofs; // one per output, non-aggregated version of Groth-Bootle-Esgin yet, need to be upgraded later -- sowle + std::vector bge_proofs; // one per output, non-aggregated version of Groth-Bootle-Esgin yet, need to be upgraded later -- sowle BEGIN_SERIALIZE_OBJECT() + FIELD(bge_proofs) END_SERIALIZE() BEGIN_BOOST_SERIALIZATION() + BOOST_SERIALIZE(bge_proofs) END_BOOST_SERIALIZATION() }; - /* - // each output has another amount commitment using generators U and G for range proof aggregation - struct zc_out_range_proof_aggregation_item - { - crypto::public_key amount_commitment_for_range_proof; // U = e_j * U + y'_j * G - crypto::scalar_t y0; // linear proof scalars - crypto::scalar_t y1; - - BEGIN_SERIALIZE_OBJECT() - FIELD(amount_commitment_for_range_proof) - FIELD(y0) - FIELD(y1) - END_SERIALIZE() - - BEGIN_BOOST_SERIALIZATION() - BOOST_SERIALIZE(amount_commitment_for_range_proof) - BOOST_SERIALIZE(y0) - BOOST_SERIALIZE(y1) - END_BOOST_SERIALIZATION() - }; - */ - // non-consoditated txs must have one of this objects in the attachments (elements count == vout.size()) // consolidated -- one pre consolidated part (sum(elements count) == vout.size()) struct zc_outs_range_proof diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index a7c47a36..a66816da 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018 Zano Project +// Copyright (c) 2014-2023 Zano Project // Copyright (c) 2014-2018 The Louisdor Project // Copyright (c) 2012-2013 The Cryptonote developers // Copyright (c) 2012-2013 The Boolberry developers @@ -122,8 +122,8 @@ namespace currency crypto::scalar_t secret = ogc.pseudo_outs_plus_real_out_blinding_masks[secret_index] - ogc.asset_id_blinding_masks[j]; - result.bge_proofs.emplace_back(crypto::BGE_proof{}); - r = crypto::generate_BGE_proof(context_hash, ring, secret, secret_index, result.bge_proofs.back()); + result.bge_proofs.emplace_back(crypto::BGE_proof_s{}); + r = crypto::generate_BGE_proof(context_hash, ring, secret, secret_index, result.bge_proofs.back()); CHECK_AND_ASSERT_MES(r, false, ""); } @@ -441,12 +441,19 @@ namespace currency // tx hash should be sealed by now crypto::hash tx_id = get_transaction_hash(tx); - //add range proofs - currency::zc_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); - bool r = generate_zc_outs_range_proof(tx_id, 0, outs_gen_context, tx.vout, range_proofs); + // asset surjection proof + currency::zc_asset_surjection_proof asp{}; + bool r = generate_asset_surjection_proof(tx_id, true, outs_gen_context, asp); + CHECK_AND_ASSERT_MES(r, false, "generete_asset_surjection_proof failed"); + tx.proofs.emplace_back(std::move(asp)); + + // range proofs + currency::zc_outs_range_proof range_proofs{}; + r = generate_zc_outs_range_proof(tx_id, 0, outs_gen_context, tx.vout, range_proofs); CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()"); tx.proofs.emplace_back(std::move(range_proofs)); + // balance proof currency::zc_balance_proof balance_proof{}; r = generate_tx_balance_proof(tx, tx_id, outs_gen_context, block_reward, balance_proof); CHECK_AND_ASSERT_MES(r, false, "generate_tx_balance_proof failed"); @@ -2309,8 +2316,8 @@ namespace currency CHECK_AND_ASSERT_MES(r, false, "generete_asset_surjection_proof failed"); tx.proofs.emplace_back(std::move(asp)); - // add range proofs - currency::zc_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); + // range proofs + currency::zc_outs_range_proof range_proofs{}; r = generate_zc_outs_range_proof(tx_prefix_hash, range_proof_start_index, outs_gen_context, tx.vout, range_proofs); CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()"); tx.proofs.emplace_back(std::move(range_proofs)); diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 492962c2..1459a885 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -229,7 +229,8 @@ namespace currency }; bool verify_multiple_zc_outs_range_proofs(const std::vector& range_proofs); - bool generate_tx_balance_proof(const transaction &tx, const crypto::hash& tx_id, const outputs_generation_context& ogc, uint64_t block_reward_for_miner_tx, currency::zc_balance_proof& proof); + bool generate_asset_surjection_proof(const crypto::hash& context_hash, bool has_non_zc_inputs, outputs_generation_context& ogc, zc_asset_surjection_proof& result); + bool generate_tx_balance_proof(const transaction &tx, const crypto::hash& tx_id, const outputs_generation_context& ogc, uint64_t block_reward_for_miner_tx, zc_balance_proof& proof); bool generate_zc_outs_range_proof(const crypto::hash& context_hash, size_t out_index_start, const outputs_generation_context& outs_gen_context, const std::vector& vouts, zc_outs_range_proof& result); bool check_tx_bare_balance(const transaction& tx, uint64_t additional_inputs_amount_and_fees_for_mining_tx = 0); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a9fdb9fa..660ee41b 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -4000,12 +4000,12 @@ bool wallet2::prepare_and_sign_pos_block(const mining_context& cxt, currency::bl // asset surjection proof currency::zc_asset_surjection_proof asp{}; - //r = generate_asset_surjection_proof(miner_tx_id, miner_tx_ogc, asp); - //CHECK_AND_ASSERT_MES(r, false, "generete_asset_surjection_proof failed"); + r = generate_asset_surjection_proof(miner_tx_id, false, miner_tx_ogc, asp); // has_non_zc_inputs == false because after the HF4 PoS mining is only allowed for ZC stakes inputs + WLT_CHECK_AND_ASSERT_MES(r, false, "generete_asset_surjection_proof failed"); b.miner_tx.proofs.emplace_back(std::move(asp)); // range proofs - currency::zc_outs_range_proof range_proofs = AUTO_VAL_INIT(range_proofs); + currency::zc_outs_range_proof range_proofs{}; r = generate_zc_outs_range_proof(miner_tx_id, 0, miner_tx_ogc, b.miner_tx.vout, range_proofs); WLT_CHECK_AND_ASSERT_MES(r, false, "Failed to generate zc_outs_range_proof()"); b.miner_tx.proofs.emplace_back(std::move(range_proofs));