diff --git a/src/common/va_args.h b/src/common/va_args.h new file mode 100644 index 0000000000..3389b1cb96 --- /dev/null +++ b/src/common/va_args.h @@ -0,0 +1,45 @@ +// Copyright (c) 2024, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#pragma once + +// Check for __VA_OPT__ support +// Apdated from cpplearner's StackOverflow answer: https://stackoverflow.com/a/48045656 +#define PP_THIRD_ARG(a,b,c,...) c +#define VA_OPT_SUPPORTED_I(...) PP_THIRD_ARG(__VA_OPT__(,),true,false,) +#define VA_OPT_SUPPORTED VA_OPT_SUPPORTED_I(?) + +// VA_ARGS_COMMAPREFIX(): VA_ARGS_COMMAPREFIX(__VA_ARGS__) expands to __VA_ARGS__ with a comma in +// front if more than one argument, else nothing. +// If __VA_OPT__ supported, use that. Else, use GCC's ,## hack +#if VA_OPT_SUPPORTED +# define VA_ARGS_COMMAPREFIX(...) __VA_OPT__(,) __VA_ARGS__ +#else +# define VA_ARGS_COMMAPREFIX(...) , ## __VA_ARGS__ +#endif + diff --git a/src/seraphis_impl/CMakeLists.txt b/src/seraphis_impl/CMakeLists.txt index 12413cbda8..bee0f2ca75 100644 --- a/src/seraphis_impl/CMakeLists.txt +++ b/src/seraphis_impl/CMakeLists.txt @@ -34,7 +34,6 @@ set(seraphis_impl_sources legacy_ki_import_tool.cpp scan_ledger_chunk_async.cpp scan_process_basic.cpp - serialization_demo_utils.cpp tx_builder_utils.cpp tx_fee_calculator_squashed_v1.cpp tx_input_selection_output_context_v1.cpp) diff --git a/src/seraphis_impl/seraphis_serialization.h b/src/seraphis_impl/seraphis_serialization.h new file mode 100644 index 0000000000..02a8d7901f --- /dev/null +++ b/src/seraphis_impl/seraphis_serialization.h @@ -0,0 +1,294 @@ +// Copyright (c) 2024, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Serialization implementations for seraphis transaction components and transactions. + +#pragma once + +//local headers +#include "crypto/crypto.h" +#include "crypto/x25519.h" +#include "ringct/rctTypes.h" +#include "seraphis_core/discretized_fee.h" +#include "seraphis_core/jamtis_destination.h" +#include "seraphis_core/jamtis_support_types.h" +#include "seraphis_crypto/math_utils.h" +#include "seraphis_crypto/sp_legacy_proof_helpers.h" +#include "serialization/containers.h" +#include "serialization/crypto.h" +#include "serialization/serialization.h" +#include "seraphis_main/txtype_coinbase_v1.h" +#include "seraphis_main/txtype_squashed_v1.h" + +//third party headers + +//standard headers + +//forward declarations + +namespace sp +{ +namespace serialization +{ +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +template class Archive, typename ValueType, typename... Args> +bool do_serialize_vec_exact(Archive &ar, std::vector &v, const size_t implied_size, + Args&&... args) +{ + // sanity check: there cannot be more elements remaining than bytes + if constexpr (!W) + { + if (implied_size > ar.remaining_bytes()) + return false; + } + + if (v.size() != implied_size) + { + if constexpr (W) + return false; + else + v.resize(implied_size); + } + + ar.begin_array(); + + // Serialize each element + for (size_t i{0}; i < v.size(); ++i) + { + if (i) + ar.delimit_array(); + if (!do_serialize(ar, v[i], args...)) + return false; + } + + ar.end_array(); + return ar.good(); +} +} // namespace serialization +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +#define VEC_FIELD_EXACT_F(f, s, ...) \ + do { \ + ar.tag(#f); \ + const bool dsve_res{::sp::serialization::do_serialize_vec_exact( \ + ar, v.f, s VA_ARGS_COMMAPREFIX(__VA_ARGS__))}; \ + if (!dsve_res || !ar.good()) return false; \ + } while (0); +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +#define VEC_FIELD_OPT_EXACT_F(f, s, ...) \ + if (s == SIZE_MAX) \ + FIELD_F(f) \ + else if (s < 1024) \ + VEC_FIELD_EXACT_F(f, s) \ + else \ + return false; +//-------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_FN(DiscretizedFee) + static_assert(sizeof(v.fee_encoding) == 1, "should use a varint if int size != 1"); + FIELDS(v.fee_encoding) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpCoinbaseEnoteCore) + FIELD_F(onetime_address) + VARINT_FIELD_F(amount) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpEnoteCore) + FIELD_F(onetime_address) + FIELD_F(amount_commitment) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpEnoteImageCore) + FIELD_F(masked_address) + FIELD_F(masked_commitment) + FIELD_F(key_image) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(BulletproofPlus2Proof, const size_t implied_lr_size = SIZE_MAX) + FIELD_F(A) + FIELD_F(A1) + FIELD_F(B) + FIELD_F(r1) + FIELD_F(s1) + FIELD_F(d1) + VEC_FIELD_OPT_EXACT_F(L, implied_lr_size) + VEC_FIELD_OPT_EXACT_F(R, implied_lr_size) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(LegacyClsagProof, const size_t implied_s_size = SIZE_MAX) + VEC_FIELD_OPT_EXACT_F(s, implied_s_size) + FIELD_F(c1) + FIELD_F(D) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpCompositionProof) + FIELD_F(c) + FIELD_F(r_t1) + FIELD_F(r_t2) + FIELD_F(r_ki) + FIELD_F(K_t1) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(GrootleProof) + FIELD_F(A) + FIELD_F(B) + FIELD_F(f) // @TODO: sizeless f serialization + FIELD_F(X) // @TODO: sizeless X serialization + FIELD_F(zA) + FIELD_F(z) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(LegacyEnoteImageV2) + FIELD_F(masked_commitment) + FIELD_F(key_image) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpEnoteImageV1) + FIELD_F(core) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpCoinbaseEnoteV1) + FIELD_F(core) + FIELD_F(addr_tag_enc) + VARINT_FIELD_F(view_tag) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpEnoteV1) + FIELD_F(core) + FIELD_F(encoded_amount) + FIELD_F(addr_tag_enc) + VARINT_FIELD_F(view_tag) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpBalanceProofV1, const size_t implied_lr_size = SIZE_MAX) + FIELD_F(bpp2_proof, implied_lr_size) + FIELD_F(remainder_blinding_factor) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(LegacyRingSignatureV4, const size_t implied_ring_size = SIZE_MAX) + FIELD_F(clsag_proof, implied_ring_size) + // @TODO: accumlate/decumulate CLSAG ref set offsets + VEC_FIELD_OPT_EXACT_F(reference_set, implied_ring_size) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpImageProofV1) + // @TODO: sizeless f, X serialization + FIELD_F(composition_proof) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpMembershipProofV1, const size_t implied_num_bins = SIZE_MAX) + FIELD_F(grootle_proof) + VEC_FIELD_OPT_EXACT_F(bin_loci, implied_num_bins) + VARINT_FIELD_F(bin_rotation_factor) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpTxSupplementV1, const size_t implied_num_outputs = SIZE_MAX) + const size_t implied_num_ephem_pubkeys{(2 == implied_num_outputs) ? 1 : implied_num_outputs}; + VEC_FIELD_OPT_EXACT_F(output_enote_ephemeral_pubkeys, implied_num_ephem_pubkeys) + FIELD_F(tx_extra) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpTxCoinbaseV1) + VARINT_FIELD_F(tx_semantic_rules_version) + VARINT_FIELD_F(block_height) + FIELD_F(outputs) + FIELD_F(tx_supplement, v.outputs.size()) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(SpTxSquashedV1) + VARINT_FIELD_F(tx_semantic_rules_version) + + FIELD_F(legacy_input_images) + FIELD_F(sp_input_images) + FIELD_F(outputs) + + const size_t num_legacy_inputs = v.legacy_input_images.size(); + const size_t num_sp_inputs = v.sp_input_images.size(); + const size_t num_outputs = v.outputs.size(); + const size_t num_range_proofs = num_sp_inputs + num_outputs; + const size_t implied_bpp_lr_size = bpp_lr_length(num_range_proofs); + + FIELD_F(balance_proof, implied_bpp_lr_size) + + size_t clsag_ring_size = v.legacy_ring_signatures.size() ? + v.legacy_ring_signatures[0].reference_set.size() : 0; + VARINT_FIELD(clsag_ring_size) + + VEC_FIELD_EXACT_F(legacy_ring_signatures, num_legacy_inputs, clsag_ring_size) + VEC_FIELD_EXACT_F(sp_image_proofs, num_sp_inputs) + + // we can skip storing # of bins by calcing (n^m)/num_bin_members if using static config + size_t num_bins{SIZE_MAX}; + if (v.tx_semantic_rules_version != SpTxSquashedV1::SemanticRulesVersion::MOCK) + { + const SemanticConfigSpRefSetV1 sp_ref_set_config{ + static_semantic_config_sp_ref_sets_v1(v.tx_semantic_rules_version) + }; + num_bins = math::uint_pow(sp_ref_set_config.decomp_n, sp_ref_set_config.decomp_m) + / sp_ref_set_config.num_bin_members; + } + + VEC_FIELD_EXACT_F(sp_membership_proofs, num_sp_inputs, num_bins) + FIELD_F(tx_supplement, num_outputs) + FIELD_F(tx_fee) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +namespace jamtis +{ +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(JamtisDestinationV1) + FIELD_F(addr_K1) + FIELD_F(addr_K2) + FIELD_F(addr_K3) + FIELD_F(addr_tag) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(JamtisPaymentProposalV1) + FIELD_F(destination) + FIELD_F(amount) + FIELD_F(enote_ephemeral_privkey) + FIELD_F(partial_memo) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +BEGIN_SERIALIZE_OBJECT_FN(JamtisPaymentProposalSelfSendV1) + FIELD_F(destination) + FIELD_F(amount) + VARINT_FIELD_F(type) + FIELD_F(enote_ephemeral_privkey) + FIELD_F(partial_memo) +END_SERIALIZE() +//-------------------------------------------------------------------------------------------------- +} // namespace jamtis +} // namespace sp + +BLOB_SERIALIZER(sp::jamtis::address_index_t); +BLOB_SERIALIZER(sp::jamtis::address_tag_t); +BLOB_SERIALIZER(sp::jamtis::encoded_amount_t); diff --git a/src/seraphis_impl/serialization_demo_types.h b/src/seraphis_impl/serialization_demo_types.h deleted file mode 100644 index 5180543521..0000000000 --- a/src/seraphis_impl/serialization_demo_types.h +++ /dev/null @@ -1,465 +0,0 @@ -// Copyright (c) 2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Serializable types for seraphis transaction components and transactions (a demonstration). - -#pragma once - -//local headers -#include "crypto/crypto.h" -#include "crypto/x25519.h" -#include "ringct/rctTypes.h" -#include "seraphis_core/discretized_fee.h" -#include "seraphis_core/jamtis_destination.h" -#include "seraphis_core/jamtis_support_types.h" -#include "serialization/containers.h" -#include "serialization/crypto.h" -#include "serialization/serialization.h" -#include "seraphis_main/txtype_coinbase_v1.h" -#include "seraphis_main/txtype_squashed_v1.h" - -//third party headers - -//standard headers -#include - -//forward declarations - - -namespace sp -{ -namespace serialization -{ -/// serializable jamtis::address_index_t -struct ser_address_index_t final -{ - unsigned char bytes[sizeof(jamtis::address_index_t)]; -}; - -/// serializable jamtis::address_tag_t -struct ser_address_tag_t final -{ - unsigned char bytes[sizeof(jamtis::address_tag_t)]; -}; - -/// serializable jamtis::encrypted_address_tag_t -struct ser_encrypted_address_tag_t final -{ - unsigned char bytes[sizeof(jamtis::encrypted_address_tag_t)]; -}; - -/// serializable jamtis::encoded_amount_t -struct ser_encoded_amount_t final -{ - unsigned char bytes[sizeof(jamtis::encoded_amount_t)]; -}; - -/// serializable SpCoinbaseEnoteCore -struct ser_SpCoinbaseEnoteCore final -{ - /// Ko - rct::key onetime_address; - /// a - rct::xmr_amount amount; - - BEGIN_SERIALIZE() - FIELD(onetime_address) - VARINT_FIELD(amount) - END_SERIALIZE() -}; - -/// serializable SpEnoteCore -struct ser_SpEnoteCore final -{ - /// Ko - rct::key onetime_address; - /// C - rct::key amount_commitment; - - BEGIN_SERIALIZE() - FIELD(onetime_address) - FIELD(amount_commitment) - END_SERIALIZE() -}; - -/// serializable SpEnoteImageCore -struct ser_SpEnoteImageCore final -{ - /// K" - rct::key masked_address; - /// C" - rct::key masked_commitment; - /// KI - crypto::key_image key_image; - - BEGIN_SERIALIZE() - FIELD(masked_address) - FIELD(masked_commitment) - FIELD(key_image) - END_SERIALIZE() -}; - -/// partially serializable BulletproofPlus2 -struct ser_BulletproofPlus2_PARTIAL final -{ - //rct::keyV V; (not serializable here) - rct::key A, A1, B; - rct::key r1, s1, d1; - rct::keyV L, R; - - BEGIN_SERIALIZE() - FIELD(A) - FIELD(A1) - FIELD(B) - FIELD(r1) - FIELD(s1) - FIELD(d1) - FIELD(L) - FIELD(R) - END_SERIALIZE() -}; - -/// serializable sp::LegacyClsagProof -struct ser_LegacyClsagProof final -{ - rct::keyV s; // scalars - rct::key c1; - rct::key D; // commitment key image - - BEGIN_SERIALIZE() - FIELD(s) - FIELD(c1) - FIELD(D) - END_SERIALIZE() -}; - -/// serializable SpCompositionProof -struct ser_SpCompositionProof final -{ - // challenge - rct::key c; - // responses - rct::key r_t1; - rct::key r_t2; - rct::key r_ki; - // intermediate proof key - rct::key K_t1; - - BEGIN_SERIALIZE() - FIELD(c) - FIELD(r_t1) - FIELD(r_t2) - FIELD(r_ki) - FIELD(K_t1) - END_SERIALIZE() -}; - -/// serializable GrootleProof -struct ser_GrootleProof final -{ - rct::key A; - rct::key B; - rct::keyM f; - rct::keyV X; - rct::key zA; - rct::key z; - - BEGIN_SERIALIZE() - FIELD(A) - FIELD(B) - FIELD(f) - FIELD(X) - FIELD(zA) - FIELD(z) - END_SERIALIZE() -}; - -/// serializable LegacyEnoteImageV2 -struct ser_LegacyEnoteImageV2 final -{ - /// masked commitment (aka 'pseudo-output commitment') - rct::key masked_commitment; - /// legacy key image - crypto::key_image key_image; - - BEGIN_SERIALIZE() - FIELD(masked_commitment) - FIELD(key_image) - END_SERIALIZE() -}; - -/// serializable SpEnoteImageV1 -struct ser_SpEnoteImageV1 final -{ - /// enote image core - ser_SpEnoteImageCore core; - - BEGIN_SERIALIZE() - FIELD(core) - END_SERIALIZE() -}; - -/// serializable SpCoinbaseEnoteV1 -struct ser_SpCoinbaseEnoteV1 final -{ - /// enote core (one-time address, amount commitment) - ser_SpCoinbaseEnoteCore core; - - /// addr_tag_enc - ser_encrypted_address_tag_t addr_tag_enc; - /// view_tag - unsigned char view_tag; - - BEGIN_SERIALIZE() - FIELD(core) - FIELD(addr_tag_enc) static_assert(sizeof(addr_tag_enc) == sizeof(jamtis::encrypted_address_tag_t), ""); - VARINT_FIELD(view_tag) static_assert(sizeof(view_tag) == sizeof(jamtis::view_tag_t), ""); - END_SERIALIZE() -}; - -/// serializable SpEnoteV1 -struct ser_SpEnoteV1 final -{ - /// enote core (one-time address, amount commitment) - ser_SpEnoteCore core; - - /// enc(a) - ser_encoded_amount_t encoded_amount; - /// addr_tag_enc - ser_encrypted_address_tag_t addr_tag_enc; - /// view_tag - unsigned char view_tag; - - BEGIN_SERIALIZE() - FIELD(core) - FIELD(encoded_amount) static_assert(sizeof(encoded_amount) == sizeof(jamtis::encoded_amount_t), ""); - FIELD(addr_tag_enc) static_assert(sizeof(addr_tag_enc) == sizeof(jamtis::encrypted_address_tag_t), ""); - VARINT_FIELD(view_tag) static_assert(sizeof(view_tag) == sizeof(jamtis::view_tag_t), ""); - END_SERIALIZE() -}; - -/// partially serializable SpBalanceProofV1 -struct ser_SpBalanceProofV1_PARTIAL final -{ - /// an aggregate set of BP+ proofs (partial serialization) - ser_BulletproofPlus2_PARTIAL bpp2_proof_PARTIAL; - /// the remainder blinding factor - rct::key remainder_blinding_factor; - - BEGIN_SERIALIZE() - FIELD(bpp2_proof_PARTIAL) - FIELD(remainder_blinding_factor) - END_SERIALIZE() -}; - -/// serializable LegacyRingSignatureV4 -struct ser_LegacyRingSignatureV4 final -{ - /// a clsag proof - ser_LegacyClsagProof clsag_proof; - /// on-chain indices of the proof's ring members (serializable as index offsets) - std::vector reference_set_COMPACT; - - BEGIN_SERIALIZE() - FIELD(clsag_proof) - FIELD(reference_set_COMPACT) - END_SERIALIZE() -}; - -/// serializable SpImageProofV1 -struct ser_SpImageProofV1 final -{ - /// a seraphis composition proof - ser_SpCompositionProof composition_proof; - - BEGIN_SERIALIZE() - FIELD(composition_proof) - END_SERIALIZE() -}; - -/// serializable SpMembershipProofV1 (does not include config info) -struct ser_SpMembershipProofV1 final -{ - /// a grootle proof - ser_GrootleProof grootle_proof; - /// binned representation of ledger indices of enotes referenced by the proof - std::vector bin_loci; - /// bin rotation factor (shared by all bins) - ref_set_bin_dimension_v1_t bin_rotation_factor; - - BEGIN_SERIALIZE() - FIELD(grootle_proof) - FIELD(bin_loci) - VARINT_FIELD(bin_rotation_factor) - END_SERIALIZE() -}; - -/// serializable SpTxSupplementV1 -struct ser_SpTxSupplementV1 final -{ - /// xKe: enote ephemeral pubkeys for outputs - std::vector output_enote_ephemeral_pubkeys; - /// tx memo - std::vector tx_extra; - - BEGIN_SERIALIZE() - FIELD(output_enote_ephemeral_pubkeys) - FIELD(tx_extra) - END_SERIALIZE() -}; - -/// serializable SpTxCoinbaseV1 -struct ser_SpTxCoinbaseV1 final -{ - /// semantic rules version - SpTxCoinbaseV1::SemanticRulesVersion tx_semantic_rules_version; - - /// height of the block whose block reward this coinbase tx disperses - std::uint64_t block_height; - /// tx outputs (new enotes) - std::vector outputs; - /// supplemental data for tx - ser_SpTxSupplementV1 tx_supplement; - - BEGIN_SERIALIZE() - VARINT_FIELD(tx_semantic_rules_version) - VARINT_FIELD(block_height) - FIELD(outputs) - FIELD(tx_supplement) - END_SERIALIZE() -}; - -/// serializable SpTxSquashedV1 -struct ser_SpTxSquashedV1 final -{ - /// semantic rules version - SpTxSquashedV1::SemanticRulesVersion tx_semantic_rules_version; - - /// legacy tx input images (spent legacy enotes) - std::vector legacy_input_images; - /// seraphis tx input images (spent seraphis enotes) - std::vector sp_input_images; - /// tx outputs (new enotes) - std::vector outputs; - /// balance proof (balance proof and range proofs) - ser_SpBalanceProofV1_PARTIAL balance_proof; - /// ring signature proofs: membership and ownership/key-image-legitimacy for each legacy input - std::vector legacy_ring_signatures; - /// composition proofs: ownership/key-image-legitimacy for each seraphis input - std::vector sp_image_proofs; - /// Grootle proofs on squashed enotes: membership for each seraphis input - std::vector sp_membership_proofs; - /// supplemental data for tx - ser_SpTxSupplementV1 tx_supplement; - /// the transaction fee (discretized representation) - unsigned char tx_fee; - - BEGIN_SERIALIZE() - VARINT_FIELD(tx_semantic_rules_version) - FIELD(legacy_input_images) - FIELD(sp_input_images) - FIELD(outputs) - FIELD(balance_proof) - FIELD(legacy_ring_signatures) - FIELD(sp_image_proofs) - FIELD(sp_membership_proofs) - FIELD(tx_supplement) - VARINT_FIELD(tx_fee) static_assert(sizeof(tx_fee) == sizeof(DiscretizedFee), ""); - END_SERIALIZE() -}; - -/// serializable JamtisDestinationV1 -struct ser_JamtisDestinationV1 final -{ - /// K_1 (address spend key) - rct::key addr_K1; - /// xK_2 (address view key) - crypto::x25519_pubkey addr_K2; - /// xK_3 (DH base key) - crypto::x25519_pubkey addr_K3; - /// addr_tag - ser_address_tag_t addr_tag; - - BEGIN_SERIALIZE() - FIELD(addr_K1) - FIELD(addr_K2) - FIELD(addr_K3) - FIELD(addr_tag) static_assert(sizeof(addr_tag) == sizeof(jamtis::address_tag_t), ""); - END_SERIALIZE() -}; - -/// serializable JamtisPaymentProposalV1 -struct ser_JamtisPaymentProposalV1 final -{ - /// destination address - ser_JamtisDestinationV1 destination; - /// amount - rct::xmr_amount amount; - /// enote ephemeral private key - crypto::x25519_scalar enote_ephemeral_privkey; - /// memo elements - std::vector partial_memo; - - BEGIN_SERIALIZE() - FIELD(destination) - FIELD(amount) - FIELD(enote_ephemeral_privkey) - FIELD(partial_memo) - END_SERIALIZE() -}; - -/// serializable JamtisPaymentProposalV1 -struct ser_JamtisPaymentProposalSelfSendV1 final -{ - /// destination address - ser_JamtisDestinationV1 destination; - /// amount - rct::xmr_amount amount; - /// selfspend type - unsigned char type; - /// enote ephemeral private key - crypto::x25519_scalar enote_ephemeral_privkey; - /// memo elements - std::vector partial_memo; - - BEGIN_SERIALIZE() - FIELD(destination) - FIELD(amount) - FIELD(type) - FIELD(enote_ephemeral_privkey) - FIELD(partial_memo) - END_SERIALIZE() -}; - -} //namespace serialization -} //namespace sp - -BLOB_SERIALIZER(sp::serialization::ser_address_index_t); -BLOB_SERIALIZER(sp::serialization::ser_address_tag_t); -BLOB_SERIALIZER(sp::serialization::ser_encrypted_address_tag_t); -BLOB_SERIALIZER(sp::serialization::ser_encoded_amount_t); diff --git a/src/seraphis_impl/serialization_demo_utils.cpp b/src/seraphis_impl/serialization_demo_utils.cpp deleted file mode 100644 index 0a8baf6eef..0000000000 --- a/src/seraphis_impl/serialization_demo_utils.cpp +++ /dev/null @@ -1,612 +0,0 @@ -// Copyright (c) 2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -//paired header -#include "serialization_demo_utils.h" - -//local headers -#include "common/container_helpers.h" -#include "crypto/crypto.h" -#include "ringct/rctOps.h" -#include "ringct/rctTypes.h" -#include "seraphis_core/discretized_fee.h" -#include "seraphis_core/jamtis_destination.h" -#include "seraphis_core/jamtis_payment_proposal.h" -#include "seraphis_core/jamtis_support_types.h" -#include "seraphis_crypto/bulletproofs_plus2.h" -#include "seraphis_crypto/grootle.h" -#include "seraphis_crypto/sp_composition_proof.h" -#include "seraphis_impl/serialization_demo_types.h" -#include "seraphis_main/tx_builders_inputs.h" -#include "seraphis_main/tx_component_types.h" -#include "seraphis_main/tx_component_types_legacy.h" -#include "seraphis_main/txtype_coinbase_v1.h" -#include "seraphis_main/txtype_squashed_v1.h" - -//third party headers - -//standard headers -#include - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "seraphis_impl" - -namespace sp -{ -namespace serialization -{ -//------------------------------------------------------------------------------------------------------------------- -// array2 copies array1 by invoking copy_func() on each element -//------------------------------------------------------------------------------------------------------------------- -template -static void copy_array(const CopyFuncT ©_func, const std::vector &array1, std::vector &array2_out) -{ - array2_out.clear(); - array2_out.reserve(array1.size()); - for (const Type1 &obj : array1) - copy_func(obj, tools::add_element(array2_out)); -} -//------------------------------------------------------------------------------------------------------------------- -// array2 consumes array1 by invoking relay_func() on each element -//------------------------------------------------------------------------------------------------------------------- -template -static void relay_array(const RelayFuncT &relay_func, std::vector &array1_in, std::vector &array2_out) -{ - array2_out.clear(); - array2_out.reserve(array1_in.size()); - for (Type1 &obj_in : array1_in) - relay_func(obj_in, tools::add_element(array2_out)); -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -static void indices_to_offsets(std::vector &indices_inout) -{ - if (indices_inout.size() == 0) - return; - - for (std::size_t i{indices_inout.size() - 1}; i != 0; --i) - indices_inout[i] -= indices_inout[i - 1]; -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -static void indices_from_offsets(std::vector &indices_inout) -{ - for (std::size_t i{1}; i < indices_inout.size(); ++i) - indices_inout[i] += indices_inout[i - 1]; -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -static void recover_legacy_ring_signatures_v4( - std::vector &serializable_legacy_ring_signatures_in, - const std::vector &legacy_enote_images, - std::vector &legacy_ring_signatures_out) -{ - CHECK_AND_ASSERT_THROW_MES(legacy_enote_images.size() == serializable_legacy_ring_signatures_in.size(), - "recovering legacy ring signature v4s: legacy input images don't line up with legacy ring signatures."); - - legacy_ring_signatures_out.clear(); - legacy_ring_signatures_out.reserve(serializable_legacy_ring_signatures_in.size()); - - for (std::size_t legacy_input_index{0}; legacy_input_index < legacy_enote_images.size(); ++legacy_input_index) - { - recover_legacy_ring_signature_v4(serializable_legacy_ring_signatures_in[legacy_input_index], - tools::add_element(legacy_ring_signatures_out)); - } -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -static void recover_sp_membership_proofs_v1( - std::vector &serializable_membership_proofs_in, - std::vector &membership_proofs_out) -{ - membership_proofs_out.clear(); - membership_proofs_out.reserve(serializable_membership_proofs_in.size()); - - for (ser_SpMembershipProofV1 &serializable_membership_proof : serializable_membership_proofs_in) - { - recover_sp_membership_proof_v1(serializable_membership_proof, - tools::add_element(membership_proofs_out)); - } -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -static void make_serializable_legacy_ring_signatures_v4(const std::vector &legacy_ring_signatures, - std::vector &serializable_legacy_ring_signatures_out) -{ - serializable_legacy_ring_signatures_out.clear(); - serializable_legacy_ring_signatures_out.reserve(legacy_ring_signatures.size()); - - for (const LegacyRingSignatureV4 &legacy_ring_signature : legacy_ring_signatures) - { - make_serializable_legacy_ring_signature_v4(legacy_ring_signature, - tools::add_element(serializable_legacy_ring_signatures_out)); - } -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -static void make_serializable_sp_membership_proofs_v1(const std::vector &membership_proofs, - std::vector &serializable_membership_proofs_out) -{ - serializable_membership_proofs_out.clear(); - serializable_membership_proofs_out.reserve(membership_proofs.size()); - - for (const SpMembershipProofV1 &membership_proof : membership_proofs) - { - make_serializable_sp_membership_proof_v1(membership_proof, - tools::add_element(serializable_membership_proofs_out)); - } -} -//------------------------------------------------------------------------------------------------------------------- -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_bpp2(const BulletproofPlus2Proof &bpp2_proof, ser_BulletproofPlus2_PARTIAL &serializable_bpp2_out) -{ - serializable_bpp2_out.A = bpp2_proof.A; - serializable_bpp2_out.A1 = bpp2_proof.A1; - serializable_bpp2_out.B = bpp2_proof.B; - serializable_bpp2_out.r1 = bpp2_proof.r1; - serializable_bpp2_out.s1 = bpp2_proof.s1; - serializable_bpp2_out.d1 = bpp2_proof.d1; - serializable_bpp2_out.L = bpp2_proof.L; - serializable_bpp2_out.R = bpp2_proof.R; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_clsag(const LegacyClsagProof &clsag, ser_LegacyClsagProof &serializable_clsag_out) -{ - serializable_clsag_out.s = clsag.s; - serializable_clsag_out.c1 = clsag.c1; - serializable_clsag_out.D = clsag.D; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_grootle_proof(const GrootleProof &grootle, ser_GrootleProof &serializable_grootle_out) -{ - serializable_grootle_out.A = grootle.A; - serializable_grootle_out.B = grootle.B; - serializable_grootle_out.f = grootle.f; - serializable_grootle_out.X = grootle.X; - serializable_grootle_out.zA = grootle.zA; - serializable_grootle_out.z = grootle.z; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_jamtis_payment_proposal_v1(const jamtis::JamtisPaymentProposalV1 &payment, ser_JamtisPaymentProposalV1 &serializable_payment_out) -{ - make_serializable_sp_destination_v1(payment.destination, serializable_payment_out.destination); - serializable_payment_out.amount = payment.amount; - serializable_payment_out.enote_ephemeral_privkey = payment.enote_ephemeral_privkey; - serializable_payment_out.partial_memo = payment.partial_memo; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_jamtis_payment_proposal_selfsend_v1(const jamtis::JamtisPaymentProposalSelfSendV1 &payment, ser_JamtisPaymentProposalSelfSendV1 &serializable_payment_out) -{ - make_serializable_sp_destination_v1(payment.destination, serializable_payment_out.destination); - serializable_payment_out.amount = payment.amount; - serializable_payment_out.type = static_cast(payment.type); - serializable_payment_out.enote_ephemeral_privkey = payment.enote_ephemeral_privkey; - serializable_payment_out.partial_memo = payment.partial_memo; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_composition_proof(const SpCompositionProof &proof, - ser_SpCompositionProof &serializable_proof_out) -{ - serializable_proof_out.c = proof.c; - serializable_proof_out.r_t1 = proof.r_t1; - serializable_proof_out.r_t2 = proof.r_t2; - serializable_proof_out.r_ki = proof.r_ki; - serializable_proof_out.K_t1 = proof.K_t1; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_coinbase_enote_core(const SpCoinbaseEnoteCore &enote, - ser_SpCoinbaseEnoteCore &serializable_enote_out) -{ - serializable_enote_out.onetime_address = enote.onetime_address; - serializable_enote_out.amount = enote.amount; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_enote_core(const SpEnoteCore &enote, ser_SpEnoteCore &serializable_enote_out) -{ - serializable_enote_out.onetime_address = enote.onetime_address; - serializable_enote_out.amount_commitment = enote.amount_commitment; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_enote_image_core(const SpEnoteImageCore &image, ser_SpEnoteImageCore &serializable_image_out) -{ - serializable_image_out.masked_address = image.masked_address; - serializable_image_out.masked_commitment = image.masked_commitment; - serializable_image_out.key_image = image.key_image; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_legacy_enote_image_v2(const LegacyEnoteImageV2 &image, - ser_LegacyEnoteImageV2 &serializable_image_out) -{ - serializable_image_out.masked_commitment = image.masked_commitment; - serializable_image_out.key_image = image.key_image; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_coinbase_enote_v1(const SpCoinbaseEnoteV1 &enote, ser_SpCoinbaseEnoteV1 &serializable_enote_out) -{ - make_serializable_sp_coinbase_enote_core(enote.core, serializable_enote_out.core); - memcpy(serializable_enote_out.addr_tag_enc.bytes, - enote.addr_tag_enc.bytes, - sizeof(enote.addr_tag_enc)); - serializable_enote_out.view_tag = enote.view_tag; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_enote_v1(const SpEnoteV1 &enote, ser_SpEnoteV1 &serializable_enote_out) -{ - make_serializable_sp_enote_core(enote.core, serializable_enote_out.core); - memcpy(serializable_enote_out.encoded_amount.bytes, - enote.encoded_amount.bytes, - sizeof(enote.encoded_amount)); - memcpy(serializable_enote_out.addr_tag_enc.bytes, - enote.addr_tag_enc.bytes, - sizeof(enote.addr_tag_enc)); - serializable_enote_out.view_tag = enote.view_tag; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_enote_image_v1(const SpEnoteImageV1 &image, ser_SpEnoteImageV1 &serializable_image_out) -{ - make_serializable_sp_enote_image_core(image.core, serializable_image_out.core); -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_balance_proof_v1(const SpBalanceProofV1 &proof, - ser_SpBalanceProofV1_PARTIAL &serializable_proof_out) -{ - make_serializable_bpp2(proof.bpp2_proof, serializable_proof_out.bpp2_proof_PARTIAL); - serializable_proof_out.remainder_blinding_factor = proof.remainder_blinding_factor; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_legacy_ring_signature_v4(const LegacyRingSignatureV4 &signature, - ser_LegacyRingSignatureV4 &serializable_signature_out) -{ - make_serializable_clsag(signature.clsag_proof, serializable_signature_out.clsag_proof); - serializable_signature_out.reference_set_COMPACT = signature.reference_set; - indices_to_offsets(serializable_signature_out.reference_set_COMPACT); -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_membership_proof_v1(const SpMembershipProofV1 &proof, - ser_SpMembershipProofV1 &serializable_proof_out) -{ - make_serializable_grootle_proof(proof.grootle_proof, serializable_proof_out.grootle_proof); - serializable_proof_out.bin_loci = proof.bin_loci; - serializable_proof_out.bin_rotation_factor = proof.bin_rotation_factor; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_image_proof_v1(const SpImageProofV1 &image_proof, - ser_SpImageProofV1 &serializable_image_proof_out) -{ - make_serializable_sp_composition_proof(image_proof.composition_proof, - serializable_image_proof_out.composition_proof); -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_tx_supplement_v1(const SpTxSupplementV1 &supplement, - ser_SpTxSupplementV1 &serializable_supplement_out) -{ - serializable_supplement_out.output_enote_ephemeral_pubkeys = supplement.output_enote_ephemeral_pubkeys; - serializable_supplement_out.tx_extra = supplement.tx_extra; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_discretized_fee(const DiscretizedFee discretized_fee, - unsigned char &serializable_discretized_fee_out) -{ - serializable_discretized_fee_out = discretized_fee.fee_encoding; -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_tx_coinbase_v1(const SpTxCoinbaseV1 &tx, ser_SpTxCoinbaseV1 &serializable_tx_out) -{ - // semantic rules version - serializable_tx_out.tx_semantic_rules_version = tx.tx_semantic_rules_version; - - // block height - serializable_tx_out.block_height = tx.block_height; - - // tx outputs (new enotes) - copy_array(&make_serializable_sp_coinbase_enote_v1, tx.outputs, serializable_tx_out.outputs); - - // supplemental data for tx - make_serializable_sp_tx_supplement_v1(tx.tx_supplement, serializable_tx_out.tx_supplement); -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_tx_squashed_v1(const SpTxSquashedV1 &tx, ser_SpTxSquashedV1 &serializable_tx_out) -{ - // semantic rules version - serializable_tx_out.tx_semantic_rules_version = tx.tx_semantic_rules_version; - - // legacy tx input images (spent legacy enotes) - copy_array(&make_serializable_legacy_enote_image_v2, tx.legacy_input_images, - serializable_tx_out.legacy_input_images); - - // seraphis tx input images (spent seraphis enotes) - copy_array(&make_serializable_sp_enote_image_v1, tx.sp_input_images, serializable_tx_out.sp_input_images); - - // tx outputs (new enotes) - copy_array(&make_serializable_sp_enote_v1, tx.outputs, serializable_tx_out.outputs); - - // balance proof (balance proof and range proofs) - make_serializable_sp_balance_proof_v1(tx.balance_proof, serializable_tx_out.balance_proof); - - // ring signature proofs: membership and ownership/key-image-legitimacy for each legacy input - make_serializable_legacy_ring_signatures_v4(tx.legacy_ring_signatures, - serializable_tx_out.legacy_ring_signatures); - - // composition proofs: ownership/key-image-legitimacy for each seraphis input - copy_array(&make_serializable_sp_image_proof_v1, tx.sp_image_proofs, serializable_tx_out.sp_image_proofs); - - // Grootle proofs on squashed enotes: membership for each seraphis input - make_serializable_sp_membership_proofs_v1(tx.sp_membership_proofs, serializable_tx_out.sp_membership_proofs); - - // supplemental data for tx - make_serializable_sp_tx_supplement_v1(tx.tx_supplement, serializable_tx_out.tx_supplement); - - // the transaction fee (discretized representation) - make_serializable_discretized_fee(tx.tx_fee, serializable_tx_out.tx_fee); -} -//------------------------------------------------------------------------------------------------------------------- -void make_serializable_sp_destination_v1(const jamtis::JamtisDestinationV1 &dest, ser_JamtisDestinationV1 &serializable_dest_out) -{ - serializable_dest_out.addr_K1 = dest.addr_K1; - serializable_dest_out.addr_K2 = dest.addr_K2; - serializable_dest_out.addr_K3 = dest.addr_K3; - memcpy(serializable_dest_out.addr_tag.bytes, - dest.addr_tag.bytes, - sizeof(dest.addr_tag)); -} -//------------------------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------------------------- -void recover_bpp2(ser_BulletproofPlus2_PARTIAL &serializable_bpp2_in, - BulletproofPlus2Proof &bpp2_proof_out) -{ - bpp2_proof_out.A = serializable_bpp2_in.A; - bpp2_proof_out.A1 = serializable_bpp2_in.A1; - bpp2_proof_out.B = serializable_bpp2_in.B; - bpp2_proof_out.r1 = serializable_bpp2_in.r1; - bpp2_proof_out.s1 = serializable_bpp2_in.s1; - bpp2_proof_out.d1 = serializable_bpp2_in.d1; - bpp2_proof_out.L = std::move(serializable_bpp2_in.L); - bpp2_proof_out.R = std::move(serializable_bpp2_in.R); -} -//------------------------------------------------------------------------------------------------------------------- -void recover_clsag(ser_LegacyClsagProof &serializable_clsag_in, LegacyClsagProof&clsag_out) -{ - clsag_out.s = std::move(serializable_clsag_in.s); - clsag_out.c1 = serializable_clsag_in.c1; - clsag_out.D = serializable_clsag_in.D; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_grootle_proof(ser_GrootleProof &serializable_grootle_in, GrootleProof &grootle_out) -{ - grootle_out.A = serializable_grootle_in.A; - grootle_out.B = serializable_grootle_in.B; - grootle_out.f = std::move(serializable_grootle_in.f); - grootle_out.X = std::move(serializable_grootle_in.X); - grootle_out.zA = serializable_grootle_in.zA; - grootle_out.z = serializable_grootle_in.z; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_jamtis_payment_proposal_v1(const ser_JamtisPaymentProposalV1 &serializable_payment, jamtis::JamtisPaymentProposalV1 &payment_out) -{ - recover_sp_destination_v1(serializable_payment.destination, payment_out.destination); - payment_out.amount = serializable_payment.amount; - payment_out.enote_ephemeral_privkey = serializable_payment.enote_ephemeral_privkey; - payment_out.partial_memo = serializable_payment.partial_memo; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_jamtis_payment_proposal_selfsend_v1(const ser_JamtisPaymentProposalSelfSendV1 &serializable_payment, jamtis::JamtisPaymentProposalSelfSendV1 &payment_out) -{ - recover_sp_destination_v1(serializable_payment.destination, payment_out.destination); - payment_out.amount = serializable_payment.amount; - payment_out.type = static_cast(serializable_payment.type); - payment_out.enote_ephemeral_privkey = serializable_payment.enote_ephemeral_privkey; - payment_out.partial_memo = serializable_payment.partial_memo; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_composition_proof(const ser_SpCompositionProof &serializable_proof, SpCompositionProof &proof_out) -{ - proof_out.c = serializable_proof.c; - proof_out.r_t1 = serializable_proof.r_t1; - proof_out.r_t2 = serializable_proof.r_t2; - proof_out.r_ki = serializable_proof.r_ki; - proof_out.K_t1 = serializable_proof.K_t1; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_coinbase_enote_core(const ser_SpCoinbaseEnoteCore &serializable_enote, SpCoinbaseEnoteCore &enote_out) -{ - enote_out.onetime_address = serializable_enote.onetime_address; - enote_out.amount = serializable_enote.amount; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_enote_core(const ser_SpEnoteCore &serializable_enote, SpEnoteCore &enote_out) -{ - enote_out.onetime_address = serializable_enote.onetime_address; - enote_out.amount_commitment = serializable_enote.amount_commitment; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_enote_image_core(const ser_SpEnoteImageCore &serializable_image, SpEnoteImageCore &image_out) -{ - image_out.masked_address = serializable_image.masked_address; - image_out.masked_commitment = serializable_image.masked_commitment; - image_out.key_image = serializable_image.key_image; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_legacy_enote_image_v2(const ser_LegacyEnoteImageV2 &serializable_image, LegacyEnoteImageV2 &image_out) -{ - image_out.masked_commitment = serializable_image.masked_commitment; - image_out.key_image = serializable_image.key_image; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_coinbase_enote_v1(const ser_SpCoinbaseEnoteV1 &serializable_enote, SpCoinbaseEnoteV1 &enote_out) -{ - recover_sp_coinbase_enote_core(serializable_enote.core, enote_out.core); - memcpy(enote_out.addr_tag_enc.bytes, - serializable_enote.addr_tag_enc.bytes, - sizeof(serializable_enote.addr_tag_enc)); - enote_out.view_tag = serializable_enote.view_tag; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_enote_v1(const ser_SpEnoteV1 &serializable_enote, SpEnoteV1 &enote_out) -{ - recover_sp_enote_core(serializable_enote.core, enote_out.core); - memcpy(enote_out.encoded_amount.bytes, - serializable_enote.encoded_amount.bytes, - sizeof(serializable_enote.encoded_amount)); - memcpy(enote_out.addr_tag_enc.bytes, - serializable_enote.addr_tag_enc.bytes, - sizeof(serializable_enote.addr_tag_enc)); - enote_out.view_tag = serializable_enote.view_tag; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_enote_image_v1(const ser_SpEnoteImageV1 &serializable_image, SpEnoteImageV1 &image_out) -{ - recover_sp_enote_image_core(serializable_image.core, image_out.core); -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_balance_proof_v1(ser_SpBalanceProofV1_PARTIAL &serializable_proof_in, - SpBalanceProofV1 &proof_out) -{ - // bpp2 - recover_bpp2(serializable_proof_in.bpp2_proof_PARTIAL, proof_out.bpp2_proof); - - // remainder blinding factor - proof_out.remainder_blinding_factor = serializable_proof_in.remainder_blinding_factor; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_legacy_ring_signature_v4(ser_LegacyRingSignatureV4 &serializable_signature_in, - LegacyRingSignatureV4 &signature_out) -{ - // clsag - recover_clsag(serializable_signature_in.clsag_proof, signature_out.clsag_proof); - - // reference set - signature_out.reference_set = std::move(serializable_signature_in.reference_set_COMPACT); - indices_from_offsets(signature_out.reference_set); -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_membership_proof_v1(ser_SpMembershipProofV1 &serializable_proof_in, - SpMembershipProofV1 &proof_out) -{ - // grootle proof - recover_grootle_proof(serializable_proof_in.grootle_proof, proof_out.grootle_proof); - - // binned ref set fields - proof_out.bin_loci = std::move(serializable_proof_in.bin_loci); - proof_out.bin_rotation_factor = serializable_proof_in.bin_rotation_factor; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_image_proof_v1(const ser_SpImageProofV1 &serializable_image_proof, SpImageProofV1 &image_proof_out) -{ - recover_sp_composition_proof(serializable_image_proof.composition_proof, image_proof_out.composition_proof); -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_tx_supplement_v1(ser_SpTxSupplementV1 &serializable_supplement_in, SpTxSupplementV1 &supplement_out) -{ - supplement_out.output_enote_ephemeral_pubkeys = - std::move(serializable_supplement_in.output_enote_ephemeral_pubkeys); - supplement_out.tx_extra = std::move(serializable_supplement_in.tx_extra); -} -//------------------------------------------------------------------------------------------------------------------- -void recover_discretized_fee(const unsigned char serializable_discretized_fee, DiscretizedFee &discretized_fee_out) -{ - discretized_fee_out.fee_encoding = serializable_discretized_fee; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_tx_coinbase_v1(ser_SpTxCoinbaseV1 &serializable_tx_in, SpTxCoinbaseV1 &tx_out) -{ - // semantic rules version - tx_out.tx_semantic_rules_version = serializable_tx_in.tx_semantic_rules_version; - - // block height - tx_out.block_height = serializable_tx_in.block_height; - - // tx outputs (new enotes) - relay_array(&recover_sp_coinbase_enote_v1, serializable_tx_in.outputs, tx_out.outputs); - - // supplemental data for tx - recover_sp_tx_supplement_v1(serializable_tx_in.tx_supplement, tx_out.tx_supplement); -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, - SpTxSquashedV1 &tx_out) -{ - // semantic rules version - tx_out.tx_semantic_rules_version = serializable_tx_in.tx_semantic_rules_version; - - // legacy tx input images (spent legacy enotes) - relay_array(&recover_legacy_enote_image_v2, serializable_tx_in.legacy_input_images, tx_out.legacy_input_images); - - // seraphis tx input images (spent seraphis enotes) - relay_array(&recover_sp_enote_image_v1, serializable_tx_in.sp_input_images, tx_out.sp_input_images); - - // tx outputs (new enotes) - relay_array(&recover_sp_enote_v1, serializable_tx_in.outputs, tx_out.outputs); - - // balance proof (balance proof and range proofs) - recover_sp_balance_proof_v1(serializable_tx_in.balance_proof, - tx_out.balance_proof); - - // ring signature proofs: membership and ownership/key-image-legitimacy for each legacy input - recover_legacy_ring_signatures_v4(serializable_tx_in.legacy_ring_signatures, - tx_out.legacy_input_images, - tx_out.legacy_ring_signatures); - - // composition proofs: ownership/key-image-legitimacy for each seraphis input - relay_array(&recover_sp_image_proof_v1, serializable_tx_in.sp_image_proofs, tx_out.sp_image_proofs); - - // Grootle proofs on squashed enotes: membership for each seraphis input - recover_sp_membership_proofs_v1(serializable_tx_in.sp_membership_proofs, - tx_out.sp_membership_proofs); - - // supplemental data for tx - recover_sp_tx_supplement_v1(serializable_tx_in.tx_supplement, tx_out.tx_supplement); - - // the transaction fee (discretized representation) - recover_discretized_fee(serializable_tx_in.tx_fee, tx_out.tx_fee); -} -//------------------------------------------------------------------------------------------------------------------- -bool try_recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, SpTxSquashedV1 &tx_out) -{ - try - { - recover_sp_tx_squashed_v1(serializable_tx_in, tx_out); - } - catch (...) { return false; } - - return true; -} -//------------------------------------------------------------------------------------------------------------------- -void recover_sp_destination_v1(const ser_JamtisDestinationV1 &serializable_destination, jamtis::JamtisDestinationV1 &dest_out) -{ - dest_out.addr_K1 = serializable_destination.addr_K1; - dest_out.addr_K2 = serializable_destination.addr_K2; - dest_out.addr_K3 = serializable_destination.addr_K3; - memcpy(dest_out.addr_tag.bytes, - serializable_destination.addr_tag.bytes, - sizeof(serializable_destination.addr_tag)); -} -//------------------------------------------------------------------------------------------------------------------- - -} //namespace serialization -} //namespace sp diff --git a/src/seraphis_impl/serialization_demo_utils.h b/src/seraphis_impl/serialization_demo_utils.h deleted file mode 100644 index 026a8ea0de..0000000000 --- a/src/seraphis_impl/serialization_demo_utils.h +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2023, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Serialization utilities for serializable seraphis types (a demonstration). -// WARNING: All of the deserialization functions are **destructive**, meaning the ser_ objects passed in will -// often be left in an invalid state after a function call. Note that the serialization functions -// are copy-only. - -#pragma once - -//local headers -#include "crypto/crypto.h" -#include "ringct/rctTypes.h" -#include "seraphis_core/discretized_fee.h" -#include "seraphis_core/jamtis_destination.h" -#include "seraphis_core/sp_core_types.h" -#include "seraphis_impl/serialization_demo_types.h" -#include "seraphis_main/tx_component_types.h" -#include "seraphis_main/tx_component_types_legacy.h" -#include "seraphis_main/txtype_squashed_v1.h" -#include "serialization/binary_archive.h" -#include "serialization/serialization.h" -#include "span.h" - -//third party headers - -//standard headers -#include -#include - -//forward declarations -namespace sp -{ - struct BulletproofPlus2; - struct GrootleProof; - struct SpCompositionProof; -} - -namespace sp -{ -namespace serialization -{ - -/** -* brief: try_append_serializable - try to serialize an object and append it to an input string -* type: SerializableT - type of the object to be serialized (the object must support serialization/deserialization) -* param: serializable - -* inoutparam: serialized_inout - -* return: true if serialization succeeded -*/ -template -bool try_append_serializable(SerializableT &serializable, std::string &serialized_inout) -{ - // serialize - std::stringstream serializable_ss; - binary_archive b_archive(serializable_ss); - if (!::serialization::serialize(b_archive, serializable)) - return false; - - // save to string - serialized_inout.append(serializable_ss.str()); - - return true; -} -/** -* brief: try_get_serializable - try to deserialize a string into an object -* type: SerializableT - type of the object to be deserialized into (the object must support serialization/deserialization) -* param: serialized - -* outparam: serializable_out - -* return: true if deserialization succeeded -*/ -template -bool try_get_serializable(epee::span serialized, SerializableT &serializable_out) -{ - // recover serializable - binary_archive archived{serialized}; - return ::serialization::serialize(archived, serializable_out); -} -/** -* brief: make_serializable_* - convert a normal object into one that is serializable -* param: object - normal object -* outparam: serializable_object_out - object to map the normal object into; this should be serializable/deserializable -*/ -void make_serializable_bpp2(const BulletproofPlus2Proof &bpp2_proof, ser_BulletproofPlus2_PARTIAL &serializable_bpp2_out); -void make_serializable_clsag(const LegacyClsagProof &clsag, ser_LegacyClsagProof &serializable_clsag_out); -void make_serializable_grootle_proof(const GrootleProof &grootle, ser_GrootleProof &serializable_grootle_out); -void make_serializable_jamtis_payment_proposal_v1(const jamtis::JamtisPaymentProposalV1 &payment, ser_JamtisPaymentProposalV1 &serializable_payment_out); -void make_serializable_jamtis_payment_proposal_selfsend_v1(const jamtis::JamtisPaymentProposalSelfSendV1 &payment, ser_JamtisPaymentProposalSelfSendV1 &serializable_payment_out); -void make_serializable_sp_composition_proof(const SpCompositionProof &proof, - ser_SpCompositionProof &serializable_proof_out); -void make_serializable_sp_coinbase_enote_core(const SpCoinbaseEnoteCore &enote, - ser_SpCoinbaseEnoteCore &serializable_enote_out); -void make_serializable_sp_enote_core(const SpEnoteCore &enote, ser_SpEnoteCore &serializable_enote_out); -void make_serializable_sp_enote_image_core(const SpEnoteImageCore &image, ser_SpEnoteImageCore &serializable_image_out); -void make_serializable_legacy_enote_image_v2(const LegacyEnoteImageV2 &image, - ser_LegacyEnoteImageV2 &serializable_image_out); -void make_serializable_sp_enote_v1(const SpEnoteV1 &enote, ser_SpEnoteV1 &serializable_enote_out); -void make_serializable_sp_enote_image_v1(const SpEnoteImageV1 &image, ser_SpEnoteImageV1 &serializable_image_out); -void make_serializable_sp_balance_proof_v1(const SpBalanceProofV1 &proof, - ser_SpBalanceProofV1_PARTIAL &serializable_proof_out); -void make_serializable_legacy_ring_signature_v4(const LegacyRingSignatureV4 &signature, - ser_LegacyRingSignatureV4 &serializable_signature_out); -void make_serializable_sp_membership_proof_v1(const SpMembershipProofV1 &proof, - ser_SpMembershipProofV1 &serializable_proof_out); -void make_serializable_sp_image_proof_v1(const SpImageProofV1 &image_proof, - ser_SpImageProofV1 &serializable_image_proof_out); -void make_serializable_sp_tx_supplement_v1(const SpTxSupplementV1 &supplement, - ser_SpTxSupplementV1 &serializable_supplement_out); -void make_serializable_discretized_fee(const DiscretizedFee discretized_fee, - unsigned char &serializable_discretized_fee_out); -void make_serializable_sp_tx_coinbase_v1(const SpTxCoinbaseV1 &tx, ser_SpTxCoinbaseV1 &serializable_tx_out); -void make_serializable_sp_tx_squashed_v1(const SpTxSquashedV1 &tx, ser_SpTxSquashedV1 &serializable_tx_out); -void make_serializable_sp_destination_v1(const jamtis::JamtisDestinationV1 &dest, ser_JamtisDestinationV1 &serializable_dest_out); -/** -* brief: recover_* - convert a serializable object back into its normal object parent -* param: serializable_object_in - serializable object to be consumed (destructive: may be left in an unusable state) -* param: ...params... - additional data not recorded in the serializable object to paste into the normal object -* outparam: object_out - object to map the serializable object and extra params into -*/ -void recover_bpp2(ser_BulletproofPlus2_PARTIAL &serializable_bpp2_in, - BulletproofPlus2Proof &bpp2_proof_out); -void recover_clsag(ser_LegacyClsagProof &serializable_clsag_in, LegacyClsagProof &clsag_out); -void recover_grootle_proof(ser_GrootleProof &serializable_grootle_in, GrootleProof &grootle_out); -void recover_jamtis_payment_proposal_v1(const ser_JamtisPaymentProposalV1 &serializable_payment, jamtis::JamtisPaymentProposalV1 &payment_out); -void recover_jamtis_payment_proposal_selfsend_v1(const ser_JamtisPaymentProposalSelfSendV1 &serializable_payment, jamtis::JamtisPaymentProposalSelfSendV1 &payment_out); -void recover_sp_composition_proof(const ser_SpCompositionProof &serializable_proof, SpCompositionProof &proof_out); -void recover_sp_coinbase_enote_core(const ser_SpCoinbaseEnoteCore &serializable_enote, SpCoinbaseEnoteCore &enote_out); -void recover_sp_enote_core(const ser_SpEnoteCore &serializable_enote, SpEnoteCore &enote_out); -void recover_sp_enote_image_core(const ser_SpEnoteImageCore &serializable_image, SpEnoteImageCore &image_out); -void recover_legacy_enote_image_v2(const ser_LegacyEnoteImageV2 &serializable_image, LegacyEnoteImageV2 &image_out); -void recover_sp_coinbase_enote_v1(const ser_SpCoinbaseEnoteV1 &serializable_enote, SpCoinbaseEnoteV1 &enote_out); -void recover_sp_enote_v1(const ser_SpEnoteV1 &serializable_enote, SpEnoteV1 &enote_out); -void recover_sp_enote_image_v1(const ser_SpEnoteImageV1 &serializable_image, SpEnoteImageV1 &image_out); -void recover_sp_balance_proof_v1(ser_SpBalanceProofV1_PARTIAL &serializable_proof_in, - SpBalanceProofV1 &proof_out); -void recover_legacy_ring_signature_v4(ser_LegacyRingSignatureV4 &serializable_signature_in, - LegacyRingSignatureV4 &signature_out); -void recover_sp_membership_proof_v1(ser_SpMembershipProofV1 &serializable_proof_in, - SpMembershipProofV1 &proof_out); -void recover_sp_image_proof_v1(const ser_SpImageProofV1 &serializable_image_proof, SpImageProofV1 &image_proof_out); -void recover_sp_tx_supplement_v1(ser_SpTxSupplementV1 &serializable_supplement_in, SpTxSupplementV1 &supplement_out); -void recover_discretized_fee(const unsigned char serializable_discretized_fee, DiscretizedFee &discretized_fee_out); -void recover_sp_tx_coinbase_v1(ser_SpTxCoinbaseV1 &serializable_tx_in, SpTxCoinbaseV1 &tx_out); -void recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, SpTxSquashedV1 &tx_out); -bool try_recover_sp_tx_squashed_v1(ser_SpTxSquashedV1 &serializable_tx_in, SpTxSquashedV1 &tx_out); -void recover_sp_destination_v1(const ser_JamtisDestinationV1 &serializable_destination, jamtis::JamtisDestinationV1 &dest_out); - -} //namespace serialization -} //namespace sp diff --git a/src/serialization/crypto.h b/src/serialization/crypto.h index 4b05d3bcf8..0852a05865 100644 --- a/src/serialization/crypto.h +++ b/src/serialization/crypto.h @@ -90,6 +90,7 @@ BLOB_SERIALIZER(crypto::signature); BLOB_SERIALIZER(crypto::view_tag); BLOB_SERIALIZER(crypto::x25519_pubkey); BLOB_SERIALIZER(crypto::x25519_scalar); +BLOB_SERIALIZER(crypto::x25519_secret_key); VARIANT_TAG(debug_archive, crypto::hash, "hash"); VARIANT_TAG(debug_archive, crypto::hash8, "hash8"); VARIANT_TAG(debug_archive, crypto::public_key, "public_key"); diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h index d1f97e3244..512f06cbf4 100644 --- a/src/serialization/serialization.h +++ b/src/serialization/serialization.h @@ -50,6 +50,8 @@ #include #include +#include "common/va_args.h" + /*! \struct is_blob_type * * \brief a descriptor for dispatching serialize @@ -88,6 +90,15 @@ inline bool do_serialize(Archive &ar, bool &v) ar.serialize_blob(&v, sizeof(v)); return true; } +template +inline auto do_serialize(Archive &ar, T &v, Args&&... args) + -> decltype(do_serialize_object(ar, v, args...), true) +{ + ar.begin_object(); + const bool r = do_serialize_object(ar, v, args...); + ar.end_object(); + return r && ar.good(); +} /* the following add a trait to a set and define the serialization DSL*/ @@ -158,18 +169,9 @@ inline bool do_serialize(Archive &ar, bool &v) * VARINT_FIELD_F(). Otherwise, this macro is similar to * BEGIN_SERIALIZE_OBJECT(), as you should list only field serializations. */ -#define BEGIN_SERIALIZE_OBJECT_FN(stype) \ - template class Archive> \ - bool do_serialize_object(Archive &ar, stype &v); \ - template class Archive> \ - bool do_serialize(Archive &ar, stype &v) { \ - ar.begin_object(); \ - bool r = do_serialize_object(ar, v); \ - ar.end_object(); \ - return r; \ - } \ - template class Archive> \ - bool do_serialize_object(Archive &ar, stype &v) { \ +#define BEGIN_SERIALIZE_OBJECT_FN(stype, ...) \ + template class Archive> \ + bool do_serialize_object(Archive &ar, stype &v VA_ARGS_COMMAPREFIX(__VA_ARGS__)) { /*! \macro PREPARE_CUSTOM_VECTOR_SERIALIZATION */ @@ -187,10 +189,10 @@ inline bool do_serialize(Archive &ar, bool &v) * * \brief serializes a field \a f tagged \a t */ -#define FIELD_N(t, f) \ +#define FIELD_N(t, f, ...) \ do { \ ar.tag(t); \ - bool r = do_serialize(ar, f); \ + bool r = do_serialize(ar, f VA_ARGS_COMMAPREFIX(__VA_ARGS__)); \ if (!r || !ar.good()) return false; \ } while(0); @@ -209,7 +211,7 @@ inline bool do_serialize(Archive &ar, bool &v) * * \brief tags the field with the variable name and then serializes it (for use in a free function) */ -#define FIELD_F(f) FIELD_N(#f, v.f) +#define FIELD_F(f, ...) FIELD_N(#f, v.f VA_ARGS_COMMAPREFIX(__VA_ARGS__)) /*! \macro FIELDS(f) * diff --git a/tests/performance_tests/seraphis_tx.h b/tests/performance_tests/seraphis_tx.h index 965161cbbb..135729f8d2 100644 --- a/tests/performance_tests/seraphis_tx.h +++ b/tests/performance_tests/seraphis_tx.h @@ -324,8 +324,8 @@ class test_seraphis_tx m_sp_ref_set_config = sp::SemanticConfigSpRefSetV1{ .decomp_n = params.n, .decomp_m = params.m, - .bin_radius = sp::math::uint_pow(params.n, params.m) / 2, - .num_bin_members = sp::math::uint_pow(params.n, params.m / 2) + .bin_radius = static_cast(sp::math::uint_pow(params.n, params.m) / 2), + .num_bin_members = static_cast(sp::math::uint_pow(params.n, params.m / 2)) }; // make tx diff --git a/tests/unit_tests/seraphis_serialization.cpp b/tests/unit_tests/seraphis_serialization.cpp index 7c033d24ed..76c8efd14b 100644 --- a/tests/unit_tests/seraphis_serialization.cpp +++ b/tests/unit_tests/seraphis_serialization.cpp @@ -28,41 +28,33 @@ #include "ringct/rctTypes.h" #include "seraphis_core/binned_reference_set.h" -#include "seraphis_impl/serialization_demo_types.h" -#include "seraphis_impl/serialization_demo_utils.h" +#include "seraphis_impl/seraphis_serialization.h" #include "seraphis_main/txtype_base.h" #include "seraphis_main/txtype_coinbase_v1.h" #include "seraphis_main/txtype_squashed_v1.h" #include "seraphis_mocks/seraphis_mocks.h" +#include "serialization/binary_utils.h" #include "span.h" #include "gtest/gtest.h" using namespace sp; -using namespace mocks; +using namespace jamtis; +using namespace sp::mocks; //------------------------------------------------------------------------------------------------------------------- -TEST(seraphis_serialization_demo, seraphis_coinbase_empty) +TEST(seraphis_serialization, seraphis_coinbase_empty) { // make empty tx SpTxCoinbaseV1 tx{}; - // convert the tx to serializable form - sp::serialization::ser_SpTxCoinbaseV1 serializable_tx; - EXPECT_NO_THROW(sp::serialization::make_serializable_sp_tx_coinbase_v1(tx, serializable_tx)); - // serialize the tx std::string serialized_tx; - EXPECT_TRUE(sp::serialization::try_append_serializable(serializable_tx, serialized_tx)); - - // deserialize the tx - sp::serialization::ser_SpTxCoinbaseV1 serializable_tx_recovered; - EXPECT_TRUE(sp::serialization::try_get_serializable(epee::strspan(serialized_tx), - serializable_tx_recovered)); + EXPECT_TRUE(::serialization::dump_binary(tx, serialized_tx)); // recover the tx SpTxCoinbaseV1 recovered_tx; - EXPECT_NO_THROW(sp::serialization::recover_sp_tx_coinbase_v1(serializable_tx_recovered, recovered_tx)); + EXPECT_TRUE(::serialization::parse_binary(serialized_tx, recovered_tx)); // check that the original tx was recovered rct::key original_tx_id; @@ -75,27 +67,18 @@ TEST(seraphis_serialization_demo, seraphis_coinbase_empty) EXPECT_NO_THROW(EXPECT_TRUE(sp_tx_coinbase_v1_size_bytes(tx) == sp_tx_coinbase_v1_size_bytes(recovered_tx))); } //------------------------------------------------------------------------------------------------------------------- -TEST(seraphis_serialization_demo, seraphis_squashed_empty) +TEST(seraphis_serialization, seraphis_squashed_empty) { // make empty tx SpTxSquashedV1 tx{}; - // convert the tx to serializable form - sp::serialization::ser_SpTxSquashedV1 serializable_tx; - EXPECT_NO_THROW(sp::serialization::make_serializable_sp_tx_squashed_v1(tx, serializable_tx)); - // serialize the tx std::string serialized_tx; - EXPECT_TRUE(sp::serialization::try_append_serializable(serializable_tx, serialized_tx)); - - // deserialize the tx - sp::serialization::ser_SpTxSquashedV1 serializable_tx_recovered; - EXPECT_TRUE(sp::serialization::try_get_serializable(epee::strspan(serialized_tx), - serializable_tx_recovered)); + EXPECT_TRUE(::serialization::dump_binary(tx, serialized_tx)); // recover the tx SpTxSquashedV1 recovered_tx; - EXPECT_NO_THROW(sp::serialization::recover_sp_tx_squashed_v1(serializable_tx_recovered, recovered_tx)); + EXPECT_TRUE(::serialization::parse_binary(serialized_tx, recovered_tx)); // check that the original tx was recovered rct::key original_tx_id; @@ -108,7 +91,7 @@ TEST(seraphis_serialization_demo, seraphis_squashed_empty) EXPECT_NO_THROW(EXPECT_TRUE(sp_tx_squashed_v1_size_bytes(tx) == sp_tx_squashed_v1_size_bytes(recovered_tx))); } //------------------------------------------------------------------------------------------------------------------- -TEST(seraphis_serialization_demo, seraphis_coinbase_standard) +TEST(seraphis_serialization, seraphis_coinbase_standard) { // ledger context MockLedgerContext ledger_context{0, 10000}; @@ -118,22 +101,13 @@ TEST(seraphis_serialization_demo, seraphis_coinbase_standard) SpTxCoinbaseV1 tx; make_mock_tx(SpTxParamPackV1{.output_amounts = {1}}, ledger_context, tx); - // convert the tx to serializable form - sp::serialization::ser_SpTxCoinbaseV1 serializable_tx; - EXPECT_NO_THROW(sp::serialization::make_serializable_sp_tx_coinbase_v1(tx, serializable_tx)); - // serialize the tx std::string serialized_tx; - EXPECT_TRUE(sp::serialization::try_append_serializable(serializable_tx, serialized_tx)); - - // deserialize the tx - sp::serialization::ser_SpTxCoinbaseV1 serializable_tx_recovered; - EXPECT_TRUE(sp::serialization::try_get_serializable(epee::strspan(serialized_tx), - serializable_tx_recovered)); + EXPECT_TRUE(::serialization::dump_binary(tx, serialized_tx)); // recover the tx SpTxCoinbaseV1 recovered_tx; - EXPECT_NO_THROW(sp::serialization::recover_sp_tx_coinbase_v1(serializable_tx_recovered, recovered_tx)); + EXPECT_TRUE(::serialization::parse_binary(serialized_tx, recovered_tx)); // check the tx was recovered rct::key original_tx_id; @@ -148,7 +122,7 @@ TEST(seraphis_serialization_demo, seraphis_coinbase_standard) EXPECT_TRUE(validate_tx(recovered_tx, tx_validation_context)); } //------------------------------------------------------------------------------------------------------------------- -TEST(seraphis_serialization_demo, seraphis_squashed_standard) +TEST(seraphis_serialization, seraphis_squashed_standard) { // config SpTxParamPackV1 tx_params; @@ -165,7 +139,7 @@ TEST(seraphis_serialization_demo, seraphis_squashed_standard) tx_params.sp_input_amounts = {2, 3}; tx_params.output_amounts = {3}; tx_params.discretized_fee = discretize_fee(3); - + const SemanticConfigSpRefSetV1 sp_ref_set_config{ .decomp_n = tx_params.ref_set_decomp_n, .decomp_m = tx_params.ref_set_decomp_m, @@ -179,27 +153,15 @@ TEST(seraphis_serialization_demo, seraphis_squashed_standard) // make a tx SpTxSquashedV1 tx; - make_mock_tx(tx_params, - ledger_context, - tx); - - // convert the tx to serializable form - sp::serialization::ser_SpTxSquashedV1 serializable_tx; - EXPECT_NO_THROW(sp::serialization::make_serializable_sp_tx_squashed_v1(tx, serializable_tx)); + make_mock_tx(tx_params, ledger_context, tx); // serialize the tx std::string serialized_tx; - EXPECT_TRUE(sp::serialization::try_append_serializable(serializable_tx, serialized_tx)); - - // deserialize the tx - sp::serialization::ser_SpTxSquashedV1 serializable_tx_recovered; - EXPECT_TRUE(sp::serialization::try_get_serializable(epee::strspan(serialized_tx), - serializable_tx_recovered)); + EXPECT_TRUE(::serialization::dump_binary(tx, serialized_tx)); // recover the tx SpTxSquashedV1 recovered_tx; - EXPECT_NO_THROW(sp::serialization::recover_sp_tx_squashed_v1(serializable_tx_recovered, - recovered_tx)); + EXPECT_TRUE(::serialization::parse_binary(serialized_tx, recovered_tx)); // check the tx was recovered rct::key original_tx_id; @@ -214,3 +176,56 @@ TEST(seraphis_serialization_demo, seraphis_squashed_standard) EXPECT_TRUE(validate_tx(recovered_tx, tx_validation_context)); } //------------------------------------------------------------------------------------------------------------------- +TEST(seraphis_serialization, jamtis_destination_v1) +{ + // generate + JamtisDestinationV1 dest{gen_jamtis_destination_v1()}; + + // serialize + std::string serialized_dest; + EXPECT_TRUE(::serialization::dump_binary(dest, serialized_dest)); + + // deserialize + JamtisDestinationV1 recovered_dest; + EXPECT_TRUE(::serialization::parse_binary(serialized_dest, recovered_dest)); + + // compare + EXPECT_EQ(dest, recovered_dest); +} +//------------------------------------------------------------------------------------------------------------------- +TEST(seraphis_serialization, jamtis_payment_proposal_v1) +{ + // generate + JamtisPaymentProposalV1 payprop{gen_jamtis_payment_proposal_v1(7, 3)}; + + // serialize + std::string serialized_payprop; + EXPECT_TRUE(::serialization::dump_binary(payprop, serialized_payprop)); + + // deserialize + JamtisPaymentProposalV1 recovered_payprop; + EXPECT_TRUE(::serialization::parse_binary(serialized_payprop, recovered_payprop)); + + // compare + EXPECT_EQ(payprop, recovered_payprop); +} +//------------------------------------------------------------------------------------------------------------------- +TEST(seraphis_serialization, jamtis_payment_proposal_self_send_v1) +{ + // generate + JamtisPaymentProposalSelfSendV1 payprop{ + gen_jamtis_selfsend_payment_proposal_v1(7, JamtisSelfSendType::SELF_SPEND, 3) + }; + + // serialize + std::string serialized_payprop; + EXPECT_TRUE(::serialization::dump_binary(payprop, serialized_payprop)); + + // deserialize + JamtisPaymentProposalSelfSendV1 recovered_payprop; + EXPECT_TRUE(::serialization::parse_binary(serialized_payprop, recovered_payprop)); + + // compare + EXPECT_EQ(payprop, recovered_payprop); +} +//-------------------------------------------------------------------------------------------------------------------