interim checkin of changes for audit; bumped version number

This commit is contained in:
Some Random Crypto Guy
2025-01-29 15:39:08 +00:00
parent 2a4d08b67f
commit a7c1ba652b
49 changed files with 1692 additions and 899 deletions
+79 -21
View File
@@ -1,5 +1,5 @@
// Copyright (c) 2016, Monero Research Labs
// Portions Copyright (c) 2023-2024, Salvium (author: SRCG)
// Portions Copyright (c) 2023-2025, Salvium (author: SRCG)
//
// Author: Shen Noether <shen.noether@gmx.com>
//
@@ -677,7 +677,7 @@ namespace rct {
kv.push_back(p.t);
}
}
else if (rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs)
else if (rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne)
{
kv.reserve((6*2+6) * rv.p.bulletproofs_plus.size());
for (const auto &p: rv.p.bulletproofs_plus)
@@ -1161,7 +1161,7 @@ namespace rct {
//mask amount and mask
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
rv.ecdhInfo[i].amount = d2h(amounts[i]);
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs);
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne);
}
//set txn fee
@@ -1206,6 +1206,7 @@ namespace rct {
ctkeyV &outSk,
const RCTConfig &rct_config,
hw::device &hwdev,
const rct::salvium_data_t &salvium_data,
const key &x_change,
const size_t change_index,
const key &key_yF
@@ -1235,6 +1236,9 @@ namespace rct {
case 5:
rv.type = RCTTypeFullProofs;
break;
case 6:
rv.type = RCTTypeSalviumOne;
break;
default:
ASSERT_MES_AND_THROW("Unsupported BP version: " << rct_config.bp_version);
}
@@ -1289,6 +1293,7 @@ namespace rct {
rv.p.bulletproofs_plus.push_back(proveRangeBulletproofPlus(C, masks, outamounts, keys, hwdev));
else
rv.p.bulletproofs.push_back(proveRangeBulletproof(C, masks, outamounts, keys, hwdev));
#ifdef DBG
if (plus)
CHECK_AND_ASSERT_THROW_MES(verBulletproofPlus(rv.p.bulletproofs_plus.back()), "verBulletproofPlus failed on newly created proof");
@@ -1351,7 +1356,7 @@ namespace rct {
//mask amount and mask
rv.ecdhInfo[i].mask = copy(outSk[i].mask);
rv.ecdhInfo[i].amount = d2h(outamounts[i]);
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs);
hwdev.ecdhEncode(rv.ecdhInfo[i], amount_keys[i], rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne);
}
//set txn fee
@@ -1367,28 +1372,43 @@ namespace rct {
rv.p.MGs.resize(inamounts.size());
key sumpouts = zero(); //sum pseudoOut masks
keyV a(inamounts.size());
bool audit = (tx_type == cryptonote::transaction_type::AUDIT && rv.type == RCTTypeSalviumOne && salvium_data.salvium_data_type == rct::SalviumAudit);
for (i = 0 ; i < inamounts.size(); i++) {
if (audit)
a[i] = rct::zero();
else
skGen(a[i]);
sc_add(sumpouts.bytes, a[i].bytes, sumpouts.bytes);
genC(pseudoOuts[i], a[i], inamounts[i]);
sc_add(sumpouts.bytes, a[i].bytes, sumpouts.bytes);
genC(pseudoOuts[i], a[i], inamounts[i]);
}
key difference;
sc_sub(difference.bytes, sumpouts.bytes, sumout.bytes);
genC(rv.p_r, difference, 0);
DP(rv.p_r);
if (rv.type == RCTTypeFullProofs) {
rv.pr_proof = PRProof_Gen(difference);
if (rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne) {
rv.salvium_data.pr_proof = PRProof_Gen(difference);
#ifdef DBG
CHECK_AND_ASSERT_THROW_MES(PRProof_Ver(rv.p_r, rv.pr_proof), "PRProof_Ver() failed on recently created proof");
CHECK_AND_ASSERT_THROW_MES(PRProof_Ver(rv.p_r, rv.salvium_data.pr_proof), "PRProof_Ver() failed on recently created proof");
#endif
rv.salvium_data.salvium_data_type = salvium_data.salvium_data_type;
if (audit) {
// SRCG: populate the audit proof here
rv.salvium_data.input_verification_data = salvium_data.input_verification_data;
rv.salvium_data.spend_pubkey = salvium_data.spend_pubkey;
rv.salvium_data.enc_view_privkey_str = salvium_data.enc_view_privkey_str;
rv.salvium_data.cz_proof = PRProof_Gen(outSk[0].mask);
#ifdef DBG
CHECK_AND_ASSERT_THROW_MES(PRProof_Ver(rv.outPk[0].mask, rv.salvium_data.cz_proof), "PRProof_Ver() failed on recently created change proof");
#endif
}
}
/*
// Check if spend authority proof is needed (only for TRANSFER TXs)
if (tx_type == cryptonote::transaction_type::TRANSFER && rv.type == rct::RCTTypeFullProofs) {
rv.sa_proof = SAProof_Gen(destinations[change_index], x_change, key_yF);
if (tx_type == cryptonote::transaction_type::TRANSFER && rv.type == rct::RCTTypeSalviumOne) {
rv.salvium_data.sa_proof = SAProof_Gen(destinations[change_index], x_change, key_yF);
#ifdef DBG
CHECK_AND_ASSERT_THROW_MES(SAProof_Ver(rv.sa_proof, destinations[change_index], key_yF), "SAProof_Ver() failed on recently created proof");
CHECK_AND_ASSERT_THROW_MES(SAProof_Ver(rv.salvium_data.sa_proof, destinations[change_index], key_yF), "SAProof_Ver() failed on recently created proof");
#endif
}
*/
@@ -1428,6 +1448,7 @@ namespace rct {
unsigned int mixin,
const RCTConfig &rct_config,
hw::device &hwdev,
const rct::salvium_data_t &salvium_data,
const key &x_change,
const size_t change_index,
const key &key_yF
@@ -1441,7 +1462,7 @@ namespace rct {
mixRing[i].resize(mixin+1);
index[i] = populateFromBlockchainSimple(mixRing[i], inPk[i], mixin);
}
return genRctSimple(message, inSk, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk, rct_config, hwdev, x_change, change_index, key_yF);
return genRctSimple(message, inSk, destinations, tx_type, in_asset_type, destination_asset_types, inamounts, outamounts, txnFee, mixRing, amount_keys, index, outSk, rct_config, hwdev, salvium_data, x_change, change_index, key_yF);
}
//RingCT protocol
@@ -1530,10 +1551,11 @@ namespace rct {
std::vector<const BulletproofPlus*> bpp_proofs;
size_t max_non_bp_proofs = 0, offset = 0;
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs,
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne,
false, "verRctSemanticsSimple called on non simple rctSig");
if (rv.type == RCTTypeFullProofs)
CHECK_AND_ASSERT_MES(PRProof_Ver(rv.p_r, rv.pr_proof), false, "Invalid p_r commitment to difference");
if (rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne)
CHECK_AND_ASSERT_MES(PRProof_Ver(rv.p_r, rv.salvium_data.pr_proof), false, "Invalid p_r commitment to difference");
const bool bulletproof = is_rct_bulletproof(rv.type);
const bool bulletproof_plus = is_rct_bulletproof_plus(rv.type);
if (bulletproof || bulletproof_plus)
@@ -1656,7 +1678,7 @@ namespace rct {
{
PERF_TIMER(verRctNonSemanticsSimple);
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs,
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne,
false, "verRctNonSemanticsSimple called on non simple rctSig");
const bool bulletproof = is_rct_bulletproof(rv.type);
const bool bulletproof_plus = is_rct_bulletproof_plus(rv.type);
@@ -1696,6 +1718,42 @@ namespace rct {
}
}
bool audit = (rv.type == RCTTypeSalviumOne && rv.salvium_data.salvium_data_type == rct::SalviumAudit);
if (audit) {
// Validate the Salvium audit data
CHECK_AND_ASSERT_THROW_MES(PRProof_Ver(rv.outPk[0].mask, rv.salvium_data.cz_proof), "PRProof_Ver() failed on change proof");
CHECK_AND_ASSERT_THROW_MES(pseudoOuts.size() == rv.salvium_data.input_verification_data.size(), "incorrect number of input verification datasets");
CHECK_AND_ASSERT_THROW_MES(rv.salvium_data.spend_pubkey != crypto::null_pkey, "Invalid spend pubkey provided in audit data");
CHECK_AND_ASSERT_THROW_MES(rv.salvium_data.enc_view_privkey_str != "", "Invalid encrypted viewkey provided in audit data");
for (size_t i=0; i < rv.salvium_data.input_verification_data.size(); ++i) {
// Check for STAKE origin
crypto::public_key Ks = rv.salvium_data.spend_pubkey;
if (rv.salvium_data.input_verification_data[i].origin_tx_type != cryptonote::transaction_type::UNSET) {
// Verify the origin data provided
CHECK_AND_ASSERT_THROW_MES(crypto::derive_public_key(rv.salvium_data.input_verification_data[i].aR_stake, rv.salvium_data.input_verification_data[i].i_stake, rv.salvium_data.spend_pubkey, Ks),
"Failed to derive ephemeral public key from audit data");
}
// Recalculate the value of Ks from the Ko value
crypto::public_key ephemeral_pub = crypto::null_pkey;
CHECK_AND_ASSERT_THROW_MES(crypto::derive_public_key(rv.salvium_data.input_verification_data[i].aR, rv.salvium_data.input_verification_data[i].i, Ks, ephemeral_pub),
"Failed to derive ephemeral public key from audit data");
// Now find this in the list of mixring entries
bool found = false;
for (size_t n=0; n<rv.mixRing[i].size(); ++n) {
if (ephemeral_pub == rct::rct2pk(rv.mixRing[i][n].dest)) {
found = true;
break;
}
}
CHECK_AND_ASSERT_THROW_MES(found, "Failed to match ephemeral public key provided in audit data");
// Verify the individual input commitment
CHECK_AND_ASSERT_THROW_MES(equalKeys(scalarmultH(d2h(rv.salvium_data.input_verification_data[i].amount)), pseudoOuts[i]), "Invalid pseudoOuts entry");
}
}
return true;
}
// we can get deep throws from ge_frombytes_vartime if input isn't valid
@@ -1728,7 +1786,7 @@ namespace rct {
//mask amount and mask
ecdhTuple ecdh_info = rv.ecdhInfo[i];
hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs);
hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne);
mask = ecdh_info.mask;
key amount = ecdh_info.amount;
key C = rv.outPk[i].mask;
@@ -1752,14 +1810,14 @@ namespace rct {
}
xmr_amount decodeRctSimple(const rctSig & rv, const key & sk, unsigned int i, key &mask, hw::device &hwdev) {
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs,
CHECK_AND_ASSERT_MES(rv.type == RCTTypeSimple || rv.type == RCTTypeBulletproof || rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne,
false, "decodeRct called on non simple rctSig");
CHECK_AND_ASSERT_THROW_MES(i < rv.ecdhInfo.size(), "Bad index");
CHECK_AND_ASSERT_THROW_MES(rv.outPk.size() == rv.ecdhInfo.size(), "Mismatched sizes of rv.outPk and rv.ecdhInfo");
//mask amount and mask
ecdhTuple ecdh_info = rv.ecdhInfo[i];
hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs);
hwdev.ecdhDecode(ecdh_info, sk, rv.type == RCTTypeBulletproof2 || rv.type == RCTTypeCLSAG || rv.type == RCTTypeBulletproofPlus || rv.type == RCTTypeFullProofs || rv.type == RCTTypeSalviumOne);
mask = ecdh_info.mask;
key amount = ecdh_info.amount;
key C = rv.outPk[i].mask;
+2
View File
@@ -149,6 +149,7 @@ namespace rct {
unsigned int mixin,
const RCTConfig &rct_config,
hw::device &hwdev,
const rct::salvium_data_t &salvium_data,
const key &x_change = rct::zero(),
const size_t change_index = 0,
const key &key_yF = rct::zero()
@@ -169,6 +170,7 @@ namespace rct {
ctkeyV &outSk,
const RCTConfig &rct_config,
hw::device &hwdev,
const rct::salvium_data_t &salvium_data,
const key &x_change = rct::zero(),
const size_t change_index = 0,
const key &key_yF = rct::zero()
+3
View File
@@ -198,6 +198,7 @@ namespace rct {
case RCTTypeCLSAG:
case RCTTypeBulletproofPlus:
case RCTTypeFullProofs:
case RCTTypeSalviumOne:
return true;
default:
return false;
@@ -223,6 +224,7 @@ namespace rct {
{
case RCTTypeBulletproofPlus:
case RCTTypeFullProofs:
case RCTTypeSalviumOne:
return true;
default:
return false;
@@ -248,6 +250,7 @@ namespace rct {
case RCTTypeCLSAG:
case RCTTypeBulletproofPlus:
case RCTTypeFullProofs:
case RCTTypeSalviumOne:
return true;
default:
return false;
+78 -18
View File
@@ -55,6 +55,7 @@ extern "C" {
#include "serialization/binary_archive.h"
#include "serialization/json_archive.h"
#include "cryptonote_protocol/enums.h"
//Define this flag when debugging to get additional info on the console
#ifdef DBG
@@ -316,7 +317,8 @@ namespace rct {
RCTTypeBulletproof2 = 4,
RCTTypeCLSAG = 5,
RCTTypeBulletproofPlus = 6,
RCTTypeFullProofs = 7
RCTTypeFullProofs = 7,
RCTTypeSalviumOne = 8
};
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
struct RCTConfig {
@@ -329,6 +331,50 @@ namespace rct {
VARINT_FIELD(bp_version)
END_SERIALIZE()
};
enum SalviumDataType { SalviumNormal=0, SalviumAudit=1 };
struct salvium_input_data_t {
crypto::key_derivation aR;
xmr_amount amount;
size_t i;
uint8_t origin_tx_type;
crypto::key_derivation aR_stake;
size_t i_stake;
BEGIN_SERIALIZE_OBJECT()
FIELD(aR)
VARINT_FIELD(amount)
VARINT_FIELD(i)
VARINT_FIELD(origin_tx_type)
if (origin_tx_type != cryptonote::transaction_type::UNSET) {
FIELD(aR_stake)
FIELD(i_stake)
}
END_SERIALIZE()
};
struct salvium_data_t {
uint8_t salvium_data_type; // flag to indicate what type of data is valid
zk_proof pr_proof; // p_r
zk_proof sa_proof; // spend authority proof
zk_proof cz_proof; // change is zero proof
std::vector<salvium_input_data_t> input_verification_data;
crypto::public_key spend_pubkey;
std::string enc_view_privkey_str;
BEGIN_SERIALIZE_OBJECT()
VARINT_FIELD(salvium_data_type)
FIELD(pr_proof)
FIELD(sa_proof)
if (salvium_data_type == SalviumAudit)
{
FIELD(cz_proof)
FIELD(input_verification_data)
FIELD(spend_pubkey)
FIELD(enc_view_privkey_str)
}
END_SERIALIZE()
};
struct rctSigBase {
uint8_t type;
key message;
@@ -339,11 +385,10 @@ namespace rct {
ctkeyV outPk;
xmr_amount txnFee; // contains b
key p_r;
zk_proof pr_proof; // p_r
zk_proof sa_proof; // spend authority proof
salvium_data_t salvium_data;
rctSigBase() :
type(RCTTypeNull), message{}, mixRing{}, pseudoOuts{}, ecdhInfo{}, outPk{}, txnFee(0), p_r{}, pr_proof{}, sa_proof{}
type(RCTTypeNull), message{}, mixRing{}, pseudoOuts{}, ecdhInfo{}, outPk{}, txnFee(0), p_r{}, salvium_data{}
{}
template<bool W, template <bool> class Archive>
@@ -352,7 +397,7 @@ namespace rct {
FIELD(type)
if (type == RCTTypeNull)
return ar.good();
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeBulletproofPlus && type != RCTTypeFullProofs)
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeBulletproofPlus && type != RCTTypeFullProofs && type != RCTTypeSalviumOne)
return false;
VARINT_FIELD(txnFee)
// inputs/outputs not saved, only here for serialization help
@@ -381,7 +426,7 @@ namespace rct {
return false;
for (size_t i = 0; i < outputs; ++i)
{
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs || type == RCTTypeSalviumOne)
{
// Since RCTTypeBulletproof2 enote types, we don't serialize the blinding factor, and only serialize the
// first 8 bytes of ecdhInfo[i].amount
@@ -418,10 +463,14 @@ namespace rct {
}
ar.end_array();
FIELD(p_r)
if (type == RCTTypeFullProofs)
if (type == RCTTypeSalviumOne)
{
FIELD(pr_proof)
FIELD(sa_proof)
FIELD(salvium_data)
}
else if (type == RCTTypeFullProofs)
{
FIELD(salvium_data.pr_proof)
FIELD(salvium_data.sa_proof)
}
return ar.good();
}
@@ -435,9 +484,14 @@ namespace rct {
FIELD(outPk)
VARINT_FIELD(txnFee)
FIELD(p_r)
if (type == RCTTypeFullProofs) {
FIELD(pr_proof)
FIELD(sa_proof)
if (type == RCTTypeSalviumOne)
{
FIELD(salvium_data)
}
else if (type == RCTTypeFullProofs)
{
FIELD(salvium_data.pr_proof)
FIELD(salvium_data.sa_proof)
}
END_SERIALIZE()
};
@@ -461,9 +515,9 @@ namespace rct {
return false;
if (type == RCTTypeNull)
return ar.good();
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeBulletproofPlus && type != RCTTypeFullProofs)
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeBulletproofPlus && type != RCTTypeFullProofs && type != RCTTypeSalviumOne)
return false;
if (type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
if (type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs || type == RCTTypeSalviumOne)
{
uint32_t nbp = bulletproofs_plus.size();
VARINT_FIELD(nbp)
@@ -520,7 +574,7 @@ namespace rct {
ar.end_array();
}
if (type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
if (type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs || type == RCTTypeSalviumOne)
{
ar.tag("CLSAGs");
ar.begin_array();
@@ -611,7 +665,7 @@ namespace rct {
}
ar.end_array();
}
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs || type == RCTTypeSalviumOne)
{
ar.tag("pseudoOuts");
ar.begin_array();
@@ -643,12 +697,12 @@ namespace rct {
keyV& get_pseudo_outs()
{
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs ? p.pseudoOuts : pseudoOuts;
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs || type == RCTTypeSalviumOne ? p.pseudoOuts : pseudoOuts;
}
keyV const& get_pseudo_outs() const
{
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs ? p.pseudoOuts : pseudoOuts;
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs || type == RCTTypeSalviumOne ? p.pseudoOuts : pseudoOuts;
}
BEGIN_SERIALIZE_OBJECT()
@@ -820,6 +874,8 @@ VARIANT_TAG(debug_archive, rct::multisig_out, "rct::multisig_out");
VARIANT_TAG(debug_archive, rct::clsag, "rct::clsag");
VARIANT_TAG(debug_archive, rct::BulletproofPlus, "rct::bulletproof_plus");
VARIANT_TAG(debug_archive, rct::zk_proof, "rct::zk_proof");
VARIANT_TAG(debug_archive, rct::salvium_input_data_t, "rct::salvium_input_data");
VARIANT_TAG(debug_archive, rct::salvium_data_t, "rct::salvium_data");
VARIANT_TAG(binary_archive, rct::key, 0x90);
VARIANT_TAG(binary_archive, rct::key64, 0x91);
@@ -839,6 +895,8 @@ VARIANT_TAG(binary_archive, rct::multisig_out, 0x9e);
VARIANT_TAG(binary_archive, rct::clsag, 0x9f);
VARIANT_TAG(binary_archive, rct::BulletproofPlus, 0xa0);
VARIANT_TAG(binary_archive, rct::zk_proof, 0xa1);
VARIANT_TAG(binary_archive, rct::salvium_input_data_t, 0xa2);
VARIANT_TAG(binary_archive, rct::salvium_data_t, 0xa3);
VARIANT_TAG(json_archive, rct::key, "rct_key");
VARIANT_TAG(json_archive, rct::key64, "rct_key64");
@@ -858,5 +916,7 @@ VARIANT_TAG(json_archive, rct::multisig_out, "rct_multisig_out");
VARIANT_TAG(json_archive, rct::clsag, "rct_clsag");
VARIANT_TAG(json_archive, rct::BulletproofPlus, "rct_bulletproof_plus");
VARIANT_TAG(json_archive, rct::zk_proof, "rct_zk_proof");
VARIANT_TAG(json_archive, rct::salvium_input_data_t, "rct_salvium_input_data");
VARIANT_TAG(json_archive, rct::salvium_data_t, "rct_salvium_data");
#endif /* RCTTYPES_H */