Skip to content

Commit

Permalink
Tx rigidity and direct serialization
Browse files Browse the repository at this point in the history
Okay I promise after this and the BulletproofPlus2Proof PR I'll stop bitching
about the tx class format.

* Replace `rct::clsag` with `LegacyClsagProof`, which is `rct::clsag` without `I` field
* Remove bin config fields and generator seed from `SpMembershipProofV1`
* Add `SemanticConfigSpRefSetV1 get_sp_ref_set_config(tx_version_t)` method to `TxValidationContext`
* Add `validate_tx_sp_ref_set_semantics` validator impl free function
* Add `tx_version_from(const SpTxType&)` validator impl free function
* Make `TxValidationContextMock` bound to a specific `SemanticConfigSpRefSetV1`
* Direct serialization

Depends on monero-project#9195 and
monero-project#9194
  • Loading branch information
jeffro256 committed Mar 4, 2024
1 parent bf4952f commit e70e4a2
Show file tree
Hide file tree
Showing 40 changed files with 810 additions and 1,705 deletions.
2 changes: 1 addition & 1 deletion src/ringct/rctTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ namespace std
BLOB_SERIALIZER(rct::key);
BLOB_SERIALIZER(rct::key64);
BLOB_SERIALIZER(rct::ctkey);
BLOB_SERIALIZER(rct::multisig_kLRki);
BLOB_SERIALIZER_FORCED(rct::multisig_kLRki);
BLOB_SERIALIZER(rct::boroSig);

VARIANT_TAG(debug_archive, rct::key, "rct::key");
Expand Down
6 changes: 6 additions & 0 deletions src/seraphis_crypto/sp_crypto_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ rct::key invert(const rct::key &x)
return inv;
}
//-------------------------------------------------------------------------------------------------------------------
bool scalarmult_inv8_checked(const rct::key &P, rct::key &P_mul_inv8_out)
{
P_mul_inv8_out = rct::scalarmultKey(P, rct::INV_EIGHT);
return rct::scalarmult8(P_mul_inv8_out) == P;
}
//-------------------------------------------------------------------------------------------------------------------
rct::key scalarmult_inv8_checked(const rct::key &P)
{
const rct::key P_mul_inv8 = rct::scalarmultKey(P, rct::INV_EIGHT);
Expand Down
7 changes: 7 additions & 0 deletions src/seraphis_crypto/sp_crypto_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ rct::key minus_one();
* return: (1/x) mod l
*/
rct::key invert(const rct::key &x);
/**
* brief: return point (1/8)*P, checking that 8*((1/8)*P) == P
* param: P - canonical point which lies on prime order subgroup
* outparam: P_mul_inv8_out - (1/8)*P
* return: return true if 8*((1/8)*P) == P, false otherwise
*/
bool scalarmult_inv8_checked(const rct::key &P, rct::key &P_mul_inv8_out);
/**
* brief: return point (1/8)*P, checking that 8*((1/8)*P) == P
* param: P - canonical point which lies on prime order subgroup
Expand Down
8 changes: 0 additions & 8 deletions src/seraphis_crypto/sp_legacy_proof_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,6 @@ static std::size_t highest_bit_position(std::size_t num)
}
//-------------------------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------------------------
void append_clsag_to_transcript(const rct::clsag &clsag_proof, SpTranscriptBuilder &transcript_inout)
{
transcript_inout.append("s", clsag_proof.s);
transcript_inout.append("c1", clsag_proof.c1);
transcript_inout.append("I", clsag_proof.I);
transcript_inout.append("D", clsag_proof.D);
}
//-------------------------------------------------------------------------------------------------------------------
std::size_t clsag_size_bytes(const std::size_t ring_size)
{
return 32 * (ring_size + 2); //does not include 'I', which is treated as a cached value here
Expand Down
8 changes: 0 additions & 8 deletions src/seraphis_crypto/sp_legacy_proof_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,6 @@ namespace sp { class SpTranscriptBuilder; }

namespace sp
{

/**
* brief: append_clsag_to_transcript - append CLSAG proof to a transcript
* transcript += {s} || c1 || I || D
* param: clsag_proof -
* inoutparam: transcript_inout - contents appended to a transcript
*/
void append_clsag_to_transcript(const rct::clsag &clsag_proof, SpTranscriptBuilder &transcript_inout);
/**
* brief: clsag_size_bytes - get the size of a CLSAG proof in bytes
* - CLSAG size: 32 * (ring size + 2)
Expand Down
1 change: 0 additions & 1 deletion src/seraphis_impl/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
265 changes: 265 additions & 0 deletions src/seraphis_impl/seraphis_tx_serialization.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
// 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/binned_reference_set.h"
#include "seraphis_core/discretized_fee.h"
#include "seraphis_core/jamtis_destination.h"
#include "seraphis_core/jamtis_support_types.h"
#include "seraphis_crypto/sp_crypto_utils.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

#define MUL_INV8_FIELD_F(f) \
do { \
ar.tag(#f); \
if (!sp::serialization::serialize_pubkey_mul_inv8(ar, v.f)) \
return false; \
} while(0);

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 <typename SerializableT>
bool try_append_serializable(SerializableT &serializable, std::string &serialized_inout)
{
// serialize
std::stringstream serializable_ss;
binary_archive<true> 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 <typename SerializableT>
bool try_get_serializable(epee::span<const std::uint8_t> serialized, SerializableT &serializable_out)
{
// recover serializable
binary_archive<false> archived{serialized};
return ::serialization::serialize(archived, serializable_out);
}

/**
* brief: serialize_pubkey_mul_inv8 - serialize rct::key point in (1/8)*P form
*/
template <bool W, template <bool> class Archive>
bool serialize_pubkey_mul_inv8(Archive<W> &ar, rct::key &P)
{
rct::key P_mul_inv8;
if (W && !scalarmult_inv8_checked(P, P_mul_inv8))
return false;
FIELDS(P_mul_inv8)
if (!W)
P = rct::scalarmult8(P_mul_inv8);
return true;
}
} // namespace serialization

