Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2a4f5cea7c | |||
| 16eba0d12d |
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cryptoforknote-util",
|
"name": "cryptoforknote-util",
|
||||||
"version": "15.6.1",
|
"version": "15.6.2",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "LucasJones",
|
"name": "LucasJones",
|
||||||
"email": "lucasjonesdev@hotmail.co.uk"
|
"email": "lucasjonesdev@hotmail.co.uk"
|
||||||
|
|||||||
+70
-210
@@ -87,8 +87,18 @@ namespace rct {
|
|||||||
typedef std::vector<key> keyV; //vector of keys
|
typedef std::vector<key> keyV; //vector of keys
|
||||||
typedef std::vector<keyV> keyM; //matrix of keys (indexed by column first)
|
typedef std::vector<keyV> keyM; //matrix of keys (indexed by column first)
|
||||||
|
|
||||||
static key null_key = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
struct zk_proof {
|
||||||
|
key R; // Commitment
|
||||||
|
key z1; // Response
|
||||||
|
key z2; // Response
|
||||||
|
|
||||||
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
|
FIELD(R)
|
||||||
|
FIELD(z1)
|
||||||
|
FIELD(z2)
|
||||||
|
END_SERIALIZE()
|
||||||
|
};
|
||||||
|
|
||||||
//containers For CT operations
|
//containers For CT operations
|
||||||
//if it's representing a private ctkey then "dest" contains the secret key of the address
|
//if it's representing a private ctkey then "dest" contains the secret key of the address
|
||||||
// while "mask" contains a where C = aG + bH is CT pedersen commitment and b is the amount
|
// while "mask" contains a where C = aG + bH is CT pedersen commitment and b is the amount
|
||||||
@@ -294,10 +304,8 @@ namespace rct {
|
|||||||
RCTTypeBulletproof = 3,
|
RCTTypeBulletproof = 3,
|
||||||
RCTTypeBulletproof2 = 4,
|
RCTTypeBulletproof2 = 4,
|
||||||
RCTTypeCLSAG = 5,
|
RCTTypeCLSAG = 5,
|
||||||
RCTTypeCLSAGN = 6,
|
RCTTypeBulletproofPlus = 6,
|
||||||
RCTTypeHaven2 = 7, // Add public mask sum terms, remove extraneous fields (txnFee_usd,txnFee_xasset,txnOffshoreFee_usd,txnOffshoreFee_xasset)
|
RCTTypeFullProofs = 7
|
||||||
RCTTypeHaven3 = 8, // Add public mask sum term for collateral
|
|
||||||
RCTTypeBulletproofPlus = 9,
|
|
||||||
};
|
};
|
||||||
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
enum RangeProofType { RangeProofBorromean, RangeProofBulletproof, RangeProofMultiOutputBulletproof, RangeProofPaddedBulletproof };
|
||||||
struct RCTConfig {
|
struct RCTConfig {
|
||||||
@@ -318,27 +326,24 @@ namespace rct {
|
|||||||
keyV pseudoOuts; //C - for simple rct
|
keyV pseudoOuts; //C - for simple rct
|
||||||
std::vector<ecdhTuple> ecdhInfo;
|
std::vector<ecdhTuple> ecdhInfo;
|
||||||
ctkeyV outPk;
|
ctkeyV outPk;
|
||||||
ctkeyV outPk_usd;
|
|
||||||
ctkeyV outPk_xasset;
|
|
||||||
xmr_amount txnFee = 0; // contains b
|
xmr_amount txnFee = 0; // contains b
|
||||||
xmr_amount txnFee_usd = 0;
|
|
||||||
xmr_amount txnFee_xasset = 0;
|
|
||||||
xmr_amount txnOffshoreFee = 0;
|
|
||||||
xmr_amount txnOffshoreFee_usd = 0;
|
|
||||||
xmr_amount txnOffshoreFee_xasset = 0;
|
|
||||||
keyV maskSums; // contains 2 or 3 elements. 1. is the sum of masks of inputs. 2. is the sum of masks of change outputs. 3. mask of the col output.
|
|
||||||
key p_r;
|
key p_r;
|
||||||
|
zk_proof pr_proof; // p_r
|
||||||
|
zk_proof sa_proof; // spend authority proof
|
||||||
|
|
||||||
|
rctSigBase() :
|
||||||
|
type(RCTTypeNull), message{}, mixRing{}, pseudoOuts{}, ecdhInfo{}, outPk{}, txnFee(0), p_r{}, pr_proof{}, sa_proof{}
|
||||||
|
{}
|
||||||
|
|
||||||
template<bool W, template <bool> class Archive>
|
template<bool W, template <bool> class Archive>
|
||||||
bool serialize_rctsig_base(Archive<W> &ar, size_t inputs, size_t outputs)
|
bool serialize_rctsig_base(Archive<W> &ar, size_t inputs, size_t outputs)
|
||||||
{
|
{
|
||||||
FIELD(type)
|
FIELD(type)
|
||||||
if (type == RCTTypeNull)
|
if (type == RCTTypeNull)
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
if (type != RCTTypeBulletproofPlus)
|
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeBulletproofPlus && type != RCTTypeFullProofs)
|
||||||
return serialize_rctsig_base_old(ar, inputs, outputs);
|
return false;
|
||||||
VARINT_FIELD(txnFee)
|
VARINT_FIELD(txnFee)
|
||||||
VARINT_FIELD(txnOffshoreFee)
|
|
||||||
// inputs/outputs not saved, only here for serialization help
|
// inputs/outputs not saved, only here for serialization help
|
||||||
// FIELD(message) - not serialized, it can be reconstructed
|
// FIELD(message) - not serialized, it can be reconstructed
|
||||||
// FIELD(mixRing) - not serialized, it can be reconstructed
|
// FIELD(mixRing) - not serialized, it can be reconstructed
|
||||||
@@ -349,193 +354,44 @@ namespace rct {
|
|||||||
return false;
|
return false;
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
for (size_t i = 0; i < outputs; ++i)
|
||||||
{
|
{
|
||||||
ar.begin_object();
|
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
|
||||||
if (!typename Archive<W>::is_saving())
|
{
|
||||||
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
|
// Since RCTTypeBulletproof2 enote types, we don't serialize the blinding factor, and only serialize the
|
||||||
crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount;
|
// first 8 bytes of ecdhInfo[i].amount
|
||||||
FIELD(amount);
|
ar.begin_object();
|
||||||
ar.end_object();
|
if (!typename Archive<W>::is_saving())
|
||||||
if (outputs - i > 1)
|
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
|
||||||
ar.delimit_array();
|
crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount;
|
||||||
}
|
FIELD(amount);
|
||||||
ar.end_array();
|
ar.end_object();
|
||||||
|
}
|
||||||
ar.tag("outPk");
|
else
|
||||||
ar.begin_array();
|
{
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk);
|
FIELDS(ecdhInfo[i])
|
||||||
if (outPk.size() != outputs)
|
}
|
||||||
return false;
|
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
|
||||||
{
|
|
||||||
FIELDS(outPk[i].mask)
|
|
||||||
if (outputs - i > 1)
|
|
||||||
ar.delimit_array();
|
|
||||||
}
|
|
||||||
ar.end_array();
|
|
||||||
|
|
||||||
// if txnOffshoreFee is not 0, it is a conversion tx
|
|
||||||
if (txnOffshoreFee) {
|
|
||||||
ar.tag("maskSums");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(3, maskSums);
|
|
||||||
if (maskSums.size() != 3)
|
|
||||||
return false;
|
|
||||||
FIELDS(maskSums[0])
|
|
||||||
ar.delimit_array();
|
|
||||||
FIELDS(maskSums[1])
|
|
||||||
ar.delimit_array();
|
|
||||||
FIELDS(maskSums[2])
|
|
||||||
ar.end_array();
|
|
||||||
}
|
|
||||||
if (crypto_verify_32(p_r.bytes, null_key.bytes))
|
|
||||||
FIELD(p_r)
|
|
||||||
return ar.stream().good();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool W, template <bool> class Archive>
|
|
||||||
bool serialize_rctsig_base_old(Archive<W> &ar, size_t inputs, size_t outputs)
|
|
||||||
{
|
|
||||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN && type != RCTTypeHaven2 && type != RCTTypeHaven3)
|
|
||||||
return false;
|
|
||||||
VARINT_FIELD(txnFee)
|
|
||||||
if (type == RCTTypeHaven2 || type == RCTTypeHaven3) {
|
|
||||||
// serialize offshore fee
|
|
||||||
VARINT_FIELD(txnOffshoreFee)
|
|
||||||
} else if (type == RCTTypeCLSAG || type == RCTTypeCLSAGN) {
|
|
||||||
VARINT_FIELD(txnFee_usd)
|
|
||||||
if (type == RCTTypeCLSAGN)
|
|
||||||
{
|
|
||||||
VARINT_FIELD(txnFee_xasset)
|
|
||||||
}
|
|
||||||
VARINT_FIELD(txnOffshoreFee)
|
|
||||||
VARINT_FIELD(txnOffshoreFee_usd)
|
|
||||||
if (type == RCTTypeCLSAGN)
|
|
||||||
{
|
|
||||||
VARINT_FIELD(txnOffshoreFee_xasset)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
txnFee_usd = 0;
|
|
||||||
txnFee_xasset = 0;
|
|
||||||
txnOffshoreFee = 0;
|
|
||||||
txnOffshoreFee_usd = 0;
|
|
||||||
txnOffshoreFee_xasset = 0;
|
|
||||||
}
|
|
||||||
// inputs/outputs not saved, only here for serialization help
|
|
||||||
// FIELD(message) - not serialized, it can be reconstructed
|
|
||||||
// FIELD(mixRing) - not serialized, it can be reconstructed
|
|
||||||
if (type == RCTTypeSimple) // moved to prunable with bulletproofs
|
|
||||||
{
|
|
||||||
ar.tag("pseudoOuts");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(inputs, pseudoOuts);
|
|
||||||
if (pseudoOuts.size() != inputs)
|
|
||||||
return false;
|
|
||||||
for (size_t i = 0; i < inputs; ++i)
|
|
||||||
{
|
|
||||||
FIELDS(pseudoOuts[i])
|
|
||||||
if (inputs - i > 1)
|
|
||||||
ar.delimit_array();
|
|
||||||
}
|
|
||||||
ar.end_array();
|
|
||||||
}
|
|
||||||
|
|
||||||
ar.tag("ecdhInfo");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, ecdhInfo);
|
|
||||||
if (ecdhInfo.size() != outputs)
|
|
||||||
return false;
|
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
|
||||||
{
|
|
||||||
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3)
|
|
||||||
{
|
|
||||||
ar.begin_object();
|
|
||||||
if (!typename Archive<W>::is_saving())
|
|
||||||
memset(ecdhInfo[i].amount.bytes, 0, sizeof(ecdhInfo[i].amount.bytes));
|
|
||||||
crypto::hash8 &amount = (crypto::hash8&)ecdhInfo[i].amount;
|
|
||||||
FIELD(amount);
|
|
||||||
ar.end_object();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FIELDS(ecdhInfo[i])
|
|
||||||
}
|
|
||||||
if (outputs - i > 1)
|
|
||||||
ar.delimit_array();
|
|
||||||
}
|
|
||||||
ar.end_array();
|
|
||||||
|
|
||||||
ar.tag("outPk");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk);
|
|
||||||
if (outPk.size() != outputs)
|
|
||||||
return false;
|
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
|
||||||
{
|
|
||||||
FIELDS(outPk[i].mask)
|
|
||||||
if (outputs - i > 1)
|
if (outputs - i > 1)
|
||||||
ar.delimit_array();
|
ar.delimit_array();
|
||||||
}
|
}
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
|
|
||||||
// if txnOffshoreFee is not 0, it is a conversion tx
|
ar.tag("outPk");
|
||||||
if (type == RCTTypeHaven3 && txnOffshoreFee) {
|
ar.begin_array();
|
||||||
|
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk);
|
||||||
|
if (outPk.size() != outputs)
|
||||||
|
return false;
|
||||||
|
for (size_t i = 0; i < outputs; ++i)
|
||||||
|
{
|
||||||
|
FIELDS(outPk[i].mask)
|
||||||
|
if (outputs - i > 1)
|
||||||
|
ar.delimit_array();
|
||||||
|
}
|
||||||
|
ar.end_array();
|
||||||
|
|
||||||
ar.tag("maskSums");
|
FIELD(p_r)
|
||||||
ar.begin_array();
|
if (type == RCTTypeFullProofs)
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(3, maskSums);
|
{
|
||||||
if (maskSums.size() != 3)
|
FIELD(pr_proof)
|
||||||
return false;
|
FIELD(sa_proof)
|
||||||
FIELDS(maskSums[0])
|
|
||||||
ar.delimit_array();
|
|
||||||
FIELDS(maskSums[1])
|
|
||||||
ar.delimit_array();
|
|
||||||
FIELDS(maskSums[2])
|
|
||||||
ar.end_array();
|
|
||||||
|
|
||||||
} else if (type == RCTTypeHaven2) {
|
|
||||||
|
|
||||||
ar.tag("maskSums");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(2, maskSums);
|
|
||||||
if (maskSums.size() != 2)
|
|
||||||
return false;
|
|
||||||
FIELDS(maskSums[0])
|
|
||||||
ar.delimit_array();
|
|
||||||
FIELDS(maskSums[1])
|
|
||||||
ar.end_array();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if ((type == RCTTypeCLSAG) || (type == RCTTypeCLSAGN))
|
|
||||||
{
|
|
||||||
ar.tag("outPk_usd");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk_usd);
|
|
||||||
if (outPk_usd.size() != outputs)
|
|
||||||
return false;
|
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
|
||||||
{
|
|
||||||
FIELDS(outPk_usd[i].mask)
|
|
||||||
if (outputs - i > 1)
|
|
||||||
ar.delimit_array();
|
|
||||||
}
|
|
||||||
ar.end_array();
|
|
||||||
}
|
|
||||||
if (type == RCTTypeCLSAGN)
|
|
||||||
{
|
|
||||||
ar.tag("outPk_xasset");
|
|
||||||
ar.begin_array();
|
|
||||||
PREPARE_CUSTOM_VECTOR_SERIALIZATION(outputs, outPk_xasset);
|
|
||||||
if (outPk_xasset.size() != outputs)
|
|
||||||
return false;
|
|
||||||
for (size_t i = 0; i < outputs; ++i)
|
|
||||||
{
|
|
||||||
FIELDS(outPk_xasset[i].mask)
|
|
||||||
if (outputs - i > 1)
|
|
||||||
ar.delimit_array();
|
|
||||||
}
|
|
||||||
ar.end_array();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
}
|
}
|
||||||
@@ -548,8 +404,11 @@ namespace rct {
|
|||||||
FIELD(ecdhInfo)
|
FIELD(ecdhInfo)
|
||||||
FIELD(outPk)
|
FIELD(outPk)
|
||||||
VARINT_FIELD(txnFee)
|
VARINT_FIELD(txnFee)
|
||||||
VARINT_FIELD(txnOffshoreFee)
|
FIELD(p_r)
|
||||||
FIELD(maskSums)
|
if (type == RCTTypeFullProofs) {
|
||||||
|
FIELD(pr_proof)
|
||||||
|
FIELD(sa_proof)
|
||||||
|
}
|
||||||
END_SERIALIZE()
|
END_SERIALIZE()
|
||||||
};
|
};
|
||||||
struct rctSigPrunable {
|
struct rctSigPrunable {
|
||||||
@@ -572,9 +431,9 @@ namespace rct {
|
|||||||
return false;
|
return false;
|
||||||
if (type == RCTTypeNull)
|
if (type == RCTTypeNull)
|
||||||
return ar.stream().good();
|
return ar.stream().good();
|
||||||
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeCLSAGN && type != RCTTypeHaven2 && type != RCTTypeHaven3 && type != RCTTypeBulletproofPlus)
|
if (type != RCTTypeFull && type != RCTTypeSimple && type != RCTTypeBulletproof && type != RCTTypeBulletproof2 && type != RCTTypeCLSAG && type != RCTTypeBulletproofPlus && type != RCTTypeFullProofs)
|
||||||
return false;
|
return false;
|
||||||
if (type == RCTTypeBulletproofPlus)
|
if (type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
|
||||||
{
|
{
|
||||||
uint32_t nbp = bulletproofs_plus.size();
|
uint32_t nbp = bulletproofs_plus.size();
|
||||||
VARINT_FIELD(nbp)
|
VARINT_FIELD(nbp)
|
||||||
@@ -593,10 +452,10 @@ namespace rct {
|
|||||||
return false;
|
return false;
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
}
|
}
|
||||||
else if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3)
|
else if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG)
|
||||||
{
|
{
|
||||||
uint32_t nbp = bulletproofs.size();
|
uint32_t nbp = bulletproofs.size();
|
||||||
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3)
|
if (type == RCTTypeBulletproof2 || type == RCTTypeCLSAG)
|
||||||
VARINT_FIELD(nbp)
|
VARINT_FIELD(nbp)
|
||||||
else
|
else
|
||||||
FIELD(nbp)
|
FIELD(nbp)
|
||||||
@@ -631,7 +490,7 @@ namespace rct {
|
|||||||
ar.end_array();
|
ar.end_array();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3 || type == RCTTypeBulletproofPlus)
|
if (type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
|
||||||
{
|
{
|
||||||
ar.tag("CLSAGs");
|
ar.tag("CLSAGs");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
@@ -722,7 +581,7 @@ namespace rct {
|
|||||||
}
|
}
|
||||||
ar.end_array();
|
ar.end_array();
|
||||||
}
|
}
|
||||||
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3 || type == RCTTypeBulletproofPlus)
|
if (type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs)
|
||||||
{
|
{
|
||||||
ar.tag("pseudoOuts");
|
ar.tag("pseudoOuts");
|
||||||
ar.begin_array();
|
ar.begin_array();
|
||||||
@@ -754,12 +613,12 @@ namespace rct {
|
|||||||
|
|
||||||
keyV& get_pseudo_outs()
|
keyV& get_pseudo_outs()
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3 || type == RCTTypeBulletproofPlus ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyV const& get_pseudo_outs() const
|
keyV const& get_pseudo_outs() const
|
||||||
{
|
{
|
||||||
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeCLSAGN || type == RCTTypeHaven2 || type == RCTTypeHaven3 || type == RCTTypeBulletproofPlus ? p.pseudoOuts : pseudoOuts;
|
return type == RCTTypeBulletproof || type == RCTTypeBulletproof2 || type == RCTTypeCLSAG || type == RCTTypeBulletproofPlus || type == RCTTypeFullProofs ? p.pseudoOuts : pseudoOuts;
|
||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_SERIALIZE_OBJECT()
|
BEGIN_SERIALIZE_OBJECT()
|
||||||
@@ -930,5 +789,6 @@ VARIANT_TAG(binary_archive, rct::multisig_kLRki, 0x9d);
|
|||||||
VARIANT_TAG(binary_archive, rct::multisig_out, 0x9e);
|
VARIANT_TAG(binary_archive, rct::multisig_out, 0x9e);
|
||||||
VARIANT_TAG(binary_archive, rct::clsag, 0x9f);
|
VARIANT_TAG(binary_archive, rct::clsag, 0x9f);
|
||||||
VARIANT_TAG(binary_archive, rct::BulletproofPlus, 0xa0);
|
VARIANT_TAG(binary_archive, rct::BulletproofPlus, 0xa0);
|
||||||
|
VARIANT_TAG(binary_archive, rct::zk_proof, 0xa1);
|
||||||
|
|
||||||
#endif /* RCTTYPES_H */
|
#endif /* RCTTYPES_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user