Line data Source code
1 : // Copyright (c) 2016-2020 The ZCash developers 2 : // Copyright (c) 2020-2021 The PIVX Core developers 3 : // Distributed under the MIT software license, see the accompanying 4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 : 6 : #ifndef PIVX_SAPLING_SAPLING_TRANSACTION_H 7 : #define PIVX_SAPLING_SAPLING_TRANSACTION_H 8 : 9 : #include "serialize.h" 10 : #include "streams.h" 11 : #include "uint256.h" 12 : #include "consensus/consensus.h" 13 : 14 : #include "sapling/noteencryption.h" 15 : #include "sapling/sapling.h" 16 : 17 : #include <boost/variant.hpp> 18 : 19 : // transaction.h comment: spending taddr output requires CTxIn >= 148 bytes and typical taddr txout is 34 bytes 20 : #define CTXIN_SPEND_DUST_SIZE 149 21 : #define CTXOUT_REGULAR_SIZE 34 22 : 23 : // These constants are defined in the protocol § 7.1: 24 : // https://zips.z.cash/protocol/protocol.pdf#txnencoding 25 : #define OUTPUTDESCRIPTION_SIZE 948 26 : #define SPENDDESCRIPTION_SIZE 384 27 : #define BINDINGSIG_SIZE 64 28 : 29 : namespace libzcash { 30 : static constexpr size_t GROTH_PROOF_SIZE = ( 31 : 48 + // π_A 32 : 96 + // π_B 33 : 48); // π_C 34 : 35 : typedef std::array<unsigned char, GROTH_PROOF_SIZE> GrothProof; 36 : } 37 : 38 : /** 39 : * A shielded input to a transaction. It contains data that describes a Spend transfer. 40 : */ 41 : class SpendDescription 42 : { 43 : public: 44 : typedef std::array<unsigned char, 64> spend_auth_sig_t; 45 : 46 : uint256 cv{UINT256_ZERO}; //!< A value commitment to the value of the input note. 47 : uint256 anchor{UINT256_ZERO}; //!< A Merkle root of the Sapling note commitment tree at some block height in the past. 48 : uint256 nullifier{UINT256_ZERO}; //!< The nullifier of the input note. 49 : uint256 rk{UINT256_ZERO}; //!< The randomized public key for spendAuthSig. 50 : libzcash::GrothProof zkproof = {{0}}; //!< A zero-knowledge proof using the spend circuit. 51 : spend_auth_sig_t spendAuthSig = {{0}}; //!< A signature authorizing this spend. 52 : 53 143767 : SpendDescription() {} 54 : 55 6505 : SERIALIZE_METHODS(SpendDescription, obj) { READWRITE(obj.cv, obj.anchor, obj.nullifier, obj.rk, obj.zkproof, obj.spendAuthSig); } 56 : 57 : friend bool operator==(const SpendDescription& a, const SpendDescription& b) 58 : { 59 : return ( 60 : a.cv == b.cv && 61 : a.anchor == b.anchor && 62 : a.nullifier == b.nullifier && 63 : a.rk == b.rk && 64 : a.zkproof == b.zkproof && 65 : a.spendAuthSig == b.spendAuthSig 66 : ); 67 : } 68 : 69 : friend bool operator!=(const SpendDescription& a, const SpendDescription& b) 70 : { 71 : return !(a == b); 72 : } 73 : }; 74 : 75 : /** 76 : * A shielded output to a transaction. It contains data that describes an Output transfer. 77 : */ 78 : class OutputDescription 79 : { 80 : public: 81 : uint256 cv{UINT256_ZERO}; //!< A value commitment to the value of the output note. 82 : uint256 cmu{UINT256_ZERO}; //!< The u-coordinate of the note commitment for the output note. 83 : uint256 ephemeralKey{UINT256_ZERO}; //!< A Jubjub public key. 84 : libzcash::SaplingEncCiphertext encCiphertext = {{0}}; //!< A ciphertext component for the encrypted output note. 85 : libzcash::SaplingOutCiphertext outCiphertext = {{0}}; //!< A ciphertext component for the encrypted output note. 86 : libzcash::GrothProof zkproof = {{0}}; //!< A zero-knowledge proof using the output circuit. 87 : 88 149620 : OutputDescription() {} 89 : 90 594416 : SERIALIZE_METHODS(OutputDescription, obj) { READWRITE(obj.cv, obj.cmu, obj.ephemeralKey, obj.encCiphertext, obj.outCiphertext, obj.zkproof); } 91 : 92 : friend bool operator==(const OutputDescription& a, const OutputDescription& b) 93 : { 94 : return ( 95 : a.cv == b.cv && 96 : a.cmu == b.cmu && 97 : a.ephemeralKey == b.ephemeralKey && 98 : a.encCiphertext == b.encCiphertext && 99 : a.outCiphertext == b.outCiphertext && 100 : a.zkproof == b.zkproof 101 : ); 102 : } 103 : 104 : friend bool operator!=(const OutputDescription& a, const OutputDescription& b) 105 : { 106 : return !(a == b); 107 : } 108 : }; 109 : 110 : class SaplingTxData 111 : { 112 : public: 113 : typedef std::array<unsigned char, BINDINGSIG_SIZE> binding_sig_t; 114 : 115 : CAmount valueBalance{0}; 116 : std::vector<SpendDescription> vShieldedSpend; 117 : std::vector<OutputDescription> vShieldedOutput; 118 : binding_sig_t bindingSig = {{0}}; 119 : 120 152201 : SERIALIZE_METHODS(SaplingTxData, obj) { READWRITE(obj.valueBalance, obj.vShieldedSpend, obj.vShieldedOutput, obj.bindingSig); } 121 : 122 1758220 : explicit SaplingTxData() : valueBalance(0), vShieldedSpend(), vShieldedOutput() { } 123 12367837 : explicit SaplingTxData(const SaplingTxData& from) : valueBalance(from.valueBalance), vShieldedSpend(from.vShieldedSpend), vShieldedOutput(from.vShieldedOutput), bindingSig(from.bindingSig) {} 124 : 125 12898671 : bool hasBindingSig() const 126 : { 127 12898671 : return std::any_of(bindingSig.begin(), bindingSig.end(), 128 206378216 : [](const unsigned char& c){ return c != 0; }); 129 : } 130 : }; 131 : 132 : 133 : #endif // PIVX_SAPLING_SAPLING_TRANSACTION_H