BEGIN_SERIALIZE_FN(sp::DiscretizedFee)
FIELDS(v.fee_encoding)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpCoinbaseEnoteCore)
FIELD_F(onetime_address)
VARINT_FIELD_F(amount)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpEnoteCore)
FIELD_F(onetime_address)
MUL_INV8_FIELD_F(amount_commitment)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpEnoteImageCore)
FIELD_F(masked_address)
MUL_INV8_FIELD_F(masked_commitment)
FIELD_F(key_image)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::LegacyClsagProof)
FIELD_F(s)
FIELD_F(c1)
FIELD_F(D)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::BulletproofPlus2Proof)
FIELD_F(A)
FIELD_F(A1)
FIELD_F(B)
FIELD_F(r1)
FIELD_F(s1)
FIELD_F(d1)
FIELD_F(L)
FIELD_F(R)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::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(sp::GrootleProof)
FIELD_F(A)
FIELD_F(B)
FIELD_F(f)
FIELD_F(X)
FIELD_F(zA)
FIELD_F(z)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::LegacyEnoteImageV2)
FIELD_F(masked_commitment)
FIELD_F(key_image)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpEnoteImageV1)
FIELD_F(core)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpCoinbaseEnoteV1)
FIELD_F(core)
FIELD_F(addr_tag_enc)
VARINT_FIELD_F(view_tag)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpEnoteV1)
FIELD_F(core)
FIELD_F(encoded_amount)
FIELD_F(addr_tag_enc)
VARINT_FIELD_F(view_tag)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpBalanceProofV1)
FIELD_F(bpp2_proof)
FIELD_F(remainder_blinding_factor)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::LegacyRingSignatureV4)
FIELD_F(clsag_proof)
FIELD_F(reference_set)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpImageProofV1)
FIELD_F(composition_proof)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpMembershipProofV1)
FIELD_F(grootle_proof)
FIELD_F(bin_loci)
VARINT_FIELD_F(bin_rotation_factor)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpTxSupplementV1)
FIELD_F(output_enote_ephemeral_pubkeys)
FIELD_F(tx_extra)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpTxCoinbaseV1)
VARINT_FIELD_F(tx_semantic_rules_version)
VARINT_FIELD_F(block_height)
VARINT_FIELD_F(block_reward)
FIELD_F(outputs)
FIELD_F(tx_supplement)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::SpTxSquashedV1)
VARINT_FIELD_F(tx_semantic_rules_version)
FIELD_F(legacy_input_images)
FIELD_F(sp_input_images)
FIELD_F(outputs)
FIELD_F(balance_proof)
FIELD_F(legacy_ring_signatures)
FIELD_F(sp_image_proofs)
FIELD_F(sp_membership_proofs)
FIELD_F(tx_supplement)
FIELD_F(tx_fee)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::jamtis::JamtisDestinationV1)
FIELD_F(addr_K1)
FIELD_F(addr_K2)
FIELD_F(addr_K3)
FIELD_F(addr_tag)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::jamtis::JamtisPaymentProposalV1)
FIELD_F(destination)
FIELD_F(amount)
FIELD_F(enote_ephemeral_privkey)
FIELD_F(partial_memo)
END_SERIALIZE()

BEGIN_SERIALIZE_OBJECT_FN(sp::jamtis::JamtisPaymentProposalSelfSendV1)
FIELD_F(destination)
FIELD_F(amount)
FIELD_F(type)
FIELD_F(enote_ephemeral_privkey)
FIELD_F(partial_memo)
END_SERIALIZE()
} // namespace sp

BLOB_SERIALIZER(sp::jamtis::address_index_t);
BLOB_SERIALIZER(sp::jamtis::address_tag_t);
BLOB_SERIALIZER(sp::jamtis::encoded_amount_t);

0 comments on commit e70e4a2

Please sign in to comment.